CTFShow:萌新web1

首先给出参考大佬的博客链接:

ctfshow-萌新-web1( 利用intval函数的特性获取敏感数据)_ctfshow萌新web_士别三日wyx的博客-CSDN博客

第一次做web1题目,刚开始一脸懵逼,看了大佬的一些博客,才做出来,心里非常激动!记录一下,先直接给出结果:

 题目源代码:

<html>
<head>
    <title>ctf.show萌新计划web1</title>
    <meta charset="utf-8">
</head>
<body>
<?php
# 包含数据库连接文件
include("config.php");
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
    $id = $_GET['id'];
    # 判断id的值是否大于999
    if(intval($id) > 999){
        # id 大于 999 直接退出并返回错误
        die("id error");
    }else{
        # id 小于 999 拼接sql语句
        $sql = "select * from article where id = $id order by id limit 1 ";
        echo "执行的sql为:$sql<br>";
        # 执行sql 语句
        $result = $conn->query($sql);
        # 判断有没有查询结果
        if ($result->num_rows > 0) {
            # 如果有结果,获取结果对象的值$row
            while($row = $result->fetch_assoc()) {
                echo "id: " . $row["id"]. " - title: " . $row["title"]. " <br><hr>" . $row["content"]. "<br>";
            }
        }
        # 关闭数据库连接
        $conn->close();
    }
    
}else{
    highlight_file(__FILE__);
}

?>
</body>
<!-- flag in id = 1000 -->
</html>

最后一行可以看出我们想要的flag就是id=1000,因此我们需要让参数id通过此题的过滤(if条件判断之类的,就好比与筛选),最终结果可以为1000 

解题前应该做的web基础知识准备工作:

  1. 了解基本的Web安全知识,如HTTP协议、请求和响应、Cookie、Session、HTML、JavaScript等。

  2. 探索Web应用程序的不同功能。输入一些测试数据并观察输出。使用浏览器的开发者工具查看网络请求、响应和Cookies。

  3. 尝试在输入中注入一些特殊字符,如单引号、双引号、反斜杠、尖括号等,并观察是否有任何异常输出。此外,尝试使用常见的Web攻击向量,如SQL注入、XSS、CSRF等。

  4. 查看页面源代码和注释,寻找潜在的漏洞和安全隐患。有时,关键信息可能隐藏在HTML注释中。

  5. 尝试更改URL参数值,了解应用程序如何处理输入。(此题用到)

  6. 查看任何隐藏的文件或目录,以查找潜在的漏洞。有时开发人员会留下一些备份文件或测试文件。

  7. 研究应用程序使用的框架和库。了解框架的工作原理和安全性能,并了解其缺陷和漏洞。

具体解题思路:

第一个过滤:

 判断提交的参数id是否存在,这必然是存在的,不然也不会得到最后的id=1000。

第二个过滤:

若intval($id)的值大于999,则直接退出并返回错误

否则执行sql查询语句

第三个过滤:

若执行的sql语句在数据库中查询不到,则啥也不做,无返回数据

否则返回结果对象的值$row 

判断id的值是否大于999,我们知道id=1000,而若参数id的值就是1000的话就会进入die语句结束程序,所以我们需要1000,但不能只光是1000。通过条件判断的表达式中我们可以看到有个intval函数,这时我们需要了解intval函数才能做出来。

intval()函数

intval() 是 PHP 中的一个内置函数,主要用于将字符串或浮点数转换成整数。

需要注意的是,当 传入的参数为字符串时,如果字符串中包含非数字字符,则只有第一个数字字符及其后的字符将被转换为整数。例如,"123abc1" 转换为整数后为 123。如果字符串以非数字字符开头,则返回 0。 

因此,参数id的值可以为一个字符串,该字符串大致结构可以为“ 数字 + 字符串 + 数字 ”,而前面的数字可以为小于1000的数,用来绕过intval(&id)>999;而后面的数字可以为1000,让此字符串id能够取到1000

因此我们可以推出id的可能表达式:

1 || 1000

所以我们传入参数id=1 || 1000试试:

 回车,结果为:

 执行的sql为:select * from article where id = 1 order by id limit 1
id: 1 - title: this is title


this is content

返回了数据库中存在的id=1的信息,而不是id=1000(逻辑或id=1为真)

所以我们换一个id的表达式:

2 || 1000

 重新传入,得到结果:

执行的sql为:select * from article where id = 2 || id=1000 order by id limit 1
id: 1000 - title: CTFshowflag

ctfshow{6bae37a5-90d2-43cb-85e0-60ab0da68e53}


返回了id=1000的信息,即我们想要的flag!!! 

最后,我们可以试验一下

如果直接传入id=1000,会得到什么返回结果:

与我们料想的一致(没有通过第二个过滤(intval(&id)>999)) 。

如果传入id=1,会返回id=1的信息:

如果传入id=2,会返回id=2的信息,但在数据库中没有id=2的信息,则为空:

 

猜你喜欢

转载自blog.csdn.net/weixin_64089259/article/details/130144716