两年前两分钟热度加入了学校ctf战队,web入门刚学完就退出了,现在都全忘了~写文章慢慢记录一下
网址:ctf.showd
进入靶场,看见的全是php的源码
讲解一下:
这段代码是一个简单的 PHP 程序,用于从数据库中查询文章信息。让我来解释一下它的工作原理:
1. PHP 代码部分:
- `include("config.php");`:包含了一个名为 `config.php` 的文件,该文件用于数据库连接。
- `if(isset($_GET['id']))`:判断是否有名为 `id` 的 GET 参数提交。
- `if(intval($id) > 999)`:检查提交的 `id` 是否大于 999。如果是,则直接输出 "id error" 并结束程序。
- 否则,拼接 SQL 查询语句,并执行查询。
如果有查询结果,则将结果以 HTML 格式输出到页面上。
这里有一个知识点 intval()函数,具体我是在这篇文章里面看懂的ctfshow-萌新-web1( 利用intval函数的特性获取敏感数据)_ctf恢复丢失的敏感数据-CSDN博客
自己做些知识点补充:
`intval()` 是一个 PHP 函数,用于获取变量的整数值。它的作用是将变量转换为整数类型,并返回结果。以下是 `intval()` 函数的基本语法:
intval($var, $base);
其中,`$var` 是要转换为整数的变量,`$base` 是可选参数,表示要用作转换的进制数。
- 如果 `$var` 是一个数字或者包含数字的字符串,`intval()` 将返回其整数值。
- 如果 `$var` 是一个浮点数,`intval()` 将返回其截断的整数部分。
- 如果 `$var` 是一个布尔值,`intval()` 将返回 1(对应于 `true`)或 0(对应于 `false`)。
- 如果 `$var` 是一个非数字的字符串,`intval()` 将返回 0。
- 如果 `$var` 是一个数组或者对象,`intval()` 将返回 0。如果省略了第二个参数 `$base`,则默认使用十进制。如果提供了 `$base` 参数,则将按照给定的进制进行转换。
以下是一些示例:
$num = "123"; echo intval($num); // 输出:123 $floatNum = 3.14; echo intval($floatNum); // 输出:3 $str = "abc123"; echo intval($str); // 输出:0 $binary = "1010"; echo intval($binary, 2); // 输出:10,将二进制字符串转换为十进制整数
`intval()` 函数在处理用户输入时常用于类型转换和输入验证,但在一些情况下可能会导致意外的结果,因此在使用时需要小心谨慎。
- 最后,关闭数据库连接。
2. HTML 部分:
- 包含了一个简单的 HTML 页面结构,用于展示 PHP 代码的执行结果。
- 如果没有传递 `id` 参数,则显示 PHP 文件的源代码。
- 最后注释部分写着提示说标志在 `id = 1000`,即 flag 存在于 `id` 为 1000 的文章中。
但是
直接用id=1000,你将获得
前面的判断,真实判断的数值不是id,是id是通过intval函数后得到的,这里我们就有了这些解题思路:
1. 尝试绕过限制: 尝试使用其他的参数或方式来绕过限制,例如可能存在其他的参数或者方法可以绕过对 `id` 参数的限制,从而获取到 `id = 1000` 的结果。
2. 利用错误消息泄露:如果程序存在错误消息泄露,可以尝试通过构造恶意输入来触发错误,从而获取到更多的信息或者利用漏洞。
3. 尝试其他注入点:如果程序还有其他的注入点,可以尝试利用这些注入点来获取标志。例如可能存在其他的参数或者方法可以执行 SQL 注入攻击,从而获取到 `id = 1000` 的结果。
4. 绕过参数限制:如果存在对参数的过滤限制,可以尝试绕过这些限制。例如可能可以通过构造一些特殊的字符或者编码方式来绕过对参数的过滤。
5. 尝试其他攻击方式:如果以上方法都无法获取结果,可以尝试其他的攻击方式。例如可能可以通过 CSRF 攻击、文件包含漏洞、文件上传漏洞等方式来获取到标志。
这里我具体用到的绕过限制:
尝试绕过限制需要进行一些探索和实验。以下是一些可能的方法和技巧,可以尝试绕过对 `id` 参数的限制:
1. 使用其他参数:看看是否有其他参数可以用来获取文章,例如可能存在一个名为 `article_id` 或者 `post_id` 的参数,尝试将这些参数设置为 1000 并查看结果。
http://example.com/article.php?article_id=1000
2. 使用 HTTP 请求方法:尝试使用不同的 HTTP 请求方法,例如 `POST`、`PUT` 或者 `DELETE` 来获取文章。
POST /article.php HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded id=1000
3. 绕过输入过滤:如果程序对 `id` 参数进行了过滤,尝试绕过这些过滤。例如可能可以通过 URL 编码、双重编码、特殊字符等方式来绕过输入过滤。
http://example.com/article.php?id=1000%20OR%201=1
4. 尝试其他编码方式:尝试使用不同的编码方式来绕过限制,例如 Base64 编码、URL 编码等。
http://example.com/article.php?id=MTAwMA%3D%3D
5. 尝试其他查询方式:*尝试使用其他方式来进行查询,例如可能可以通过 `UNION` 查询来获取标志。但请注意,这需要对目标网站的数据库结构有一定的了解。
http://example.com/article.php?id=1 UNION SELECT NULL, 'flag', 'flag' FROM dual WHERE id = 1000
这里我们在网址后面直接加“?id=xx”
随便加入一个小于999的数,99
发现id被限制在1,但是已经绕开了第一层判断
我们写入?id=1看一下
第一步第二部的判断已经完成,发现内容出来了,
现在我们需要的flag,还需要id=1000才能出来,SQL同时查询 99 和 1000 这两个id, 刚才我们试过, id为99时, 没有信息, 那这条SQL查询的结果就只有 id = 1000 的信息, 从而返回flag