MD5绕过

法1:数组绕过

1
2
3
4
5
6
7
8
9
常见过滤函数如下:

ctype_alnum ( string $text ) : bool
// 如果text中所有的字符全部是字母和(或者)数字,返回 TRUE 否则返回FALSE

is_numeric ( mixed $var ) : bool
// 如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE


用数组进行绕过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
highlight_file(__FILE__);
error_reporting(0);
$flag = "flag{H3rmesk1t_is_a_loser}";
$val1 = $_GET['val1'];
$val2 = $_GET['val2'];
if (isset($_GET['val1']) and isset($_GET['val2']))
{
if ($_GET['val1'] != $_GET['val2'])
{
if ((md5($_GET['val1']) == md5($_GET['val2'])))
echo $flag;
else
echo "you can't get flag";
}
}
?>
1
这里使用val1[]=1&val2[]=2进行绕过

法2:科学计数法绕过

1
2
3
4
5
6
7
8
9
10
11
<?php
for($a=1;$a<=1000000000;$a++){
$md5 = md5($a);
if(preg_match('/^0e\d+$/',$md5)){
echo $a;
echo "\n";
echo $md5;
echo "\n";
}
}

常见的字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
byGcY
0e591948146966052067035298880982

QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020

s155964671a
0e342768416822451524974117254469

s214587387a
0e848240448830537924465865611904

s214587387a
0e848240448830537924465865611904

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s1885207154a
0e509367213418206700842008763514

240610708
0e462097431906509019562988736854

314282422
0e990995504821699494520356953734

571579406
0e972379832854295224118025748221

903251147
0e174510503823932942361353209384

1
使用val1[]=314282422&val2[]=571579406

MD5强类型比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
highlight_file(__FILE__);
error_reporting(0);
$flag = "flag{H3rmesk1t_is_a_loser}";
$val1 = $_GET['val1'];
$val2 = $_GET['val2'];
if (isset($_GET['val1']) and isset($_GET['val2']))
{
if ($_GET['val1'] != $_GET['val2'])
{
if ((md5($_GET['val1']) === md5($_GET['val2'])))
echo $flag;
else
echo "you can't get flag";
}
}
?>

法1:数组绕过

1
2
因为是强类型比较,用0e开头的字符串是没办法绕过的了,但是PHP自身的特性使得可以提交一个数组
而md5函数传入数组的返回值都是NULL,这样就可以绕过强类型比较了
1
还是使用val1[]=1&val2[]=2来进行数组绕过

法2:使用MD5加密后完全相等的两个字符串绕过

利用fastcoll_v1.0.0.5.exe来生成符合条件的字符串
构造:

  1. 创建一个文本文件,写入任意的文件内容,命名为ywj.txt (源文件)
  2. 运行fastcoll输出以下参数:-p 是源文件,-o是输出文件
    执行命令:
    1
    fastcoll_v1.0.0.5.exe -p ywj.txt -o 1.txt 2.txt
    对产生的1.txt和2.txt文件进行测试
1
2
3
4
5
6
7
8
9
10
11
12
<?php 
function readmyfile($path){
$fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
fclose($fh);
return $data;
}
echo '二进制md5加密 '. md5( (readmyfile("D:\\ctf工具\\fastcoll_v1.0.0.5.exe\\1.txt")))."\n";
echo 'url编码 '. urlencode(readmyfile("D:\\ctf工具\\fastcoll_v1.0.0.5.exe\\1.txt"))."\n";
echo '二进制md5加密 '.md5( (readmyfile("D:\\ctf工具\\fastcoll_v1.0.0.5.exe\\2.txt")))."\n";
echo 'url编码 '. urlencode(readmyfile("D:\\ctf工具\\fastcoll_v1.0.0.5.exe\\2.txt"))."\n";

1
2
3
4
5
二进制md5加密 ecd33e3e09ff2a58e1d9ed7189dc186b
url编码 abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%AC%F8%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45j%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3Xg%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%3F%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2AO%DFF%2A%F3%8BcH%FF%85%3F%0D%D0%9B%C7%C8-%12%92
二进制md5加密 ecd33e3e09ff2a58e1d9ed7189dc186b
url编码 abc%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%D6%16y%AC%CE%C5%A1LrY5fn%94%10%D9%01%C3%ACx%AAN%21%D0%27%BE%3Ej%A7%22%0C%D08%D3%AF%DFRo%2F%A4%8B%E8%EB45%EA%E4h%9C%21%22%AB%7E%BC%8E%7C%17%9E%C3%D8g%D7%A8%CDHt%BE%AB.%2FWb%3Eb%EA%FC%261%0F_%3D%AFo%BF%1E%DE%E8i%86%7D%BF%C7_Q%CDA%B4%CF%B8n%06Ir%7F%5C%A3k%F9%2A%CF%DEF%2A%F3%8BcH%FF%85%3F%0D%D0%9BG%C8-%12%92

以0x开头的字符串,并且md5加密后也以0x开头的字符串

1
0e215962017

