通过web程序,在服务器上拼接系统命令。
基础知识
正常情况下,是ping一个IP地址。确定调用系统命令
确定可控字段
确定命令语句,&&可以连接两条Windows命令
命令注入的条件:
- web应用程序调用可执行系统命令的函数
- 执行系统命令的函数或函数的参数可控
- 可控参数可拼接注入参数
PHP执行系统命令的函数:
system
exec
shell_exec
eval
…
&,&&,|,|| 的区别:
- A&B:简单的拼接,A、B之间无制约关系
- A&&B:A执行成功,然后才会执行B
- A|B:A的输出,作为B的输入
- A||B:A执行失败,然后才会执行B
漏洞利用
服务器进行参数过滤
这个限制一般是题目中允许你使用system,但是很奇怪的是你却没有办法获取执行命令的结果。比如,对面过滤了空格,你能执行ls,但是没法cat读取文件。比如,对面过滤了flag这个词语,什么文件都可以读取,就是没办法读取flag等等,都是ctf题目做到最后,这个出题人小心思故意在这里卡你一下。这个时候你就需要试试我接下来讲的这些方法:
空格代替
空格在bash下,可以用以下字符代替空格<
${IFS}
${IFS}$9
%09
这里解释一下$ {IFS},$ IFS,$ IFS $ 9的区别
首先$ IFS在linux下表示分隔符,只有cat$ IFSa.txt的时候,bash解释器会把整个IFSa当做变量名,所以导致没有办法运行,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用,而$9指的是当前系统shell进程的第九个参数的持有者,就是一个空字符串,因此$9相当于没有加东西,等于做了一个前后隔离。
截断符号
ctf很喜欢考的一点是命令执行的连接,这个地方它通常会给一个已有的命令执行,比如代码写好了ping命令,叫你填写一个ip参数这样的题目,这个时候就需要测试截断符号,将你输入的ip参数和后面要执行的命令隔开。首先测试所有的截断符号:
利用截断符号配合普通命令简单问题基本就出来;例如:ip=127.0.0.1;cat /home/flag.txt这样就可以达到同时执行两条命令的效果
利用base编码绕过
这种绕过针对的是系统过滤敏感字符的时候,比如他过滤了cat命令,那么就可以用下面这种方式将cat先base64编码后再进行解码运行。
过滤了敏感命令
如过滤了whoami,可以使用who”“ami,who”“am”“i
借鉴了:
https://baijiahao.baidu.com/s?id=1663384918072293799&wfr=spider&for=pc
https://blog.****.net/qq_45552960/article/details/104576189
对比
和文件上传漏洞对比
相同点
相同的地方是都是根据程序调用系统命令
不同点
命令注入是程序调用系统命令,在参数没有约束的情况下,在参数后加上需要执行的系统命令。这个限制在于程序不一定提供这种调用系统命令的功能。
文件上传漏洞是自己手动上传一个执行系统命令的页面,然后访问这个页面,把命令以参数的形式传给页面执行。
和远程代码执行对比
远程代码执行实际上是调用服务器网站代码进行执行,而命令注入则是调用操作系统命令进行执行。
工具的使用
防护
白名单保护
如果命令的参数是有特征性的建议使用白名单对输入的参数进行保护
比如允许[a-z][A-Z][0-9] _- 等有限的字符
黑名单保护
|;&$><`! 可以将这些字符直接作为黑名单过滤
\t\n\r\f \u0000 这些字符需要作为黑名单过滤,特别是空字符截断 \u0000 (这个在JVM6里是没有保护)