Burp Suite,mitmproxy都是非常有用的HTTP代理工具。它们不仅仅用于渗透测试和安全研究,也用于开发、测试和API研究上。实际上,我自己现在更多的是用Burp来进行调试和学习,而不是用于实际的渗透测试。观察网络中的实际HTTP请求,对理解复杂的API或测试我的脚本或工具是否正常工作是非常有帮助的。
本文涉及知识点实操练习:burpsuite实战(burpsuite是一款功能强大的用于攻击web应用程序的集成平台,通常在服务器和客户端之间充当一个双向代理,用于截获通信过程中的数据包,对于截获到的包可以人为的进行修改和重放。)
像Burp或mitmproxy这样的工具的一般使用方法是配置浏览器通过它进行通信,网上有很多关于如何配置Firefox、Chrome等与Burp Suite会话并信任Burp签名的证书颁发机构的文章和教程。
然而,我经常需要检查来自除浏览器以外的其他工具的流量,最常用的是命令行工具。很多常用服务的CLI工具只是可以发出HTTP请求,检查和或修改这些流量很有研究意义。如果一个CLI工具没有正常工作,有时候查看错误信息也没有帮助,那么只要你看看它实际发出或者接收的HTTP请求和响应,问题就会很快解决。
我曾使用这些技术来检查常用的CLI工具,如Azure 的CLI 程序。以前,我甚至代理了我们使用的商业安全工具提供的CLI工具,并了解到了一些未公开的API和行为,这些网络行为并不在他们的说明文档中。有了这些知识,我就能够很简单的完成某些事情,而这些事情是无法通过他们的 CLI或发布的API文档来实现的。
在这篇文章中,我想展示各种方法,配置不同语言编写的CLI工具,通过Burp Suite代理他们的HTTP(S)流量。一般来说,有两件事我们必须要配置。
Burp代理CLI的流量
让CLI信任Burp的 CA证书(或忽略信任)
一般来说,第二步通常比较困难,但并非不可能实现。
在大多数的例子中,我让Burp Suite在localhost:8080上监听,并在同一台机器上运行CLI工具。如果Burp运行在不同的主机或接口上,你应该将localhost替换成Burp的IP。
对于第一个例子,我将展示如何代理 curl 和 wget。这两个工具都可以很容易地配置代理,它们可以从环境变量中获取代理设置。
http_proxy
https_proxy
你可以用以下的方式来进行代理配置.
export http_proxy=localhost:8080
export https_proxy=localhost:8080
curl ifconfig.io
wget -O /dev/null ifconfig.io
## or ##
http_proxy=localhost:8080 https_proxy=localhost:8080 curl ifconfig.io
http_proxy=localhost:8080 https_proxy=localhost:8080 wget -O /dev/null ifconfig.io
在burp中我们可以看到wget和curl的流量请求
这很好用,因为它只是HTTP。那HTTPS呢?如果你尝试着运行的话,你肯定会失败的。
curl不信任Burp的证书,这些错误信息是相当有用的。大多数CLI工具在信任证书时,都会听取操作系统的安排。所以我们有两个选择:
禁用信任核查
将我们的操作系统配置为信任Burp CA
第一种选择最简单。对于curl
使用-k
或wget
使用--no-check-certificate
参数:
http_proxy=localhost:8080 https_proxy=localhost:8080 curl -k https://ifconfig.io
http_proxy=localhost:8080 https_proxy=localhost:8080 wget -O /dev/null --no-check-certificate https://ifconfig.io
对于第二个选项,我们必须从Burp内导出BurpCA。我们可以将DER格式的Burp证书下载到~/certs
。
mkdir ~/certs
wget -O ~/certs/burpca.der http://localhost:8080/cert
cd ~/certs
openssl x509 -inform DER -in burpca.der -out burpca.crt
注意:如果您使用mitmproxy
,则证书已经在~/.mitmproxy
目录下了。
在Mac上,只需双击下载的DER文件,OSX就会提示您将证书添加到信任的名单中。如果选择“系统”,则计算机上的所有用户都将信任它。然后,在导入后,您必须信任它。搜索“ PortSwigger”并打开证书。在“信任”下,为SSL选择“始终信任”:
在Windows上,双击DER文件并选择“ Install Certificate”。选择“受信任的根证书颁发机构”证书存储以安装并信任BurpCA。
对于大多数linux发行版,都包含受信任的证书/usr/share/ca-certificates
。将burpca.crt
文件复制到/usr/share/ca-certificates
,然后运行:
sudo update-ca-certificates
通过使用操作系统信任的Burp CA,您不再需要使用curl的-k参数或者wget的--no-check-certificates参数,您可以在Burp中看到HTTPS流量:
虽然我喜欢用Python或npm包或Go文件,而且我接触的很多CLI工具都是JAR形式的工具,现在,这些程序中一些有代理支持,可以通过命令行选项进行配置。然而其中一些没有,我需要强制JAR文件来使用我的代理工具。
以前使用的一个安全扫描器有一个API,并配有说明文档。使用API的token与它进行交互的唯一方式是使用他们的Java JAR CLI工具。但是我们需要开发我们的自动化工具,希望能写一个Python工具和我们的API进行交互,所以我使用了这种技术来代理他们的JAR,并弄清楚了如何使用API 的token来进行验证。
我在我找到的一个Atlassian CLI工具上演示与Jira的交互过程。例如,我可以用这个CLI来查询云托管实例上运行的Jira版本。
java -jar acli-9.1.0.jar -s https://greenshot.atlassian.net -a getServerInfo
Jira version: 1001.0.0-SNAPSHOT, build: 100119, time: 2/6/20, 6:26 AM, description: Greenshot JIRA, url: https://greenshot.atlassian.net
不幸的是,CLI工具没有用于指定代理的任何选项。好消息是,在启动Java时,强制JVM通过某些属性使用代理实际上是可行的:
http.proxyHost
http.proxyPort
https.proxyHost
https.proxyPort
http.nonProxyHosts
要通过Burpsuite代理JAR,我们需要为代理设置前4个选项,并使最后一个选项为空值。这将强制Java通过Burp代理所有主机。为此, 我们在指定JAR之前将它们作为命令行参数添加到命令中:
java -Dhttp.nonProxyHosts= -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8080 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=8080 -jar acli-9.1.0.jar -s https://greenshot.atlassian.net -a getServerInfo
但是我们现在看到了一个SSL错误:
即使我的操作系统中信任了Burp证书,Java仍实际上使用其自己的密钥库。因此,我们还需要在其中添加Burp证书。
默认密钥库位于$JAVA_HOME/lib/security/cacerts
。如果您没有设置$JAVA_HOME
环境变量,您也可以使用java
命令快速找到它:
java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home'
java.home = /Users/RonnieFlathers/.sdkman/candidates/java/11.0.3-zulu
要将证书添加到Java的密钥库中,我们可以利用Java的keytool
程序,该工具包含在$JAVA_HOME/bin/keytool
中。要导入Burp证书,我们必须将PEM格式的文件导入到受信任的CA证书中:
$JAVA_HOME/bin/keytool -import -alias burpsuite -keystore $JAVA_HOME/lib/security/cacerts -file $HOME/certs/burpca.crt -trustcacerts
这里提示您输入密钥库密码。默认情况下,值为changeit
。然后指定“是”以信任证书:
现在有了Java信任的Burp证书,我们可以查看Burp中的HTTP流量:
下一个示例将介绍Python CLI。最近,我经常使用这个工具,因为之前我做了很多Azure自动化工作,并希望很好的使用zaure的cli来提高工作效率。不过,在示例中,我已经使用homebrew安装了Azure CLI,并已经完成了azure账号的登录。
我可以使用以下方法查看可用的资源组:
$ az group list
[
{
"id": "/subscriptions/300b646c-f573-49d4-96d5-c01efe36c282/resourceGroups/ropnoptest",
"location": "centralus",
"managedBy": null,
"name": "ropnoptest",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {},
"type": "Microsoft.Resources/resourceGroups"
}
]
幸运的是,通过截取发出的请求,Python会使用 "正常 "的代理环境变量。然而当试图设置这些变量的时候,得到的结果却是SSL错误。
$ HTTPS_PROXY=http://localhost:8080 az group list
request failed: Error occurred in request., SSLError: HTTPSConnectionPool........
由于我的操作系统信任Burp CA,因此在测试Python的时候未使用它。
Python 的 CA 证书处理有点奇怪。大多数的Python CLI可能会使用requests库,它会使用自己的CA bundle,然后也会查看另一个certifi库包含的CA bundle,但是它使用了Mozilla的bundle。为了信任我们的CA,我们可以将它添加到与certifi一起包含的Mozilla bundle中。
需要注意的是,Python解释器的版本也会影响试验结果, 所以如果你使用的是虚拟环境,你需要确保使用正确版本的Python运行以下命令。
首先,我想验证 az 如何调用 Python,以及它使用的是哪个版本。
$ head `which az`
#!/usr/bin/env bash
/usr/local/Cellar/azure-cli/2.0.74/libexec/bin/python -m azure.cli "$@"
因此,az
它会调用自己内置的Python解释器,该解释器已在homebrew上安装。
首先,为了确定导入证书的位置,我们导入certifi
并运行certifi.where()
命令。
$ /usr/local/Cellar/azure-cli/2.0.74/libexec/bin/python -c "import certifi; print(certifi.where())"
/usr/local/Cellar/azure-cli/2.0.74/libexec/lib/python3.7/site-packages/certifi/cacert.pem
该cacert.pem
文件是PEM格式的所有受信任的CA证书列表。要添加Burp CA,我们只需将PEM附加到该文件中即可:
cat ~/certs/burpca.pem >> /usr/local/Cellar/azure-cli/2.0.74/libexec/lib/python3.7/site-packages/certifi/cacert.pem
将Burp CA添加到Mozilla bundle中,我们现在就可以代理az命令了!
$ HTTPS_PROXY=http://localhost:8080 az group list
现在我们想要运行的任何 az 命令都可以进行查看或者修改。
在这个例子中,我希望能够代理到来自NPM包的流量,以便与https://zeit.co进行交互。
我已经使用如下命令行安装了工具。
npm i -g now@latest
登录后,我可以查看我当前的部署:
运行:
$ HTTPS_PROXY=http://localhost:8080 now list
发现服务器返回了数据,Burp中并没有出现任何内容。看来,Node并不支持全局代理设置,但这并不意味着我们不能强行设置。
首先,我们来看看now命令调用了哪些内容:
$ which now
/Users/RonnieFlathers/.nvm/versions/node/v12.15.0/bin/now
$ head -c100 `which now`
#!/usr/bin/env node
require('./sourcemap-register.js');module.exports=function(e,t){"use strict";var%
now程序是一个JS文件,位于Node的bin目录中,我们也可以直接用node调用那个文件来运行now命令。
$ node /Users/RonnieFlathers/.nvm/versions/node/v12.15.0/bin/now -v
Now CLI 17.0.3
17.0.3
虽然node没有全局代理的支持,但是一个名为global-agent的项目解决了这个问题,它可以在Node项目中设置一个可配置的代理。要使用它,我们使用npm将它安装到我们当前的目录中。
$ mkdir nodeproxy
$ cd nodproxy/
$ npm install global-agent
该模块使用了GLOBAL_AGENT_HTTP_PROXY环境变量,所以我们必须先使用命令设置环境变量,现在我们可以将项目注入到now包中。
$ export GLOBAL_AGENT_HTTP_PROXY=http://127.0.0.1:8080
$ node -r 'global-agent/bootstrap' `which now`
现在要为Burp添加SSL证书。
这其实比Python简单不少。Node命令的一个环境变量,叫做NODE_EXTRA_CA_CERTS。如果要把我们的Burp证书加载为可信的,我们只要把这个环境变量导出,然后指向Burp的PEM文件就可以了。
export NODE_EXTRA_CA_CERTS=$HOME/certs/burpca.crt
export GLOBAL_AGENT_HTTP_PROXY=http://127.0.0.1:8080
node -r 'global-agent/bootstrap' `which now`
现在可以用了! 我们可以在Burp中查看now包的流量。
越来越多开发者开始将静态的Go二进制文件以CLI形式发布。因为Go是一门很优秀的语言。Go设置代理非常简单,因为每个Go程序都能使用环境变量http_proxy和https_proxy。
在这个例子中,我将代理Github的hub工具(对于命令行用户,GitHub提供了名为`hub命令行工具,对Git进行了简单的封装。该项目在GitHub上的地址为: https://github.com/defunkt/hub )。下载并安装了hub后,在Git repo中,我可以像这样检查看我当前的CI状态。
$ hub ci-status
success
由于hub是一个Go语言开发的二进制程序,所以我只需要设置代理的参数即可。
$ https_proxy=127.0.0.1:8080 hub ci-status
Error fetching statuses: Get https://api.github.com/repos/ropnop/blog.ropnop.com/commits/89c7759ac344d5a412dc63ce3f053fc3f06d09a0/status: x509: certificate signed by unknown authority
而这里我们得到一个SSL错误的返回结果。
不幸的是,Go没有提供任何渠道来设置信任外界的CA证书。对于每个平台,Go都会在操作系统上寻找受信任的CA证书。
这时,你必须将Burp证书添加到你的系统的密钥链中。之后,Go就会检查到它,你就可以代理Go语言的二进制文件了。
$ https_proxy=127.0.0.1:8080 hub ci-status
success
希望这些内容对你能有帮助。Python、Node和Go囊括了我使用的绝大多数CLI工具,当然还有其他工具。无论你是在对一个应用或CLI进行渗透测试,还是只是在开发中想进行调试,学会拦截HTTP流量并对其进行分析真的很重要。