MD5弱类型比较

1.md5($a) == md5($b) & $a != $b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
include "flag.php";
$md5_1=$_GET['md5_1'];
$md5_2=$_GET['md5_2'];
if(md5($md5_1)==md5($md5_2) & $md5_1 != $md5_2)
{
echo $flag;
}
else
{
echo "try harder";
}
?>
```~

**需要找到两个不同的字符,md5加密之后都是0e3242342的形式**

MMHUWUV 0e701732711630150438129209816536

MAUXXQC 0e478478466848439040434801845361

IHKFRNS 0e256160682445802696926137988570

GZECLQZ 0e537612333747236407713628225676

GGHMVOE 0e362766013028313274586933780773

GEGHBXL 0e248776895502908863709684713578

EEIZDOI 0e782601363539291779881938479162

DYAXWCA 0e424759758842488633464374063001
------------------------------------------------

### 2.$a==md5($a)

**这一类题目要求满足$a是0e开头,且加密后也是0e开头**

0e215962017 0e291242476940776845150308577824

0e1284838308 0e708279691820928818722257405159

0e1137126905 0e291659922323405260514745084877

0e807097110 0e318093639164485566453180786895

0e730083352 0e870635875304277170259950255928

# 正则达式绕过:

```php
if (preg_match('/[oc]:\d+:/i', $var))
如果要绕过这个函数:
只需要在类的名字长度前加一个+即可。

intval()函数漏洞绕过

intval()函数可以获取变量的[整数值]。常用于强制类型转换。

语法:

1
int intval($var,$base)

参数:

  • $var:需要转换成integer的[变量]
  • $base:转换所使用的[进制]

一.进制自动转换

  • 如果 $var 以 0 开头,就使用 8进制
  • 如果 $var 以0x开头,就使用 16进制
  • 否则,就使用 10进制
1
2
3
4
5
6
# 10的 8进制是12
var_dump(intval(012));
# 10的 16进制是A
var_dump(intval(0xA));
# 10的 10进制是10
var_dump(intval(10));

输出

1
2
3
int(10)
int(10)
int(10)

二.转换数组

intval() 转换数组类型时,不关心数组中的内容,只判断数组中有没有元素。

  • 「空数组」返回 0
  • 「非空数组」返回 1

示例:

1
2
var_dump(intval(array()));
var_dump(intval(array(3,2)));

输出:

1
2
int(0)
int(1)

三、转换字符串

intval() 转换字符串类型时,会判断字符串是否以数字开头

  • 如果以数字开头,就返回1个或多个连续的数字
  • 如果以字母开头,就返回0

实例:

1
2
3
4
5
6
var_dump(intval('12abc'));
var_dump(intval("12abc"));
var_dump(intval('abc123'));
var_dump(intval('1a2b3c'));
var_dump(intval('0101'));
var_dump(intval("0x2b"));

输出:

1
2
3
4
5
6
int(12)
int(12)
int(0)
int(1)
int(101)
int(0)

四,intval()绕过思路

1)当某个数字被过滤时,可以使用它的 8进制/16进制来绕过;比如过滤10,就用012(八进制)或0xA(十六进制)。
2)对于弱比较(a==b),可以给a、b两个参数传入空数组,使弱比较为true。
3)当某个数字被过滤时,可以给它增加小数位来绕过;比如过滤3,就用3.1。
4)当某个数字被过滤时,可以给它拼接字符串来绕过;比如过滤3,就用3ab。(GET请求的参数会自动拼接单引号)
5)当某个数字被过滤时,可以两次取反来绕过;比如过滤10,就用~~10。
6)当某个数字被过滤时,可以使用算数运算符绕过;比如过滤10,就用 5+5 或 2*5。

php弱类型比较及其绕过

php中的弱类型比较

php是一种弱类型语言,对数据的类型要求并不严格,可以让数据类型互相转换

强类型与弱类型

强类型

所谓强类型(Strongly typed),顾名思义就是强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型。J

•ava、.NET、C++等都是强类型语言,在变量使用之前必须声明变量的类型和名称;且不经强制转换不允许两种不同类型的变量互相操作。

弱类型

•对数据的类型要求并不严格,可以让数据类型互相转换。

PHP转换规则

字符串和数字比较使用==时,字符串会先转换为数字类型再比较,若字符串以数字开头,则取开头数字作为转换结果,不能转换为数字的字符串(例如”aaa”是不能转换为数字的字符串,而”123”或”123aa”就是可以转换为数字的字符串)或null,则转换为0;例如

1
2
var_dump(12=="12")                         //true var_dump(12=="12aa")                       //true var_dump( "admin"==0)		   		    //true
var_dump(false==""==0==NULL) //true
1.布尔型和任意比较

布尔值true和任意字符串都弱相等,除了0和false,因为0也认为是bool false,true是不等于false的,例如:

1
2
3
4
var_dump(true=="hyuf")                   //true
var_dump(True == 0); //bool(false)
var_dump(True == 'False'); //bool(true)
var_dump(True == 2); //bool(true)