前置知识
include:包含一个文件,也可以包含一些其他东西,后续用到再解析
substr:对字符串进行切片,第一个参数是字符串,第二第三个参数出从第a个索引开始切n个,索引从0开始计数。
例如:$a = substr("012345", 2, 3);
⇒ $a === '234'
intval:其他类型转换为int类型,不可用于array和object。第一个参数是需要转换的值,第二个可选参数可以制定进制,默认是十进制。
例如:intval(“a”) ==> 0,intval(“123a”) ⇒ 123,后续的非数字将被截断,Intval与 ==
搭配可能会出现漏洞,后续用到再说。
信息收集
if(substr($token, 1,1)===substr($token, 14,1) && substr($token, 14,1) ===substr($token, 17,1)){if((intval(substr($token, 1,1))+intval(substr($token, 14,1))+substr($token, 17,1))/substr($token, 1,1)===intval(substr($token, 31,1))){echo $flag;}}
关键在于这里,只要按照它的要求跑出这个token即可。所以我们自己构造代码,随机生成md5,检查md5是否满足要求,若满足要求,输出md5对应的字符串。
解题:
为什么是自己跑md5,而不是爆破网站,因为在现实情况下,频繁访问网站可能会被ban掉IP。还有一个原因是,爆破网站比本地爆破慢太多了
我只会python,所以用python写的,如果用php可以直接抄写它的判断语句,不用翻译
import itertools
import hashlib
import string
def md5(s):if type(s) != bytes:s = bytes(s, encoding="utf-8")hash_md5 = hashlib.md5()hash_md5.update(s)return hash_md5.hexdigest()def web23():dir = string.digits + string.ascii_uppercase + string.ascii_lowercase# 这里我不知道多少位能满足需求,所以写成变量,如果1-3位跑不出来,我可以跑更多位的for i in range(1, 4):for comb in itertools.combinations_with_replacement(dir, i):str_comb = "".join(comb)v_md5 = md5(str_comb)if v_md5[1] == v_md5[14] == v_md5[17]:try: # 除零异常,字符串无法转int异常,我懒得处理了,统统忽略就行了if ((int(v_md5[1])+int(v_md5[14])+int(v_md5[17]))/int(v_md5[1])==int(v_md5[31])):print(str_comb)print(v_md5[1], v_md5[14], v_md5[17])except:passif __name__ == '__main__':web23()
跑出来这些结果
3j
6Vh
AKh
JKh
Jik
SVi
UYg
ejt
输入url/?token=3j
拿到flag
web22题目已弃用
web21 目录 web24