240610708 的md5值为?0e462097431906509019562988736854
QNKCDZO 的md5值为?0e830400451993494058024219903391
为什么两者的md5后是一样的?
因为php规定在进行字符串与字符串比较时,“0e”判断为科学计数法,又因为0的多少次方都为0所以两者会相等。
"0e123456"=="0e345" //True
但是以下为False
"0e12adfc"=="0e345" //False
原因在于0e后面不能含有字母!!!否则判断为False
扩展:在php中进行字符串与int进行比较时:
1.md5($a)==md5($b) & $a != $b
(两个不同字符,md5加密后一样)
eg:
MMHUWUV 0e701732711630150438129209816536
MAUXXQC 0e478478466848439040434801845361
IHKFRNS 0e256160682445802696926137988570
GZECLQZ 0e537612333747236407713628225676
GGHMVOE 0e362766013028313274586933780773
GEGHBXL 0e248776895502908863709684713578
EEIZDOI 0e782601363539291779881938479162
DYAXWCA 0e424759758842488633464374063001
2.$a==md5($a)
(字符的md5加密后与本身一样。满足$a是0e开头,且加密后也是0e开头)
eg:
0e215962017 0e291242476940776845150308577824
0e1284838308 0e708279691820928818722257405159
0e1137126905 0e291659922323405260514745084877
0e807097110 0e318093639164485566453180786895
0e730083352 0e870635875304277170259950255928
1.md5($a)===md5($b) & $a != $b
(===
?是 PHP 中的严格相等运算符,用于比较两个值是否相等且数据类型也相同。)
因为PHP对无法md5加密的东西不加密,结果为NULL,虽然会报错,但是null=null,逻辑关系为True。所以可以输出flag
eg:
md5_1[]=1&md5_2[]=2
eg2:
两串不一样的字符,加密结果却相同
$a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2
$b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2
?题目要求:传入参数a,使得加密后的$a必须是123开头并且后面为字母的字符串。
为了满足$a==123(字符串与int比较)
脚本:
import multiprocessing
import hashlib
import random
import string
import sys
?
CHARS = string.ascii_letters + string.digits
?
?
def cmp_md5(substr, stop_event, str_len, start=0, size=20):
? ? global CHARS
? ? while not stop_event.is_set():
? ? ? ? rnds = ''.join(random.choice(CHARS) for _ in range(size))
? ? ? ? md5 = hashlib.md5(rnds.encode())
? ? ? ? value = md5.hexdigest()
? ? ? ? if value[start: start + str_len] == substr:
? ? ? ? ? ? print(rnds)
? ? ? ? ? ? print(value)
? ? ? ? ? ? stop_event.set()
?
?
if __name__ == '__main__':
? ? substr = sys.argv[1].strip()
? ? start_pos = int(sys.argv[2]) if len(sys.argv) > 2 else 0
? ? str_len = len(substr)
? ? cpus = multiprocessing.cpu_count()
? ? stop_event = multiprocessing.Event()
? ? processes = [multiprocessing.Process(target=cmp_md5, args=(substr,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?stop_event, str_len, start_pos))
? ? ? ? ? ? ? ? ?for i in range(cpus)]
? ? for p in processes:
? ? ? ? p.start()
? ? for p in processes:
? ? ? ? p.join()
python md5.py "123" 0
"123" =>要跑的字符
0 =>要跑的字符的起始位置
第一列:为传入参数a
第二列:为a加密后的$a 满足条件
1.查看题目,解读if函数。
通过$_GET获取v1和v2参数。
isset()用于检查变量是否已设置且非空。
ctype_alpha()函数用来检查v1是否为纯字母字符串,如果假则输出"v1 error"
is_numeric()函数用来检查v2是否纯数字,如果假则输出"v2 error"
最后比较md5(v1)与md5(v2)是否相等,相等输出flag值
2.了解完if规则后,可以查询md5碰撞,可知md5('240610708') ==md5('QNKCDZO')尝试一下成功获取flag。