php基础,弱类型和变量覆盖

Php基础
Php基本语法:
https://www.w3school.com.cn/php/php_syntax.asp
php要求
1、文件后缀必须为php
2、文件开头必须是 <?php 文件结束:?>
3、变量的声明必须添加 $
4、每一行代码后都要添加;来结束。

变量的要求
1、变量以 $ 符号开始,后面跟着变量的名称
2、变量名必须以字母或者下划线字符开始
3、变量名只能包含字母数字字符以及下划线(A-z、0-9 和 _ )
4、变量名不能包含空格
5、变量名是区分大小写的($y 和 $Y 是两个不同的变量

超全局变量
https://www.php.net/manual/zh/language.variables.superglobals.php
PHP中预定义了几个超级全局变(superglobals) ,这意味着它们在一个脚本的全部作用域中都可用。 不需要特别说明,就可以在函数及类中使用。PHP 超级全局变量列表:
G L O B A L S 是 P H P 的 一 个 超 级 全 局 变 量 组 , 在 一 个 P H P 脚 本 的 全 部 作 用 域 中 都 可 以 访 问 。 GLOBALS 是PHP的一个超级全局变量组,在一个PHP脚本的全部作用域中都可以访问。 GLOBALSPHPPHP访GLOBALS 是一个包含了全部变量的全局组合数组。变量的名字就是数组的键。
$_SERVER 服务器环境变量数组,由 Web 服务器创建,是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。
$_POST 通过POST方法传递给脚本的变量数组
$_GET 通过GET方法传递给脚本的变量数组
$_COOKIE cookie 变量数组
$_REQUEST所有用户输入的变量数组包含了 G E T , _GET, GET_POST 和 $_COOKIE 所包含的输入内容
$_FILES 与文件上传相关的变量数组
$_ENV 环境变量数组
$_SESSION 会话变量数组
练习:http://123.206.87.240:8004/index1.php
源码:

<?php  
error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){
    $args = $_GET['args'];
    if(!preg_match("/^\w+$/",$args)){
        die("args error!");
    }
    eval("var_dump($$args);");
}
?>
?args=GLOBALS

弱类型
如果一个字符串为 “合法数字+e+合法数字”类型,将会解释为科学计数法的浮点数
如果一个字符串为 “合法数字+ 不可解释为合法数字的字符串”类型,将会被转换为该合法数字的值,后面的字符串将会被丢弃
如果一个字符串为“不可解释为合法数字的字符串+任意”类型,则被转换为0!

1 <?php
2 var_dump("admin"==0);  //true
3 var_dump("1admin"==1); //true
4 var_dump("admin1"==1) //false
5 var_dump("admin1"==0) //true
6 var_dump("0e123456"=="0e4456789"); //true 

MD5 0e开头会被当成0
常见md5 0e开头:
QNKCDZO
240610708
s878926199a
s155964671a
数组无法比较

strcmp()
数组可以绕过,要求较低php版本php -v <5.3

$password="*";
$a = array();
if (strcmp($a, $password) == 0) {
echo "Right!!!login success";
exit();
} else {
echo "Wrong password..";
}

is_array
is_array() 函数用于检测变量是否是一个数组

array_search
下面是官方手册对array_search的介绍,

mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] )

