参考书籍:《从0到1:ctfer成长之路》
对相应实战案例进行复现总结
前言
在传统的CTF线上比赛中,Web类题目是主要的题型之一,相较于二进制、逆向等类型的题目,参赛者不需掌握系统底层知识;相较于密码学、杂项问题,不需具特别强的编程能力,故入门较为容易。Web类题目常见的漏洞类型包括注入、XSS、文件包含、代码执行、上传、SSRF等。
本章将分别介绍CTF线上比赛中常见的各种Web漏洞,通过相关例题解析,尽可能让读者对CTF线上比赛的Web类题目有相对全面的了解。但是Web漏洞的分类十分复杂,希望读者在阅读本书的同时在互联网上了解相关知识,这样才可以达到举一反三的目的,以便提升自身能力。
按照漏洞出现的频率、漏洞的复杂程度,我们将Web类题目分为入门、进阶、拓展三个层次进行介绍。讲解每个层次的漏洞时,我们辅以相关例题解析,让读者更直观地了解CTF线上比赛中Web类题目不同漏洞带来的影响,由浅入深地了解Web类题目,清楚自身技能的不足,从而达到弥补的目的。本章从“入门”层次开始,介绍Web类题目中最常见的3类漏洞,即信息搜集、SQL注入、任意文件读取漏洞。
1.1 举足轻重的信息搜集
1.1.1 信息搜集的重要性
古人云“知己知彼,百战不殆”,在现实世界和比赛中,信息搜集是前期的必备工作,也是重中之重。在CTF线上比赛的Web类题目中,信息搜集涵盖的面非常广,有备份文件、目录信息、Banner信息等,这就需要参赛者有丰富的经验,或者利用一些脚本来帮助自己发现题目信息、挖掘题目漏洞。本节会尽可能叙述在CTF线上比赛中Web类题目包含的信息搜集,也会推荐一些作者测试无误的开源工具软件。
因为信息搜集大部分是工具的使用(git泄露可能涉及git命令的应用),所以本章可能不会有太多的技术细节。同时,因为信息搜集的种类比较多,本章会尽可能地涵盖,如有不足之处还望理解;最后会通过比赛的实际例子来体现信息搜集的重要性。
1.1.2 信息搜集的分类
前期的题目信息搜集可能对于解决CTF线上比赛的题目有着非常重要的作用,下面将从敏感目录、敏感备份文件、Banner识别三方面来讲述基础的信息搜集,以及如何在CTF线上比赛中发现解题方向。
1.1.2.1 敏感目录泄露
通过敏感目录泄露,我们往往能获取网站的源代码和敏感的URL地址,如网站的后台地址等。
1.git泄露
【漏洞简介】
git是一个主流的分布式版本控制系统,开发人员在开发过程中经常会遗忘.git文件夹,导致攻击者可以通过.git文件夹中的信息获取开发人员提交过的所有源码,进而可能导致服务器被攻击而沦陷。
(1)常规git泄露
常规git泄露:即没有任何其他操作,参赛者通过运用现成的工具或自己编写的脚本即可获取网站源码或者flag。这里推荐一个工具:https://github.com/denny0223/scrabble,使用方法也很简单:
./scrabble http://example.com/
本地自行搭建Web环境
初始化git(在内部会生成隐藏的.git文件夹)
git add 命令可将flag.php文件添加到暂存区。
文件修改后,我们一般都需要进行 git add 操作,从而保存历史版本。
git commit -m “注释”把它提交到版本库:
git status -sb 查看工作区
运行该工具,即可获取源代码,拿到flag
./scrabble http://127.0.0.1/git_test/
注:该工具只能在linux下运行
(2)git回滚
git作为一个版本控制工具,会记录每次提交(commit)的修改,所以当题目存在git泄露时,flag(敏感)文件可能在修改中被删除或被覆盖了,这时我们可以利用git的“git reset”命令来恢复到以前的版本。本地自行搭建Web环境
echo "flag is old" > flag.php
覆盖flag
我们先利用scrabble工具获取源码,再通过“git reset–hard HEAD^”命令跳到上一版本(在git中,用HEAD表示当前版本,上一个版本是HEAD^),即可获取到源码
除了使用“git reset”,更简单的方式是通过“git log-stat”命令查看每个commit修改了哪些文件,再用“git diff HEAD commit-id”比较在当前版本与想查看的commit之间的变化。
(3)git分支
在每次提交时,git都会自动把它们串成一条时间线,这条时间线就是一个分支。而git允许使用多个分支,从而让用户可以把工作从开发主线上分离出来,以免影响开发主线。如果没有新建分支,那么只有一条时间线,即只有一个分支,git中默认为master分支。因此,我们要找的flag或敏感文件可能不会藏在当前分支中,这时使用“git log”命令只能找到在当前分支上的修改,并不能看到我们想要的信息,因此需要切换分支来找到想要的文件。
现在大多数现成的git泄露工具都不支持分支,如果需要还原其他分支的代码,往往需要手工进行文件的提取,这里以功能较强的GitHacker(https://github.com/WangYihang/GitHacker)工具为例。GitHacker的使用十分简单,只需执行命令“python GitHacker.py http://127.0.0.1:8000/.git/”。运行后,我们会在本地看到生成的文件夹,进入后执行“git log–all”或“git branch-v”命令,只能看到master分支的信息。如果执行“git reflog”命令,就可以看到一些checkout的记录,见图1-1-5。
可以看到,除了master还有一个secret分支,但自动化工具只还原了master分支的信息,因此需要手动下载secret分支的head信息,保存到.git/refs/heads/secret中(执行命令“wget http://127.0.0.1:8000/.git/refs/heads/secret”)。恢复head信息后,我们可以复用GitHacker的部分代码,以实现自动恢复分支的效果。在GitHacker的代码中可以看到,他是先下载object文件,再使用git fsck检测,并继续下载缺失的文件。此处可以直接复用检测缺失文件并恢复的fixmissing函数。我们注释掉程序最后调用main的部分,修改为如下代码:
修改后重新执行“python GitHacker.py”命令,运行该脚本,再次进入生成的文件夹,执行“git log–all”或“git branch-v”命令,则secret分支的信息就可以恢复了,从git log中找到对应提交的hash,执行“git diff HEAD b94c”(b94c为hash的前4位)命令,即可得到flag,见图1-1-6。
(4)git泄露的其他利用
除了查看源码的常见利用方式,泄露的git中也可能有其他有用的信息,如.git/config文件夹中可能含有access_token信息,从而可以访问这个用户的其他仓库。
2.SVN泄露
SVN(subversion)是源代码版本管理软件,造成SVN源代码漏洞的主要原因是管理员操作不规范将SVN隐藏文件夹暴露于外网环境,可以利用.svn/entries或wc.db文件获取服务器源码等信息。这里推荐两个工具:https://github.com/kost/dvcs-ripper,Seay-svn(Windows下的源代码备份漏洞利用工具)。
3.HG泄露
在初始化项目时,HG会在当前文件夹下创建一个.hg隐藏文件夹,其中包含代码和分支修改记录等信息。这里推荐工具:https://github.com/kost/dvcs-ripper。
4.总结经验
不论是.git这些隐藏文件,还是实战中的admin之类的敏感后台文件夹,其关键在于字典的强大,读者可以在某些工具的基础上进行二次开发,以满足自己需要。这里推荐一个开源的目录扫描工具:https://github.com/maurosoria/dirsearch。CTF线上比赛往往会有重定向一类问题。例如,只要访问.git,便会返回403,此时**试探着访问.git/config**,如果有文件内容返回,就说明存在git泄露,反之,一般不存在。
而在SVN泄露中,一般是在entries中爬取源代码,但有时会出现entries为空的情况,这时注意wc.db文件存在与否,便可通过其中的checksum在pristine文件夹中获取源代码。
1.1.2.2 敏感备份文件
通过一些敏感的备份文件,我们往往能获得某一文件的源码,亦或网站的整体目录等。
1.gedit备份文件
在Linux下,用gedit编辑器保存后,当前目录下会生成一个后缀为“~”的文件,其文件内容就是刚编辑的内容。假设刚才保存的文件名为flag,则该文件名为flag~,见图1-1-7。通过浏览器访问这个带有“~”的文件,便可以得到源代码。
2.vim备份文件
vim是目前运用得最多的Linux编辑器,当用户在编辑文件但意外退出时(如通过SSH连接到服务器时,在用vim编辑文件的过程中可能遇到因为网速不够导致的命令行卡死而意外退出的情况),会在当前目录下生成一个备份文件,文件名格式为:
.文件名.swp
该文件用来备份缓冲区中的内容即退出时的文件内容,见图1-1-8。
针对SWP备份文件,我们可以用“vim-r”命令恢复文件的内容。这里先模拟执行“vim flag”命令,随后直接关闭客户端,当前目录下会生成一个.flag.swp文件。恢复SWP备份文件的办法是,先在当前目录下创建一个flag文件,再使用“vim-rflag”命令,即可得到意外退出时编辑的内容,见图1-1-9。
3.常规文件
常规文件所依靠的无非就是字典的饱和性,不论是CTF比赛中还是现实世界中,我们都会碰到一些经典的有辨识的文件,从而让我们更好地了解网站。这里只是简单举一些例子,具体还需要读者用心搜集记录。
❖ robots.txt:记录一些目录和CMS版本信息。
❖ readme.md:记录CMS版本信息,有的甚至有Github地址。
❖ www.zip/rar/tar.gz:往往是网站的源码备份。
4.总结经验
在CTF线上比赛的过程中,出题人往往会在线运维题目,有时会因为各种情况导致SWP备份文件的生成,所以读者在比赛过程中可以编写实时监控脚本,对题目服务进行监控。vim在第一次意外退出时生成的备份文件为.swp,第二次意外退出时的为.swo,第三次退出时的为.swn,以此类推。vim的官方手册中还有.un.文件名.swp类型的备份文件。另外,在实际环境中,网站的备份往往可能是网站域名的压缩包。
1.1.2.3 Banner识别
在CTF线上比赛中,一个网站的Banner信息(服务器对外显示的一些基础信息)对解题有着十分重要的作用,选手往往可以通过Banner信息来获得解题思路,如得知网站是用ThinkPHP的Web框架编写时,我们可以尝试ThinkPHP框架的相关历史漏洞。或者得知这个网站是Windows服务器,那么我们在测试上传漏洞时可以根据Windows的特性进行尝试。这里介绍最常用的两种Banner识别方式。
1.自行搜集指纹库
Github上有大量成型且公开的CMS指纹库,读者可以自行查找,同时可以借鉴一些成型扫描器对网站进行识别。
2.使用已有工具
我们可以利用Wappalyzer工具(见图1-1-10),同时提供了成型的Python库,用法如下:
在data目录下,apps.json文件是其规则库,读者可以根据自己需求自由添加。
3.总结经验
在进行服务器的Banner信息探测时,除了通过上述两种常见的识别方式,我们还可以尝试随意输入一些URL,有时可以通过404页面和302跳转页面发现一些信息。例如,开启了debug选项的ThinkPHP网站会在一些错误页面显示ThinkPHP的版本。
1.1.3 从信息搜集到题目解决
下面通过一个CTF靶场赛场景的复盘,来展示如何从信息搜集到获得flag的过程。
1.环境信息
❖ Windows 7.
❖ PHPstudy 2018(开启目录遍历)。
❖ DedeCMS(织梦CMS,未开启会员注册)。
2.解题步骤
通过访问网站,根据观察和Wappalyzer的提示(见图1-1-11和图1-1-12),我们可以发现这是搭建在Windows上的DedeCMS,访问默认后台目录发现是404,见图1-1-13。
这时我们可以联想到DedeCMS在Windows服务器上存在后台目录爆破漏洞(漏洞成因在这里不过多叙述,读者可以自行查阅),我们在本地运行爆破脚本,得到目录为zggga111,见图1-1-14。
但是经过测试,我们发现其关闭了会员注册功能,也就意味着我们不能利用会员密码重置漏洞来重置管理员密码。我们应该怎么办?其实,在DedeCMS中,只要管理员登录过后台,就会在data目录下有一个相应的session文件,而这个题目恰好没有关闭目录遍历,见图1-1-15。所以我们可以获得管理员的session值,通过editcookie修改Cookie,从而成功进入后台,见图1-1-16。
然后在模板的标签源码碎片管理中插入一段恶意代码,即可执行任意命令,见图1-1-17和图1-1-18。
3.总结这个例子可以反映信息搜集的重要性,体现在如下两方面。
❖ 一是服务器的信息,针对Windows服务器,大概率意味着我们去寻找CMS在其上的一些漏洞。
❖ 二是在不知道密码和无法重置的情况下,通过CMS网站本身的特性,结合目录遍历来实现最后的RCE(Remote Command/Code Execute,远程命令/代码执行)。