攻防世界-web02
- 题目:
小周
将他小时候最心爱的玩具锁在了密码箱
里,但由于时间久远,密码
忘记了一部分,你能帮帮他吗? - 靶机:
http://47.94.14.162:10008/?password=ISCC%7B4%7D&password2=5
分析
F12
查看源码看到style="display:none"
,去掉display:none
可以看到密码箱
信息
根据题目提示但由于时间久远,
密码忘记了一部分
,猜测(wen da lao)
密码可能为4
、5
, 点击
解锁`页面跳转到下一级
有一个弹框阻扰
我们分析代码
,F12
可以看到隐藏掉弹框即可,这里password
会有一个base64
字符串是显示这个图片的,这个弹框是LastPass
的图片,不需要关注
找到div
,输入style="display:none"
,去掉弹框
代码审计
可以看到<?php
里面 包含具体加密逻辑
计算给定字符串的哈希码
计算给定字符串的哈希码 -l
# 计算给定字符串的哈希码
def MyHashCode(str):
h = 0
length = len(str)
for i in range(length):
hash = int40(int40(40 * hash) + ord(str[i]))
return abs(hash)
将一个整数转换为40位的二进制补码表示
计算给定字符串的哈希码 -l
def int40(code):
# 将一个32位整数转换为40位的二进制补码表示
flag = code >> 32
# 如果该整数的最高位为1,则表示该整数是负数
if flag == 1:
# 需要先对其进行一次按位取反操作,再加1得到其二进制补码表示,最后再乘以-1得到其负值
code = ~ (code - 1)
return code * -1
else:
return code
检测字符串是否包含 ISCC,包含直接false
- 解题格式一般为 ISCC{FLAG}
def Checked(str):
p1 = 'ISCC'
if p1 in str:
return False
return True
对数据进行加密处理
对数据进行加密处理 -l
def SecurityCheck(sha1, sha2, user):
if Checked(sha1) and Checked(sha2): # 检测是否包含 ISCC,如果包含就返回 wrong
sha1 = sha1.upper() # 转为大写
sha2 = sha2.lower() # 转为小写
user = user.upper() # user 转为大写字母
crypto = MyHashCode(sha1) ^ MyHashCode(sha2)
# 计算sha1和sha2的哈希值,并将它们异或起来得到crypto
else:
print("wrong")
# 如果其中一个checked 函数返回false 则打印字符串 “wrong” 并返回none。
return None
return [crypto, user]
# 返回一个包含 crypto 和 user的列表
关键逻辑,获取FLAG
大坑
使用VisualCode
,观察了三天(wen da lao)
,结果用sublime Text
打开后直接得到结果,copy
到url
中加上sha2
参数
获取参数sha1,sha2,username的值 -l
$user = $_GET['username'];//user
$sha1 = $_GET['sha1'];//sha1
$sha2 = $_GET['//sha2sha2'];
//see me can you
关键逻辑 -l
#检查sha1 和 sha2 和 user 是否被赋值
if sha1 and sha2 and user:
# 34839520012
[crypto, user] = SecurityCheck(sha1, sha2, user)
# 检查crypto和user的SHA-1哈希的最后六个字符是否都等于字符串'a05c53'
# 14987637 ceca5d3ab81779f20b97dab9220c46f3f9 a05c53
if sha1(crypto)[-6:] == sha1(user)[-6:] == 'a05c53': # welcome to ISCC
#ISCCNOTHARD 484c0dd902218fef1e239baf69aeca61fbb94c06
#ISCC{}
if MyHashCode("ISCCNOTHARD") == MyHashCode(request.args
.get('password')) and Checked(request.args.get('password')):
include("f1ag.php")
print("成功了"+flag)
else:
print("就快解开了!")
else:
print("真的想不起来密码了吗?")
print("随机数:"+random.seed(int(time.time() * 1000) ^ random.randint(1, 10000)))
需要三个参数
,所以分析程序
加入username
,sha1
字段后的url
如下
http://47.94.14.162:10008/?password=ISCC&sha1=md&%E2%80%AE%E2%81%A6//sha2%E2%81%A9%E2%81%A6sha2=MD&username&password2=6
通过if((substr(sha1($crypto),-6,6) === substr(sha1($user),-6,6)) && (substr(sha1($user),-6,6)) === 'a05c53')
得到结果
如下:
user = a05c53
sha1
是一个单向哈希函数
,用来计算hashCode
,user
和 crypto
是一个 变量
,用来赋值用
比较两个字符串的后6位
是否相等,并且第二个字符串
的后6位
是否为’a05c53
’。具体来说,这段代码使用PHP
中的sha1
函数对两个变量
进行哈希处理
,然后从每个哈希值
的末尾6个字符
中提取子字符串
,并使用" ===
"运算符比较它们是否相等
。如果这两个子字符串都相等
,并且第二个字符串后6位
是’a05c53
’,则条件成立
,返回true
,否则返回false
。
检查crypto和user的SHA-1哈希的最后六个字符是否都等于字符串’a05c53’
- 编写爆破脚本,得到hash的最后
6位
为a05c53
编写爆破脚本 -l
hash_suffix = "a05c53"
# 解密格式
hash_prefix = "98f08553e02079cd966442400bcef0e031642e2"
for i in range(100000000):
num = str(i).encode('utf-8')
hash_num = hashlib.sha1(num).hexdigest()
if hash_prefix + hash_num[-6:] == hash_prefix + hash_suffix:
print("The number is: ", i)
break
结果为:14987637
HashCode = ceca5d3ab81779f20b97dab9220c46f3f9a05c53
;
得到秘钥,那么密文和公钥是什么?我该如何推导出来 sha1 和 user的值呢?
1.规律:(substr(sha1($crypto),-6,6) === substr(sha1($user),-6,6)
UNICODE 反转
- 理解一下什么是
unicode
的码点
? Unicode
是属于编码字符集
(CCS)的范围。Unicode
所做的事情就是将我们需要表示的字符表中的每个字符
映射成一个数字
,这个数字
被称为相应字符的码点
(code point)。Unicode
编码使用16位
或32位数字
来表示字符,其中16位编码
称为基本多文种平面(BMP)
,32位编码
称为补充平面
。Unicode编码
的优点是可以表示全球范围内的所有字符
,包括各种语言的字母
、符号
、标点
和表情
QA
Q:如何获取sha1,sha2,use
的值?
A:在源码
中找答案