月光宝盒:威胁流量重放
作者:糖果
在进行攻击测试时,我们可能会用描扫器直接扫描测试机,但有时想固定攻击的流量内容,让攻击测试流量的每个HTTP包内容保持一致,再次进行攻击测试时,还用这些相同的HTTP攻击请求,
然后根据相同的攻击攻击数据输入,做不同的应对策略。我们也可以人为或是脚本执行构造攻击请求也这样记录下来,然后进行流量重放就行了。简单说就是,威胁流量重放。
传统的流量复制,可以分光,也可以通过VSS等流量分发设备,有的流量分发是基于网络层的,这种流量可以用tcpcopy复制重放,除此之外,还有另外一种方式,是在7层直接进行复制,ningx-mirror-module就可做到
我们可以流量一份给正式环境,一份给WAF,一份给反扫统计模块。
我们开始做这些实验时, 需要安装一些相关的开源软件: tcpycopy, openresty, luarocks, lapis,moonscript。
1.TCP层流量录制。
1-1.如是我们想做四层回放,需要安装tcpcopy和
安装tcpcopy:
git clone https://github.com/session-replay-tools/tcpcopy.git
./configure
make
sudo make install
1-2.安装intercept:
git clone https://github.com/session-replay-tools/intercept.git
./configure
make
sudo make install
1-3. 威胁流量录制:
我们也不打算真的录制威胁流量,就用简单的含有特定关键字的URL访问模拟威胁。
为了方便说明,我们把流量通过candylab.net这个域名劫持到指定ip上,我们架设的威胁URL就是:
请求访问URL,然后用tcpdump录下来:
sudo tcpdump -s0 -vv -e -i eth0 -nn port 80 -w test.pcap
用wireshark解开这个流量文件,如下图:
我们可以看到被抓取到的HTTP请求:
2.HTTP服务环境搭建。
2-1.安装Openresty的HTTP服务器。
2-1-1. 安装相关依赖软件。
yum install pcre-devel openssl-devel gcc curl
2-1-1. 安装Openresty。
wget https://openresty.org/download/openresty-1.13.6.1.tar.gz
tar -zxvf openresty-1.13.6.1.tar.gz
cd openresty-1.13.6.1
./configure
make
sudo make install
2-2.安装luarocks。
luarocks是lua的软件管理包,有很多的依赖库,我们可以使用luarocks来安装。 openresty提供丰富的操作openresty的lua的api,但这些API都粒度比较细,没有形成成套的框架,所以为了方便
演示,之后我们用lapis框架来管理web服务,这样可以减少不少的工作量,又方便说明问题。
wget https://luarocks.org/releases/luarocks-2.4.3.tar.gz
tar zxpf luarocks-2.4.3.tar.gz
cd luarocks-2.4.3
./configure; sudo make bootstrap
sudo luarocks install luasocket
除了luarocks以外还有一个moonrocks,这个先不介绍了,需要说明的地方是,lapis可以用moonscript和lua两种语言进行web开源。我们的例子是用moonscript写的,所以需要一个moonscript语言的翻译器,把
moonscript语言翻译成lua语言。
2-3.安装moonscript
luarocks install moonscript
2-4.安装lapis
Lapis是一个有历史的openresty的lua框架,用了lapis可以编码的生产性,但需要学习moonscript的语言法,国为这次的例子很简单,一看即可了解大意。
3.创建HTTP服务应用。
我们用Openresty创建三个openresty工程项目,1是主项目main,是我们访问测试的最外层入口。2是waf镜像流量接收。 3.是纯镜像流量,可以用来地做反扫,这里略了。
3-1.创建主main项目
mkdir main
lapis new
moonc app.moon
3-1-1.主服务的代码
lapis = require “lapis”
class extends lapis.Application
“/”: =>
“Main Server!”
3-1-2.修改conf文件做http的流量镜像:
location / {
default_type text/html;
content_by_lua ‘
require(“lapis”).serve(“app”)
‘;
mirror /mirror;
mirror_request_body off;
proxy_pass http://127.0.0.1:8081;
}
location /mirror {
internal;
proxy_pass http://127.0.0.1:8082$request_uri;
proxy_set_header X-Original-URI $request_uri;
}
3-2.创建WAF项目
mkdir main
lapis new
moonc app.moon
3-2-1.主WAF服务的代码
lapis = require “lapis”
class extends lapis.Application
“/”: =>
“WAF System!”
3-2-2.修改conf文件
加入的在access阶段进行拦截的代码,我们简单的对url中含有blues的url进行拦截,直接返回401。
location / {
default_type text/html;
access_by_lua_file access.lua;
content_by_lua ‘
require(“lapis”).serve(“app”)
‘;
}
3-2-3.拦截逻辑
if ngx.re.find(ngx.var.request_uri, ‘blues’, “jo”) then
ngx.exit(401)
end
4.流量回放。
前几步都准备好了,我们反pcap中录的流量重放给HTTP服务,我们用了一个web服务根本没有的咱由进行测试,我们录制的HTTP访问的URL是http://candylab.net/blues,但上面的代码根本没有提供这个
路由的处理,正常就是返回500状态,先把waf的那个简单的拦截逻辑去掉,我们先看看,正常的http数据访问分流是什么的,把access.lua的中代码注释掉。
if ngx.re.find(ngx.var.request_uri, ‘blues’, “jo”) then
— ngx.exit(401)
end
4-1.正常HTTP流量镜像访问。
输入
10.210.128.63/blues
我们通过tmux把屏幕分层四块,可以看到一个主服务和两个镜像服务的访问流量。
我们用curl测试效果也是一样的。
4-2.Tcpcopy的流量回放访问。
之前的步骤我们录制了几次/blues的get请求,现在要把含有此访问的pcap流量重放。
重放流量之前我们要打开intercept服务,工作eth0口上。
sudo /usr/local/tcpcopy/sbin/intercept -i eth0 -F’tcp and src port 80′ -d
然后我们就可以重放了。
4-3.给WAF加上拦截逻辑
把之前waf项目中的access.lua的注释放开,复位web服务,然后重放录制的流量。
if ngx.re.find(ngx.var.request_uri, ‘blues’, “jo”) then
ngx.exit(401)
end
加上拦截逻辑的项目的请求,在访问阶段就被拦截,而mirror镜像的流量因为没有拦截的,原校报的请求通过。
5.总结
来思考一人问题,能不能不用画图就可把nginx的WAF说清楚呢, 这WAF就像一个对话的监听者,在用户与服务通信之间进行监听。正常人与人之前的交流都是用自然语言交流,大家遵守英语或是汉语
的语言发音和语法就可以沟通,HTTP客户端和HTTP服务器之间,只要遵守HTTP协议就可以进交互通信,WAF就是HTTP会话之间的监听者,一旦发现流量中有她认为是为威胁的数据就拦截,可以是一个
大的字符串配对算法,因数openrsty、nginx是可以做http的代理服务,自然就可以做监听,并且性能很高,所以,在一些场合我们通过openresty这种开源软件做WAF安全监听防护。