ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ctfshow web由一道题的思路实现通杀

2022-02-21 10:30:01  阅读:298  来源: 互联网

标签:web 0000 intval 通杀 1111 ctfshow 题目 id 1000


ctfshow萌新计划

根据web1的几个解法思路我实现了对后面几道题的通杀,仔细想想感觉对于我这样的新手来说这几题还不错

题目一: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>

大部分地方题目都有注释,所以我们来了解一些函数作用

1.isset()函数:根据题目注释我们大概可以知道isset函数就是检测用来检测变量是否存在

2.intval():这里实际上就用到了intval函数的特性

我们写如下这样一段代码

<?php
	$id=$_GET['id']; //定义一个GET传参的变量
	var_dump($id);   //使用var_dump函数输出这个变量长什么样
	echo "<br />";   //换行,方便区分
	var_dump(intval($id));  //用var_dump函数输出经过intval函数处理以后的变量长什么样
?>

我们传参?id=1000,输出结果如下:

 我们再传参?id='1000',输出结果如下:

可以看到:

$id=$_GET['id'] 

我们传参'1000'给变量id,直接输出的还是'1000';

但是:

var_dump=intval($id)

可以发现经过intval函数处理后输出的就是int(0)

我把代码更改一下
 

<?php
	$id=$_GET['id'];
	var_dump($id);
	echo "<br />";
	var_dump(intval($id));
	if(intval($id)>999)
	{
		echo "true";
	}
	else 
	{
		echo "false";
	}
	
?>

拓展:这个地方我拓展一下知识

intval函数处理的时候,如果

1.传参里面有字符的时候,函数会直接返回0

2.当传参里面前面是字符后面是数字,返回的也是0,例如:abc123

3.当传参前面是数字后面是字符的时候,返回前面的数字而后面的字符置0

 

 解法一:根据这个特性再加上题目的提示 flag in id = 1000

我们尝试构造payload:

?id='1000'

顺利得到flag:

ctfshow{85577894-0cb1-4d0d-9fa2-f7f1b03d77c2}

 如果这里我们直接使用?id=1000的话,那么

根据题目的这句话就会直接返回错误

 解法二: 既然题目已经出现了回显,那么根据回显提示我们是否可以尝试使用SQL注入来找到flag呢?

那我们尝试构造:

?id=100 or id=1000

返回后我们发现这样也可以获得flag,这是因为,我们输入id=100 or id=1000的时候,if语句中首先是100和999进行比较,然后查询id=1000里面的东西,实现了绕过

解法三:  搜索了一些大佬的文章,我发现还有一种构造方法,那么就顺便学习一下:

我们可以构造取反:

?id=~~1000

我来讲讲原理:

假设我们拿10来举例:

10的二进制表示是:1010

化成32位二进制就是:0000 0000 0000 0000 0000 0000 0000 1010

按位取反就是:           1111 1111 1111 1111 1111 1111 1111 0101

然后我们知道第一位的0/1表示的是正负,所以有:

 -111 1111 1111 1111 1111 1111 1111 0101

负数是用补码表示的,然后补码是原码取反加1,所以我们把补码减1再取反

-111 1111 1111 1111 1111 1111 1111 0100

-000 0000 0000 0000 0000 0000 0000 1011

计算得到:-11

这个地方我们要取反两次,因为最后要查询的数据是1000里面的数,所以经过两次取反后还是1000,但是这样做可以绕过前面的限制

解法四:

我们还可以构造payload:

?id=100%2B900

我们知道数据库是可以做计算的,所以我们构造100+900,但是要注意不能直接注入+号,因为在url里面+号会直接被PHP解析成空格

题目二:web2 

第二题和第一题还是一样,不同的地方在于加了一个正则过滤

    if(preg_match("/or|\+/i",$id)){
            die("id error");
    }

 这个正则表达式过滤了or 和 + ;后面的符号i标记这是一个大小写不敏感的搜索

有不理解的小伙伴建议可以看看正则表达式的知识

正则表达式 – 匹配规则 | 菜鸟教程

这么一看上面的第二种解法就不能用了,但是其他解法照用不误,只要不出现被过滤的关键字就可以,而且上面的第四种解法我们把+号改成*号照样可以绕过

构造payload:

?id='1000'

 

题目三:web 3

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

好家伙,这次过滤的更多,实际上这里过滤掉了or 和+ - * / !,但是,我们构造payload:

?id='1000'

照样可以使用

 

题目四:web4

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

这次又过滤了更多,但是不影响payload:

?id='1000'

 

题目五:web5

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

这一次终于把' "过滤了,那么我们试试取反:

?id=~~1000

 

成功绕过

题目六:web6

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

 构造payload:

?id=~~1000

 

题目七:web7

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

哦豁,我们发现这里把~符号过滤了,看来只能想其他方法了,思考了一下,根据前面我们使用二进制取反实现绕过,那么我们能不能直接使用二进制表示1000从而实现绕过呢?

构造payload:

?id=1111101000

发现不行,想了一下,加上标识符:

?id=0b1111101000

 

 绕过成功

有兴趣的小伙伴可以看看这篇文章

CTFSHOW 萌新计划 web 1-8_羽的博客-CSDN博客_ctfshow萌新web

标签:web,0000,intval,通杀,1111,ctfshow,题目,id,1000
来源: https://blog.csdn.net/weixin_52555162/article/details/123039563

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有