作为一个网络安全小菜鸡,最近开始想研究CTF。一方面是学习巩固相关的知识,另一方面也想多学一些技巧。俗话说:好记性不如烂笔头。所以专门当个笔记一样写在这,把相关题目的思路写下来,日后忘记了可以多回顾。生命不息,学习不止。
刚入门有所磕磕绊绊,如果有师傅看到哪里写错了或哪里没写好,希望可以帮忙指出,感激不尽!
Bugku的题有一些因为环境问题已经做不出来,所以后面可能会和ctfshow换着做题。
每次历经困难后看到flag的界面总是很激动,长出一口气。
1.Simple_SSTI_1
ssti叫Server Side Template Injection,服务端模板注入。模板可以理解为一段固定好格式,等着你来填充信息的文件。以{{}}作为变量包裹的标识符。同时,这个符号包裹内还可以执行一些简单的表达式。
flask注入的三种模板:
{% … %}
{{ … }}
{# … #}
{{config}} 可以获取当前设置,可以直接访问 {{config['FLAG']}} 或者 {{config.FLAG}} 得到 flag。
题目显示为需要传入一个flag参数。
![](https://i-blog.csdnimg.cn/blog_migrate/201d7a151d5f4847d2220f55ff9e3beb.png)
查看源代码,提示在flask中,设置了secret_key。那就是在注入模板中输入内容就会显示对应的值。
![](https://i-blog.csdnimg.cn/blog_migrate/f796abdf7aab7ee6dbf431e803ffa16d.png)
传入?flag={{SECRET_KEY}}显示空白。
![](https://i-blog.csdnimg.cn/blog_migrate/3b82787de9cc0771e32a762ea606f84b.png)
根据上面的知识,在前面加上config即可。
![](https://i-blog.csdnimg.cn/blog_migrate/7f0d2223d9e4f01da1daa7232c2e8f5c.png)
2.Simple_SSTI_2
魔术对象:
__class__:返回类型所属的对象
__mro__:返回一个包含对象所继承的基类元组,方法在解析时按照元组的顺序解析。
__base__"返回该对象所继承的基类 // __base__和__mro__都是用来寻找基类的
__subclasses__:获取当前类的所有子类
__init__ :类的初始化方法
__globals__:对包含(保存)函数全局变量的字典的引用
os.popen():
__globals__[‘os’].popen(‘ls’,‘r’).read()
依旧是服务端模板注入,查看源代码没有可利用的信息。
![](https://i-blog.csdnimg.cn/blog_migrate/1aa6a290e43f308e78ca1fed1b145bd4.png)
先试试传入config。
![](https://i-blog.csdnimg.cn/blog_migrate/b20b8b6c7b4c1297ae05cc168f87a533.png)
使用ls查看有哪些文件:
?flag={{config.__class__.__init__.__globals__[%27os%27].popen(%27ls%27,%27r%27).read()}}
![](https://i-blog.csdnimg.cn/blog_migrate/2a8bf359de7f073e48de44e10d329049.png)
发现了flag文件,直接cat查看?flag={{config.__class__.__init__.__globals__[%27os%27].popen(%27cat%20flag%27,%27r%27).read()}}
![](https://i-blog.csdnimg.cn/blog_migrate/ac4b309e9aabdfb201d187a18f3ad382.png)
3.Flask_FileUpload
os.system()函数:
os.system是os模块最基础的方法
原理:system函数可以将字符串转化成命令在服务器上运行
执行多条命令:
import os
os.system('cd /home ; mkdir 1.txt')
os.system('cd /home && mkdir 1.txt')
是一个文件上传的页面,查看源代码意思为:上传文件,我会返回python运行的结果
![](https://i-blog.csdnimg.cn/blog_migrate/434f05c3c23361509dde021b5a2f00e9.png)
试试上传一句话木马,果然失败了,并且源码限制了白名单为jpg、png。
![](https://i-blog.csdnimg.cn/blog_migrate/e9d53c1e4bbc01e902886733325d2368.png)
上传jpg发现可以,抓包中表明确实会用python执行。
![](https://i-blog.csdnimg.cn/blog_migrate/a39c2d0342ba85a5879634556477fbe4.png)
使用os模块,并把后缀改为jpg上传抓包,发现jpg内的代码执行成功,但是没有显示flag,说明不在当前目录下。
![](https://i-blog.csdnimg.cn/blog_migrate/9a9d0a43064ac368d848d7589eeb0077.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7a8fb63dea6d6e146ad2b5540de65067.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a9fbd79ae5fdbaeeecb22138adddd423.png)
重新上传查看根目录下的文件,发现flag位置。
![](https://i-blog.csdnimg.cn/blog_migrate/a3775af3f65be84043c2a1b2f0845e8d.png)
![](https://i-blog.csdnimg.cn/blog_migrate/c20acb376d7fbab6265f59a9525778b0.png)
burp直接repeater命令查看得到flag。
![](https://i-blog.csdnimg.cn/blog_migrate/3fa9349064247ebcc6054bddadbd1183.png)
4.滑稽
右键查看源码即可获得flag。
![](https://i-blog.csdnimg.cn/blog_migrate/98cd1bce199fc5d6ef207afe191b41c9.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ef5a5bd0b125d21220c7b78da9b74fe9.png)
5.留言板
注:本来需要使用xss平台打管理员cookie,但是环境出了问题缺少存放管理员账号密码的数据库文件。
进入后是一个留言板界面,插入XSS代码提交。
![](https://i-blog.csdnimg.cn/blog_migrate/b849d0158ccee9611641b5ffdf4c0900.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2e072ef39480fa3d4aab76b845d04406.png)
既然是留言板那应该需要管理员登录,并查看我们的XSS代码来获得管理员cookie。使用dirsearch扫描网站目录,发现admin.php。
![](https://i-blog.csdnimg.cn/blog_migrate/7df6cbb8dc65020cec9760f382e2b1e4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1048a4236631a643e8e8d0580c83747a.png)
因为网站问题少了个存放有账号密码的数据库文件,所以直接用账号admin,密码011be4d65feac1a8登录。
flag在cookie中,控制台输入alert(document.cookie)弹出cookie。
![](https://i-blog.csdnimg.cn/blog_migrate/19b49f31441129e0c4b9dc5771856487.png)
提交显示不正确,仔细一看发现花括号被编码了,解码即可。
![](https://i-blog.csdnimg.cn/blog_migrate/054adf8aa96f0ac7be87129db0765f3b.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ef42b70a8470ec2015b5ef0760c379f5.png)
6.计算器
进入后发现是一个计算题,口算下答案填进去就行了,但是发现写了1就写不了后面的数字了。
![](https://i-blog.csdnimg.cn/blog_migrate/714f9ea8fc40adfc5add0eaa3b6a9dd2.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1f5f91ac6cab001027607e13f13014ba.png)
F12看看,发现输入框maxlength="1",意思是最大长度是1,直接改成999提交即可获得flag。
![](https://i-blog.csdnimg.cn/blog_migrate/d1d1c427ac9bb7c8646965e6a7ffdaaf.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a8d4effab923c794d396ba21cbc1513e.png)
![](https://i-blog.csdnimg.cn/blog_migrate/5b5a65dd1647faa8ed83b362abfa3254.png)
7.GET
代码告诉我们用get方式对what进行传参,直接输入?what=flag即可。
![](https://i-blog.csdnimg.cn/blog_migrate/e588df22394702775a48b081052ab55f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/16751b4d113f48dbcb7cfd21e7058f2e.png)
8.POST
用POST方式对what进行传参。
![](https://i-blog.csdnimg.cn/blog_migrate/82e4fe208c6473f11a646fcc34dac453.png)
9.矛盾
进入页面显示的是源代码,通过GET方式传入num参数,如果传参不是数字(is_numeric() 函数用于检测变量是否为数字或数字字符串)输出参数。如果参数是1输出flag。
![](https://i-blog.csdnimg.cn/blog_migrate/727e9cf99a346683ef9eaa8cd860b423.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7db3747c9b734248537029c2026fa536.png)
但是传参是1时没有反应,仔细查看源码发现$num==1,==表示检查数据内容并且自动进行类型转换。非数字字符开头的字符串被转换成0,数字开头的字符串保留数字。与上面的is_numeric($num)函数结合,因此需要一个不是数字字符串并且与1弱相等的字符串。
![](https://i-blog.csdnimg.cn/blog_migrate/87af188dd20ae7c889adc3d4c7e212fb.png)
输入1'得到flag。
![](https://i-blog.csdnimg.cn/blog_migrate/f74bb2afeb80e1d0717cbac0f4acaafa.png)
10.弹窗
进来后重复弹两个窗口,想查看源代码也显示空白。
![](https://i-blog.csdnimg.cn/blog_migrate/96d08d9db03869b48551c506ee02bac4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/d86dbedc356735987848c4ca2d888610.png)
![](https://i-blog.csdnimg.cn/blog_migrate/623618d4f4fefd1f53dad2c5b37ad347.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4ced642ef40ff5ee3ef3b16613a9e67b.png)
在burp抓包查看返回包时,发现了Unicode编码,解码即可得到flag。
![](https://i-blog.csdnimg.cn/blog_migrate/f395e9ca1fda0ffde3b132a1034b5d25.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7967ba61e0eeccbfda6cafeba82a7984.png)
11.你必须让它停下
进入后会一直刷新界面,其中有一个界面不一样,可能flag就在这个页面中。
![](https://i-blog.csdnimg.cn/blog_migrate/a7a5a8c4f7cc0b75dd5f812e740963e4.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ce910f8ced44830c87cb9f8faea898c1.png)
既然要抓取其中的一个界面,使用burp抓包拦截,一直到我们想要的数据包。
![](https://i-blog.csdnimg.cn/blog_migrate/8998792993f6ddf827b993f1b8cd345d.png)
flag就在其中。
![](https://i-blog.csdnimg.cn/blog_migrate/721c8ed27284333b80bc60af20466dd1.png)
12.game1
进入是一个游戏界面,抓包玩了一会,发现了三个参数score分数,IP地址,sign。sign的值感觉像是被编码过。放进base64解码,无法解析。应该是从编码入手,多试几次看看。
![](https://i-blog.csdnimg.cn/blog_migrate/89ccaa0656db1d42d36603caa8d8c407.png)
![](https://i-blog.csdnimg.cn/blog_migrate/32293776a12cbf4bff3c4df75e0e3349.png)
重新玩了几次,发现sign的值前两位zM是固定的。
![](https://i-blog.csdnimg.cn/blog_migrate/301fa68c61ec77f3fcd8dc5f12b34d20.png)
![](https://i-blog.csdnimg.cn/blog_migrate/7e814200628359399250fca9f647cc16.png)
把zM去除重新base64解码成功。
![](https://i-blog.csdnimg.cn/blog_migrate/388d49605d5dd961953eddcf60612a77.png)
把score改成10000,并把sign改为zM+经过base64编码后10000的值,发送数据包即可得到flag。
![](https://i-blog.csdnimg.cn/blog_migrate/8cff710ac1b3616fce5a36b619cfda74.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ce7639c6ea7e57514a37d09145c46667.png)
后面发现源码中也显示了经过base64编码,还是要仔细一些。多看看源码,有时候可以少走弯路。
![](https://i-blog.csdnimg.cn/blog_migrate/d421b18a4d10a84d794215dc104443d3.png)
13.网站被黑
进入显示网站有漏洞,那可能存在黑客留下的后门文件。使用dirseatch扫描,发现存在shell.php。
![](https://i-blog.csdnimg.cn/blog_migrate/53d1e310fd753d7a5028d52c6d62d685.png)
![](https://i-blog.csdnimg.cn/blog_migrate/4ec2c01b4d613166fda24036d6d7976f.png)
试了几次弱口令都不对,使用burp爆破出密码是hack,登录即可得到flag。
![](https://i-blog.csdnimg.cn/blog_migrate/2836b90b49979293bf9319b7cae139ed.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a28f97a0bb86d0b073356dce86ab5987.png)
14.管理员系统
是一个登录界面,并且下面有很多n,应该里面藏着有用的信息,仔细查看源码看到最后发现有base64编码,解密得到test123,可能是账户或者密码。
![](https://i-blog.csdnimg.cn/blog_migrate/810912098b75809afab8de34f5b452b8.png)
![](https://i-blog.csdnimg.cn/blog_migrate/1fbddd242bced43154c6ea55b824e86a.png)
输入admin/123456登录,显示IP禁止访问,猜测和数据包中的IP参数有关。抓包查看发现确实没有请求头部。
![](https://i-blog.csdnimg.cn/blog_migrate/ea730c2de2fa0d4259a28889ddb8e8a3.png)
X-Forwarded-For 是一个 HTTP 扩展头部。在数据包添加X-Forwarded-For:127.0.0.1重新发包即可。
![](https://i-blog.csdnimg.cn/blog_migrate/843026a1ca33f694c854a9082ac290aa.png)
15.BP
进入后是个登录界面,用户告诉了我们是admin,密码提示是弱口令top1000中的z开头密码。随意输入密码后会显示“账号或密码错误”
![](https://i-blog.csdnimg.cn/blog_migrate/ca29eadd644b2f86bf3236f95da6b9fa.png)
导入字典进行爆破,发现长度都一样无法找到爆破成功的数据。
![](https://i-blog.csdnimg.cn/blog_migrate/31be3be13f61df6fe0c6cce4d09914f1.png)
通过观察Response,发现错误的数据包中都包含特定JS代码告诉我们用户或密码错误。
![](https://i-blog.csdnimg.cn/blog_migrate/a7b181f4392b39f5cb53b089340fe428.png)
所以只要标识出错误返回包中的code值,那么没有出现标识的就是正确的密码。需要用到burp中的options——Grep-Match:在响应中找出存在指定的内容的一项。
![](https://i-blog.csdnimg.cn/blog_migrate/daf37419d0cd5753351a8b028be3bb84.png)
爆破完成后发现zxc123返回包中没有错误code值,因此密码为zxc123。
![](https://i-blog.csdnimg.cn/blog_migrate/2fd31fc80f7b03a84827e982985d02e8.png)
登录后即可获得flag。
![](https://i-blog.csdnimg.cn/blog_migrate/2e1a0808dc3eb57699ec1d1d6c704371.png)
16.eval
var_dump函数用于输出变量的相关信息,显示关于一个或多个表达式的结构信息。
show_source() 函数对文件进行语法高亮显示,是 highlight_file() 的别名。
考察文件包含,已经包含了flag.php,并且hello是变量,直接执行命令查看flag.php。
![](https://i-blog.csdnimg.cn/blog_migrate/120625c660e7210974906792f50f4983.png)
发现显示不完全。
![](https://i-blog.csdnimg.cn/blog_migrate/268885321a636c45e56cef978aec679b.png)
查询whoami试试,可以正常显示。
![](https://i-blog.csdnimg.cn/blog_migrate/8f9d680f5a92cd066964807adbc89f0a.png)
后面发现显示不完全查看源码即可。
![](https://i-blog.csdnimg.cn/blog_migrate/f056503f7d700b84c2150f7758cb8167.png)
也可以用file函数读取文件。
![](https://i-blog.csdnimg.cn/blog_migrate/703485f92d9cb935d3e53911de3921ee.png)
17.变量1
error_reporting(0)关闭错误报告,
包含flag1.php,
highlight_file(file)高亮显示文件,
preg_match("/^\w+$/"字符串的规则匹配,开头的 ^ 和结尾的 $ 让PHP从字符串开头检查到结尾,\w 匹配包括下划线的任何单词字符。等价于“[A-Za-z0-9_]
![](https://i-blog.csdnimg.cn/blog_migrate/20ada82e7f1e9a5f12efd086b69e3da4.png)
本题使用超全局变量$GLOBALS,还有其他超全局变量: $_SERVER 、$_REQUEST 、$_POST 、$_GET 、$_FILES 、$_ENV 、$_COOKIE 、$_SESSION。意味着它们在一个脚本的全部作用域中都可用。在函数或方法中无需执行 global $variable; 就可以访问它们。
![](https://i-blog.csdnimg.cn/blog_migrate/1fc5dec4cacf41f5ab7d5987f9a463d1.png)
18.头等舱
进入以后页面只有文字,没有其他信息,这时第一反应就是f12查看源代码并抓包
![](https://i-blog.csdnimg.cn/blog_migrate/5c3d035c78bd3f3aa0b60a915ddd9150.png)
在返回包中的HTTP头部直接发现flag
![](https://i-blog.csdnimg.cn/blog_migrate/8e322a85c1ab1b40edc0e5aaac72012a.png)
19.社工——伪造
进入后是一个聊天框界面,需要和小美对话后拿到flag。
输入qq号登录后聊天并不会给。
![](https://i-blog.csdnimg.cn/blog_migrate/79f129930ce0c24ddb453851eedbbb29.png)
查看小美空间,找到了关键信息:
1.只有她男朋友问她要才会给flag,需要伪造成她男朋友
2.如何伪造呢?有她男朋友的qq号和qq昵称‘小bug’
qq号无法再创建一模一样的,qq昵称可以改成一样的。重新登录把昵称改成'小bug'再向小美发送flag即可
![](https://i-blog.csdnimg.cn/blog_migrate/3733f7ae5ad4a863a78ffd14cd1a791f.png)
20.source
右键查看源代码中有一个flag,但是假的
![](https://i-blog.csdnimg.cn/blog_migrate/c42ca0c6dcd6f0692cb4ca2778c60f0b.png)
使用diesearch扫描目录,发现有.git文件泄露和flag.txt,访问flag.txt也是个假flag
![](https://i-blog.csdnimg.cn/blog_migrate/ca25b22d0f324818b05f84b80a42cd25.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a234fdca174b36be4dd47b88f5e97e7c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/414dd2e19a788a8db51b4e36365e5719.png)
打包下载.git文件:wget -r http://114.67.175.224:16353/.git/
![](https://i-blog.csdnimg.cn/blog_migrate/d2d6b7324a2de0ac16a60e20df70ef2e.png)
使用git reflog查看文件历史操作记录
![](https://i-blog.csdnimg.cn/blog_migrate/28452e81cc0a36538d6ac36ded1dc6d7.png)
使用git show显示提交或者某个文件的历史修改详细信息
![](https://i-blog.csdnimg.cn/blog_migrate/20cee47ec6a41b2c0ca879f4a66d371d.png)
在文件40c6d51找到正确的flag
![](https://i-blog.csdnimg.cn/blog_migrate/bd36a79bdecf64640979c7aed88d24bb.png)
21.源代码
查看源代码发现两个值p1、p2,并用url解码得到
p1=function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a){if("67d709b2b
p2=aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").οnsubmit=checkSubmit;
合并得到代码:
function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a{if("67d709b2b54aa2aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").οnsubmit=checkSubmit;
代码意思为在表单提交前验证密码输入框中的值是否于"67d709b2b54aa2aa648cf6e87a7114f1",把这个值输入并提交即可得到flag
22.文件包含
点击“click me”,url显示了“index.php?file=show.php”,存在文件包含
url输入“?file=/flag”可直接显示flag
也可以使用php://filter伪协议读取index.php源码。url输入“file=php://filter/read=convert.base64-encode/resource=index.php”,并用base64解码
![](https://i-blog.csdnimg.cn/blog_migrate/24e9d98c7a9ad71ab59538df76d807ba.png)
![](https://i-blog.csdnimg.cn/blog_migrate/2eab31cd93cbdafcf2366587f602de25.png)
23.好像需要密码
页面显示输入5位数密码查看,使用burp爆破。
![](https://i-blog.csdnimg.cn/blog_migrate/83528caf73a5bbbfbd9f13f5fc5a103f.png)
爆破出正确密码,得到flag
![](https://i-blog.csdnimg.cn/blog_migrate/fbf19ffd4a30a8d6f9a9daaead987eea.png)
24.备份是个好习惯
页面是一段字符串,并且是两段d41d8cd98f00b204e9800998ecf8427e重复的两段,通过cmd5解码为空密码
![](https://i-blog.csdnimg.cn/blog_migrate/514d70099be3acc399267c3fbf4c12b8.png)
使用目录扫描出备份文件index.php.bak
![](https://i-blog.csdnimg.cn/blog_migrate/8e1fa372bae912d7041999e02d1e546c.png)
查看bak文件,这段代码的功能是从URL中获取参数并计算它们的MD5哈希值,如果两个参数的哈希值相同但参数值不同,则输出$flag变量的值,这里使用了一个从另一个文件flag.php中导入的变量。
include_once "flag.php"; #导入flag.php文件中的变量,此处包括$flag变量。 ini_set("display_errors", 0); #设置错误显示为0,避免意外泄露代码信息。
$str = strstr($_SERVER['REQUEST_URI'], '?'); #从请求的URL中获取参数并去掉开头的'?'。 $str = substr($str,1);
$str = str_replace('key','',$str); #用空字符替换'key',从而获得原始参数。 parse_str($str); #解析字符串并存储在$key1和$key2变量中。 echo md5($key1);
echo md5($key2); #输出$key1和$key2的MD5哈希值。 if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag."取得flag";
} #如果$key1和$key2的哈希值相同但参数值不同,则输出$flag变量的值。
分析代码,首先对key进行了过滤,并且key1和key2需要参数不同但哈希值相同,那么需要两个都为空的不同值。
(1)经MD5加密后的值为0e.....格式,会认定为科学计数法,表示0×10的n次方为0且相等。
下面字符串的md5值为0e开头:
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
构造url:?kkeyey1=240610708&kkeyey2=s155964671a
![](https://i-blog.csdnimg.cn/blog_migrate/02f1c7d4be46d34f8ead703287c9404e.png)
(2)经查阅还可以使用数组绕过。md5()函数无法处理数组,如果传入数组会返回NULL。那么传入两个不同的数组即可
构造url:?kkeyey1[]=123&kekeyy2[]=456
![](https://i-blog.csdnimg.cn/blog_migrate/4f96189afca4a38b4de5d813bdaa56d5.png)