web_16

kim23   ·   发表于 2019-11-26 11:18:20   ·   技术文章投稿区

web_16

 

 

标签:CTF | ereg() | isset() | strpos() | 代码审计

提示:分析源码,没什么好提示的


打开网址,发现有查看源码的下载链接。

 

点击链接View Source下载源代码。

 

打开源代码,现已改名为web16_index.phps

 

 

<?php

    $flag = '*********';

    

    if (isset ($_GET['password'])) {

       

        if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)

             echo '<p >You password must be alphanumeric</p>';

        else if (strpos ($_GET['password'], '--') !== FALSE)

            die($flag);

        else

            echo '<p >Invalid password</p>';

    }

?>

 

代码解释

if (isset ($_GET['password'])) {}

isset — 检测变量是否已设置并且非 NULL

如果 传参的值存在并且值不是 NULL 则返回 TRUE,否则返回 FALSE

如果一次传入多个参数,那么 isset() 只有在全部参数都以被设置时返回 TRUE 计算过程从左至右,中途遇到没有设置的变量时就会立即停止。

也就是说GET传参的参数password必须存在且值不能为NULL,只要满足条件就能执行if里边的语句了。

 

if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)

^[a-zA-Z0-9]+$:检测英文和数字

ereg — 正则表达式匹配

语法:ereg ( string $pattern , string $string ) : int

ereg以区分大小写的方式在 string 中寻找与给定的正则表达式 pattern 所匹配的子串。

如果在 string 中找到 pattern 模式的匹配则返回 所匹配字符串的长度,如果没有找到匹配或出错则返回 FALSE

ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false

这句话的意思是传参password必须含义为数字或英文字母,不能含有其他字符。正则进行匹配出现不属于[a-z,A-Z,0-9]范围内的元素就会输出报错文字。

PHP 7+ 版本移除的扩展:ereg | mssql | mysql | sybase_ct

 

else if (strpos ($_GET['password'], '--') !== FALSE) die($flag);

strpos — 查找字符串首次出现的位置

返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。注释: 字符串位置从 0 开始,不是从 1 开始。

也就是说传参的值必须包含字符串"--"

满足两个条件才能获得flag

 因为ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)的关系,传参中不能被检测出来有除了数字英文之外的字符。

 因为else if (strpos ($_GET['password'], '--') !== FALSE) die($flag);的关系,传参必须包含字符串"--"

方法一:%00截断绕过正则匹配

原理是%00截断阻断ereg往后检测,在%00之后的数值函数无法识别。

要求提交的password的值符合正则匹配(一个或多个数字)并且能被strpos找到字符串"--" 

ereg会把null视为字符串的结束,从而被%00截断,而strpos则可以越过%00,所以提交传参为 ?password=123%00--

123:只要是a-zA-Z0-9中的字符就行

%00 %00截断 null

-- strpos 检测是字符串里否有 --

 

Payload?password=123%00--

Flagflag{Ma2be_usIng_rex6exp_a_clevr_moved}

 

 

方法二:利用数组绕过这两个函数

ereg() 只能处理字符串,而password是数组,所以返回的是null,三个等号的时候不会进行类型转换。所以null===falsefalse

strpos() 的参数同样不能够是数组,所以返回的依旧是nullnull!==false也正确。

 

Payload?password[]=1

 

Payload?password[]=*

 

 


打赏我,让我更有动力~

2 Reply   |  Until 2021-8-18 | 953 View

白且
发表于 2021-4-19

还有一种就是还是以数组表达也可以

评论列表

  • 加载数据中...

编写评论内容

zinc
发表于 2021-8-18

这个靶场貌似出了点问题

评论列表

  • 加载数据中...

编写评论内容
LoginCan Publish Content
返回顶部 投诉反馈

© 2016 - 2022 掌控者 All Rights Reserved.