‘ n e e d l e , `needle, needlehaystack必需, s t r i c t 可 选 函 数 判 断 strict可选 函数判断 stricthaystack中的值是存在$needle,存在则返回该值的键值 第三个参数默认为false,如果设置为true则会进行严格过滤, 所以,array_search()在没有选择第三个参数时,是一个弱类型比较, 0==任意字符串
preg_match 和preg_match_all 函数的参数如果是数组的话则返回false,这样就可以绕过正则的过滤。

intval() 函数用于获取变量的整数值。
说明intval()转换的时候,会将从字符串的开始进行转换知道遇到一个非数字的字符。即使出现无法转换的字符串,intval()不会报错而是返回0。
In_array()也存在这样的问题

json绕过
<?php
if (isset($_POST['message'])) {
    $message = json_decode($_POST['message']);
    $key ="*********";
    if ($message->key == $key) {
        echo "flag";
    } 
    else {
        echo "fail";
    }
 }
 else{
     echo "~~~~";
 }
?>

输入一个json类型的字符串,json_decode函数解密成一个数组,判断数组中key的值是否等于 k e y 的 值 , 但 是 key的值,但是 keykey的值我们不知道,但是可以利用0=="admin"这种形式绕过
最终payload message={“key”:0}

switch 和in_array()在判断时使用的是弱比较

ereg(v1,v2)
用指定模式搜索一个字符串中的指定字符串,成功返回ture失败返回false。
可以使用数组

<?php 
highlight_file(__FILE__); 
include('flag.php'); 
if (isset ($_GET['password'])) {     
    if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) !== FALSE) { 
        if (strpos ($_GET['password'], '*-*') !== FALSE) 
            die('Flag: ' . $flag); 
        else 
            echo('*-* have not been found'); 
    } 
}else{ 
    echo 'Invalid password'; 
} 

?>

?password=1%00*-*或者password[]=

is_numeric(mixed $var)
如果var是数字和数字字符串返回true,否则返回flase。
仅用is_numeric判断可能插入16进制的字符串到数据库,可能导致二次注入
(把字符串转换成16进制0x开头的“数” ascii 16进制)

练习:

  <?php
show_source(__FILE__);
$v1=0;$v2=0;$v3=0;
$a=(array)json_decode(@$_GET['foo']);
if(is_array($a)){
    is_numeric(@$a["bar1"])?die("nope"):NULL;
    if(@$a["bar1"]){
        ($a["bar1"]>2016)?$v1=1:NULL;
    }
    if(is_array(@$a["bar2"])){
        if(count($a["bar2"])!==5 OR !is_array($a["bar2"][0])) die("nope");
        $pos = array_search("nudt", $a["bar2"]);
        $pos===false?die("nope"):NULL;
        foreach($a["bar2"] as $key=>$val){
            $val==="nudt"?die("nope"):NULL;
        }
        $v2=1;
    }
}
$c=@$_GET['cat'];
$d=@$_GET['dog'];
if(@$c[1]){
    if(!strcmp($c[1],$d) && $c[1]!==$d){
        eregi("3|1|c",$d.$c[0])?die("nope"):NULL;
        strpos(($c[0].$d), "htctf2016")?$v3=1:NULL;
    }
}
if($v1 && $v2 && $v3){
    include "flag.php";
    echo $flag;
}

变量覆盖
extract() 变量覆盖

<?php
$a=0;
extract($_GET);
if($a==1)
	echo "flag";
else
	echo "no";

?a=1

import_request_variables 变量覆盖

bool import_request_variables (string $types [, string $prefix])

import_request_variables 将 GET、POST、Cookies 中的变量导入到全局,使用这个函数只用简单地指定类型即可。可以用字母’G’、‘P’和’C’分别表示 GET、POST 和 Cookie。这些字母不区分大小写,所以你可以使用’g’、'p’和’c’的任何组合。

<?php
$a=0;
import_request_variables("G");
if($a==1)
	echo "flag";
else
	echo "no";

这里指定G,所以用get传参
?a=1

parse_str() 变量覆盖

void parse_str ( string $str [, array &$arr ])

parse_str() 函数通常用于解析 URL 中的 querystring,但是当参数值可以被用户控制时,很可能导致变量覆盖。
下面是官方文档的内容
Parse_str()
如果 encoded_string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 )。
// 推荐用法

parse_str($str, $output);

//不推荐用法

parse_str($str);

会产生变量覆盖风险

<?php 
highlight_file(__FILE__); 
//var.php?var=new   
$var='init';   
parse_str($_SERVER['QUERY_STRING']);   
print $var; 

?>

preg_match
如果在进行正则表达式匹配的时候,没有限制字符串的开始和结束(^ 和 $),则可以存在绕过的问题

$ip = $_GET['ip']; 

if(!preg_match("/(\d+)\.(\d+)\.(\d+)\.(\d+)/",$ip)) { 
  die('error'); 
} else { 
   echo('key...'); 
}
?ip=1.2.3.4;ls

$$ 和foreach 变量覆盖

<?php
$a=1;
foreach(array('_GET',) as $_request){
	foreach ($$_request as $key => $value) {
		echo $_key.'<br />';
		$$_key=addslashes($_value);
	}
}

经典的变量覆盖代码,这里传入a=2 因为有两个$ 程 序 里 会 执 行 程序里会执行 a=2被覆盖

Metinfo变量覆盖
核心代码有$$ 和foreach变量覆盖漏洞

弱类型和变量覆盖练习:

<?php
function areyouok($greeting){
   return preg_match('/Merry.*Christmas/is',$greeting);
}
 $greeting=@$_POST['greeting'];
if(!areyouok($greeting)){
    if(strpos($greeting,'Merry Christmas')!==false){
        echo 'Merry Christmas. '.'flag{xxxxxx}';
     }else{
         echo 'Do you know .swp file?';
    }
 }else{
    echo 'Do you know PHP?';
}

数组可以绕过,但是我本地测试未成功,不知道是不是版本和环境问题

http://127.0.0.1/second/ketang/8-3/extract.php
<?php 
highlight_file(__FILE__); 
$filename = 'flag.php'; 
extract($_GET); 
if(isset($attempt)){ 
    $combination = trim(file_get_contents($filename)); 
    var_dump($attempt); 
    var_dump($combination); 
    if($attempt===$combination){ 
        echo "<p>How did you know the secret combination was"."$combination !?</p>"; 
        $next = file_get_contents('flag.php'); 
        echo "<p>You've earned the password:".$next."</p>"; 
    }else{ 
        echo "<p>Incorrect! The secret combination is not $attempt</p>"; 
    } 

} 

?>

?filename=&attempt=
右键查看源代码获得flag

ISCC web4

<?php 
error_reporting(0); 
include("flag.php"); 
$hashed_key = 'ddbafb4eb89e218701472d3f6c087fdf7119dfdd560f9d1fcbe7482b0feea05a'; 
$parsed = parse_url($_SERVER['REQUEST_URI']); 
if(isset($parsed["query"])){ 
    $query = $parsed["query"]; 
    $parsed_query = parse_str($query); 
    if($parsed_query!=NULL){ 
        $action = $parsed_query['action']; 
    } 

    if($action==="auth"){ 
        $key = $_GET["key"]; 
        $hashed_input = hash('sha256', $key); 
        if($hashed_input!==$hashed_key){ 
            die("<img src='cxk.jpg'>"); 
        } 

        echo $flag; 
    } 
}else{ 
    show_source(__FILE__); 
}?>
相关推荐
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页