DVWA全级别通关笔记(二)-- Command Injection(命令注入)
引言
结合DVWA提供的命令注入模块,对命令注入漏洞进行学习总结。命令注入(Command Injection)是指通过提交恶意构造的参数破坏命令语句结构,从而达到执行恶意命令的目的。
在一些web应用中,某些功能可能会调用一些命令执行函数,比如php中的system、exec、shell_exec等。如果对用户输入的淑数据过滤不充分的话,很容易造成命令执行漏洞。
环境
phpstudy(搭建DVWA)
Command Injection
low
我们先分析一下漏洞源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php if ( isset( $_POST [ 'submit' ] ) ) { $target = $_REQUEST [ 'ip' ];<br> // Determine OS and execute the ping command. if ( stristr (php_uname( 's' ), 'Windows NT' )) { $cmd = shell_exec( 'ping ' . $target ); echo '<pre>' . $cmd . '</pre>' ; } else { $cmd = shell_exec( 'ping -c 3 ' . $target ); echo '<pre>' . $cmd . '</pre>' ; } } ?> |
stritr函数主要用来查找字符串,并返回。php_uname返回运行PHP的操作系统描述。如果是windows系统则执行 “ping + $target” ,如果是linux系统,执行“ping -c 3 + target”, 并没有对用户输入的变量ip进行过滤,而是直接执行ping + target中的内容,所以存在命令执行漏洞,管道运算符使用的会比较多。
A && B: 先执行A,如果成功,执行B;
A || B :先执行A,如果失败,执行B;
A | B:管道,先执行A后,将A的结果作为B的输入,打印的是B的结果;
A & B:先执行A,然后不管成功与否,执行B;
可以使用以下payload,注入成功。
1 2 3 4 5 | 127.0.0.1;ifconfig 127.0.0.1&ifconfig 127.0.0.1&&ifconfig 127.0.0.1|ifconfig x||ifconfig |
medium
先分析一下源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?php if ( isset( $_POST [ 'submit' ] ) ) { $target = $_REQUEST [ 'ip' ]; // Remove any of the charactars in the array (blacklist). $substitutions = array ( '&&' => '' , ';' => '' , ); $target = str_replace ( array_keys ( $substitutions ), $substitutions , $target ); // Determine OS and execute the ping command. if ( stristr (php_uname( 's' ), 'Windows NT' )) { $cmd = shell_exec( 'ping ' . $target ); echo '<pre>' . $cmd . '</pre>' ; } else { $cmd = shell_exec( 'ping -c 3 ' . $target ); echo '<pre>' . $cmd . '</pre>' ; } } ?> |
这里创建了一个黑名单substitutions,对用户输入数据的 ‘ && ’ 和 ‘ ; ’进行了过滤。但是并没有对所有的管道运算符进行过滤,我们依然可以使用以下payload达到命令执行目的。
1 | 1270.0.1999||ls -l<br>127.0.0.1&ls -l<br>127.0.0.1|ls -l |
high
分析一下源码:
1 2 3 4 | <?php <br> if ( isset( $_POST [ 'Submit' ] ) ) {<br> // Get input<br> $target = trim($_REQUEST[ 'ip' ]); <br> // Set blacklist<br> $substitutions = array(<br> '&' => '',<br> ';' => '',<br> '| ' => '',<br> '-' => '',<br> '$' => '',<br> '(' => '',<br> ')' => '',<br> '`' => '',<br> '||' => '',<br> );<br> // Remove any of the charactars in the array (blacklist).<br> $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); <br> // Determine OS and execute the ping command.<br> if( stristr( php_uname( 's' ), 'Windows NT' ) ) {<br> // Windows<br> $cmd = shell_exec( 'ping ' . $target );<br> }<br> else {<br> // *nix<br> $cmd = shell_exec( 'ping -c 4 ' . $target );<br> }<br> // Feedback for the end user<br> echo "<pre>{$cmd}</pre>"; <br>}<br>?> |
high级别的源码对黑名单进行了扩充,过滤了更多可能造成命令执行的运算符,包括 ‘&’ 、‘;’ 、‘| ’ 、‘-’ 、‘$’ 、‘(’ 、‘)’ 、‘`’ 、‘||’ ,这里过滤的‘| ’中间有个空格,所以我们使用 ‘|’ 就可以绕过黑名单了。
1 | 127.0.0.1|ls |
impossiable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php if ( isset( $_POST [ 'Submit' ] ) ) { // Check Anti-CSRF token checkToken( $_REQUEST [ 'user_token' ], $_SESSION [ 'session_token' ], 'index.php' ); // Get input $target = $_REQUEST [ 'ip' ]; $target = stripslashes ( $target ); // Split the IP into 4 octects $octet = explode ( "." , $target ); // Check IF each octet is an integer if ( ( is_numeric ( $octet [0] ) ) && ( is_numeric ( $octet [1] ) ) && ( is_numeric ( $octet [2] ) ) && ( is_numeric ( $octet [3] ) ) && ( sizeof( $octet ) == 4 ) ) { // If all 4 octets are int's put the IP back together. $target = $octet [0] . '.' . $octet [1] . '.' . $octet [2] . '.' . $octet [3]; // Determine OS and execute the ping command. if ( stristr ( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>" ; } else { // Ops. Let the user name theres a mistake echo '<pre>ERROR: You have entered an invalid IP.</pre>' ; } } // Generate Anti-CSRF token generateSessionToken(); ?> |
explode函数
explode函数将用户输入的ip以 ‘.’ 为分隔符,分为四个字符,将这四个字符放入数组中,并判断这四个元素是否为数字或者数字字符串,如果不是则不执行命令。
命令注入的防御措施
1、采用白名单,或使用正则表达式进行过滤。
2、不要让用户可以直接控制eval()、system、exec、shell_exec等函数的参数。
3、在进入执行命令函数和方法前,对变量进行过滤,对敏感字符进行转义。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单