PHP代码安全杂谈1

一、精度绕过缺陷

php通常采用的是 IEEE 754 双精度格式,则由于取整而导致的最大相对误差为 1.11e-16。所以,可能会造成一些不必要的麻烦:

image.png

以十进制能够精确表示的有理数如 0.10.7,无论有多少尾数都不能被内部所使用的二进制精确表示,因此不能在不丢失一点点精度的情况下转换为二进制的格式。这就会造成混乱的结果:例如,floor((0.1+0.7)*10) 通常会返回 7 而不是预期中的8,因为该结果内部的表示其实是类似 7.9999999999999991118…


二、类型转换的缺陷

理论

PHP提供了is_numeric函数,用来变量判断是否为数字。PHP弱类型语言的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型intval数字化再比。

案例代码

<?php

error_reporting(0);

$flag = 'flag{1S_numer1c_Not_S4fe}';

id =_GET['id']; is_numeric($id)?die("Sorry...."):NULL;

if(id>665){ echoflag; }

?>

write-up

首先对GET传入的id进行检测。通过is_numeric函数进行检测,如果是数字就GG,如果不是数字就与655比较,大于655输出正确答案。看起来似乎很矛盾,这里又要用到php作为弱类型语言的一个特征:当一个整形和一个其他类型行比较的时候,会先把其他类型intval数字化再比。也就是说将id构造成数字+字符形式就能成功得到flag,如:id=666gg


三、松散比较符的缺陷

理论

php比较相等性的运算符有两种,一种是严格比较,另一种是松散比较。

如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行


image.png

严格比较符,会先判断两种字符串的类型是否相等,再比较。

松散比较符,会先将字符串类型转换成相同,再比较。

一个简单的例子

image.png

另一个例子

image.png
var_dump(0=="gg"); //true
var_dump(0==="gg"); //false
var_dump(1=="gg"); //false

0gg进行松散性质的不严格比较,会将gg转换为数值,强制转换,由于gg是字符串,转化的结果是0,所以 输出 true

0gg进行严格 性质的严格比较,这里的gg是字符串类型,和int类型的0不相等,所以输出 false

0gg进行松散性质的不严格比较,会将gg转换为数值,强制转换,由于gg是字符串,转化的结果是0,不等于1,所以输出 false

var_dump(1=="1gg"); //true 
var_dump(1=="gg1"); //false

11gg进行松散性质的不严格比较,这里1gg被强制转换为int类型的时候会从字符串的第一位开始做判断进行转换,这里的1gg第一位是1,所以这里1gg被转换为1,所以输出 true

1gg1进行严格 性质的严格比较,字符串gg1的第一位不是数字,所以它被强制转换为0,所以输出 false

var_dump("0e123" == "0e456");  //true
var_dump("0e123" == "0eabc");  //flase

这里比较特殊,字符串中出现了0e,PHP手册介绍如下:

当一个字符串欸当作一个数值来取值,其结果和类型如下:如果该字符串没有包含'.','e','E'并且其数值值在整形的范围之内 
该字符串被当作int来取值,其他所有情况下都被作为float来取值,
该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0。

0e1230e456相互不严格性质比较的时候,会将0e这类字符串识为科学技术法的数字,0的无论多少次方都是零,所以相等,输出 true

0e1230eabc相互进行不严格性质比较的时候,本应该将0e这类字符串识为科学技术法的数字,但是这里的0e后面跟着的是abc,数学中科学计数的指数不可以包含字母。所以这里字符串中虽然是0e开头,但是后面的abc却不符合科学技法的规范,所以输出是 false

四、sha1() md5()加密函数漏洞缺陷

理论

md5()sha1()对一个数组进行加密将返回 NULL

一个小例子

if ($_GET['name'] == $_GET['password'])
    print 'Your password can not be your name.';
else if (sha1($_GET['name']) === sha1($_GET['password']))
    die('Flag: '.$flag);

GET类型提交了两个字段namepassword,获得flag要求的条件是:

name != password

sha1(name) == sha1(password)

这个乍看起来这是不可能的,但是这里利用sha1()函数在处理数组的时候由于无法处理将返回NULL可以绕过if语句的验证,if条件成立将获得flag。 构造语句如下:

?name[]=a&password[]=b

这里符合了2个拿到flag的条件:

a不等于b

name和password由于是数组,经过sha1()函数嫁给后都返回NULL

五、字符串处理函数漏洞缺陷

理论

strcmp()函数:比较两个字符串(区分大小写).

具体的用法解释如下:

参数 `str1`第一个字符串。
参数 `str2`第二个字符串。
如果 `str1` 小于 `str2` 返回 `< 0`;
如果 `str1` 大于 `str2` 返回 `> 0`;
如果两者相等,返回 0。

这个函数接受到了不符合的类型,例如数组类型,函数将发生错误。但是在5.3之前的php中,显示了报错的警告信息后,将return 0 !!!! 也就是虽然报了错,但却判定其相等了。

  • ereg()函数:字符串正则匹配。
  • strpos()函数:查找字符串在另一字符串中第一次出现的位置,对大小写敏感。

这2个函数都是用来处理字符串的,但是在传入数组参数后都将返回NULL

六、parse_str函数变量覆盖缺陷

理论

parse_str函数的作用就是解析字符串并注册成变量,在注册变量之前不会验证当前变量是否存在,所以直接覆盖掉已有变量。

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

str 输入的字符串。
arr 如果设置了第二个变量 arr,变量将会以数组元素的形式存入到这个数组,作为替代。

实践

测试代码:

<?php
error_reporting(0);
$flag = 'flag{V4ri4ble_M4y_Be_C0verEd}';
if (empty($_GET['b'])) {
    show_source(__FILE__);
    die();
}else{
    $a = "www.windbsy.cn";
    $b = $_GET['b'];
    @parse_str($b);
    if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO')) {
        echo $flag;
    }else{
        exit('your answer is wrong~');
    }
}
?>

考察点

  • parse_str变量覆盖缺陷

write-up

找到核心代码:

@parse_str($b);
这里使用了parse_str函数来传递b的变量值
if ($a[0] != 'QNKCDZO' && md5($a[0]) == md5('QNKCDZO'))
这里用到的是文章上面的知识点md5()函数缺陷

因为这里用到了parse_str函数来传递b,if的语句的条件是拿$a[0]来比较的,有因为这里的变量a的值已经三是固定的了:

$a = "www.windbsy.cn";

这里其实是我博客的地址~~ 整体代码乍看起来又不可能,但是利用变量覆盖函数的缺陷这里可以对a的变量进行重新赋值,后面的的if语句再利用本文前面提到的md5()比较缺陷进行绕过:

http://localhost/?b=a[0]=240610708

image.png

参考文献

PHP代码安全杂谈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,776评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,527评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,361评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,430评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,511评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,544评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,561评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,315评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,763评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,070评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,235评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,911评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,554评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,173评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,424评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,106评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,103评论 2 352

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,145评论 0 13
  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,781评论 0 38
  • 大概,时间久了,就长肉里面了,最后拔出来也是伤筋动骨,哪怕是最快的刀也剔不净啊,那怎么办,老人的话是可以偷来的,不...
    向杨春泥阅读 165评论 0 2
  • 周六 起床吃饭,然后开始对暖小姐的拉练计划开始。对于她的晚睡,实在是太崩溃。 从家里出发,事先商量好我们去宝龙,但...
    小猪天堂阅读 479评论 4 1