Attack1
1. 匯編分析
push %ebp
mov %esp,%ebp
sub $0x48,%esp
其作用是建立棧結(jié)構(gòu)。
之后,
mov $0x80486b9,%eax ; $0x80486b9 contains "%s"
mov 0x8(%ebp),%edx
mov %edx,0xc(%esp)
mov %eax,0x8(%esp)
movl $0x30,0x4(%esp)
其作用是在esp上4字節(jié)處賦值0x30,8字節(jié)處添加含有%s的內(nèi)容,在12字節(jié)處添加argv[2]即我們輸入的第二個內(nèi)容。
lea -0x38(%ebp),%eax
mov %eax,(%esp)
call 80483fc <snprintf@plt>
movb $0x0,-0x9(%ebp)
lea -0x38(%ebp),%eax
mov %eax,(%esp)
call 80483cc <printf@plt>
其作用是,將esp指向棧上方16個字節(jié)處,ebp下方9個字節(jié)處賦0,最后打印。

棧結(jié)構(gòu).png
2. 攻擊代碼分析

攻擊代碼截圖.png
perl -e后面緊跟著引號里面的字符串是要執(zhí)行的命令1 表示switch中的case1
接著輸入you win!字符串的地址(winner中給出),之后的
%d%d%d%s如下圖所示讀取前三個數(shù)值之后,以%s格式讀取我們輸入的字符串,從而打印出該地址保存的字符串you win!
Attack2
1. 匯編分析
push %ebp
mov %esp,%ebp
sub $0x38,%esp %56個字節(jié)
其作用是建立棧結(jié)構(gòu)。
movl $0x20,0x8(%esp) % 將0x20賦給esp上八個字節(jié)處
movl $0x0,0x4(%esp) % 將0x0賦給esp上四個字節(jié)處
lea -0x28(%ebp),%eax
mov %eax,(%esp) % 將esp指向ebp下方40字節(jié)處
call 804839c <memset@plt> % 對內(nèi)容進行填充
mov 0x8(%ebp),%eax % 將argv[2]即我們輸入的第二個內(nèi)容賦給eax

棧結(jié)構(gòu)2.png
movzbl (%eax),%eax % 負責拷貝一個字節(jié),并用0填充其目的操作數(shù)的其余各位(0擴展)
and $0x1,%eax
test %al,%al % 判斷是否跳轉(zhuǎn)
jne 8048568 <vuln2+0x56> % 判斷結(jié)果是會跳轉(zhuǎn)
mov $0x80486d9,%eax
mov 0x8(%ebp),%edx
mov %edx,0x4(%esp) % 將argv[2]即我們輸入的第二個內(nèi)容賦給esp上方4字節(jié)處
mov %eax,(%esp) % 將$0x80486d9賦給esp
call 80483cc <printf@plt> % 調(diào)用打印函數(shù)
2. 攻擊代碼分析

攻擊代碼2.png
perl -e后面緊跟著引號里面的字符串是要執(zhí)行的命令2表示switch中的case2
只要保證首字母的尾數(shù)是偶數(shù)即可,這里我們選擇B,其后可任意填充內(nèi)容,我們填充A,從而覆蓋棧。最后覆蓋的是跳轉(zhuǎn)地址,winner函數(shù)的地址是
080484c4。填充的長度取決于是否能覆蓋返回地址。