hackinglab-解密关Writeup
hackinglab-解密关
1. 以管理员身份登录系统
在重置密码成功页面获得Tips
看链接
/reset.php?sukey=79804c0ea4d2a961fbfd2cff08664098&username=123
GET提交的参数中,sukey应该是验证,username提交要重置密码的账户名
对sukey进行md5解密
是unix时间戳
可能是你向服务器提交重置username密码的请求,服务器会给你一个sukey,并且会记录下sukey和username的值。当点击包含sukey和username参数的重置链接后,服务器会接收sukey和username,然后和服务器记录的进行匹配,当username和sukey都符合后,重置密码成功。
接下来就可以伪造sukey重置admin了
大致思路:
sukey=md5(int(time()))
先抓个包看看服务器时间
发现比北京时间慢了八个小时,转成时间戳就是慢了28800
方法一:
在重置密码界面输入账户名admin,点击提交,并且记住提交时刻的时间戳x
对x-28800进行md5加密,得到重置admin账户的sukey
将重置链接的sukey和username进行替换,重置admin
方法二:
脚本:
import requests
import hashlib
import time
se = requests.session()
headers = {'Cookie': 'PHPSESSID=423613048c7ae8017f654bea6fafe808'}
while 1:
sukey = hashlib.new('md5', str(int(time.time())-28800)).hexdigest()
url = 'http://lab1.xseclab.com/password1_dc178aa12e73cfc184676a4100e07dac/reset.php?sukey=' + sukey + '&username=admin'
r = se.get(url, headers=headers)
if r.content:
print r.content
break
else:
print 'Cracking: ' + sukey
方法三:
先提交admin重置请求,再写脚本生成对应的时间戳字典
with open("pass.txt","w") as f:
for x in range(1573180000,1573200000): #大概的时间戳范围
f.write("%d\n" % x)
抓包,点击重置连接,发送到intruder,将username改为admin,设置sukey为变量
payload设置载入字典pass.txt,设置hash md5加密
爆破,根据返回包长度判断是否爆破成功
2. 邂逅对门的妹纸
下载得到一个wifi-crack.cap包,提示信息中:“小明知道妹纸今年(2014年)上大三”猜测wifi密码可能是生日格式
写脚本生成一个字典dic.txt:
with open("dic.txt","w") as f:
for year in range(1990,2014):
for month in range(1,12):
for day in range(1,32):
f.write("%d%02d%02d\n" % (year,month,day))
上aircrack-ng
找到密码,直接32位md5小写加密,提交
3. 万恶的Cisco
找到个在线cisco交换机密码破解:Cisco Password Cracker
4. 万恶的加密
提示是某huawei/h3c交换机密码,搜了搜是DES加密,找到一个脚本:
# coding=utf-8
from Crypto.Cipher import DES
def decode_char(c):
if c == 'a':
r = '?'
else:
r = c
return ord(r) - ord('!')
def ascii_to_binary(s):
assert len(s) == 24
out = [0]*18
i = 0
j = 0
for i in range(0, len(s), 4):
y = decode_char(s[i + 0])
y = (y << 6) & 0xffffff
k = decode_char(s[i + 1])
y = (y | k) & 0xffffff
y = (y << 6) & 0xffffff
k = decode_char(s[i + 2])
y = (y | k) & 0xffffff
y = (y << 6) & 0xffffff
k = decode_char(s[i + 3])
y = (y | k) & 0xffffff
out[j+2] = chr(y & 0xff)
out[j+1] = chr((y>>8) & 0xff)
out[j+0] = chr((y>>16) & 0xff)
j += 3
return "".join(out)
def decrypt_password(p):
r = ascii_to_binary(p)
r = r[:16]
d = DES.new("\x01\x02\x03\x04\x05\x06\x07\x08", DES.MODE_ECB)
r = d.decrypt(r)
return r.rstrip("\x00")
if __name__ == '__main__':
miwen = "aK9Q4I)J'#[Q=^Q`MAF4<1!!"
print u'明文' + decrypt_password(miwen)
直接运行
5. 喜欢泡网吧的小明
修复dump文件一个字节的错误,并且把卡金额改为200就好了
winhex打开dump文件,看了看基本是前面几行有意义,后面都是重复的字节
先修复字节错误,看了提示,错误出现在第一行,文件头应该有始有终,测试后发现是将第一个AA改为8A
修改金额:将100的十六进制是64,在dump文件里没有找到
不过根据刷卡页面,金额用100.00来表示,发现10000的十六进制是2710
20000(D)->4e20(H)
所以将两个1027改成204e就好
6. 异常数据
妹纸给了一个谜语序列:AGV5IULSB3ZLVSE=
乍一看就是base64加密,但是直接解不出来
题目说的是异常数据,看了看,全是大写,应该是把大小写都给转成大写了
用脚本
# coding=utf-8
from base64 import *
import re
def dfs(res, arr, pos):
res.append(''.join(arr))
i = pos
for i in range(i, len(arr)):
if arr[i] <= 'Z' and arr[i] >= 'A':
arr[i] = arr[i].lower()
dfs(res, arr, i + 1)
arr[i] = arr[i].upper()
arr = list('AGV5IULSB3ZLVSE=')
res = []
dfs(res, arr, 0)
res_decode = map(b64decode, res)
for i in res_decode:
if re.findall(r'\\x', repr(i)):
continue
else:
print i
就这句看着正常点,key应该就是它了
7. md5真的能碰撞嘛?
$rootadmin=”!1793422703!”;
对!1793422703!进行md5加密:
0e332932043729729062996282883873
用到了PHP处理0e开头的md5哈希字符串时的一个漏洞
PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
所以只要POST提交password的值经过md5加密后是0e开头就行
8. 小明爱上了一个搞硬件的小姑凉
下载文件,用notepad打开看看
这应该就是Tips中的某逻辑分析仪
搜搜Saleae Async Serial Analyzer,下载,打开
把未知文件拖进去
但是这个COMMA夹在中间,像极了电灯泡
原来
9. 有签名限制的读取任意文件
MD5长度扩展攻击
这道题看的答案
Payload:
http://lab1.xseclab.com/decrypt1_53a52adb49c55c8daa5c8ee0ff59befe/md5_le.php?filepath=/etc/hosts%80%00%00%00%00%00%00%00%00%00%00%00%00%00P%01%00%00%00%00%00%00/etc/_flag.php&sign=7fbbac6efeb7939be04829bc9a847f0c
10. 美丽的邂逅与密码器的开门密码
下载得到一个exe文件,先运行一下
提示输入Key
用IDA打开,找到main()主函数,F5生成伪代码
可以看到v19变量用来接收输入,当v18 == 1时会输出一串字符串,否则输出Error。这些字符串应该就是Flag了
方法一:
最简单粗暴的方法是将v1到v16的值进行ASCII解码,就是对应的Flag
方法二:
跟进sub_401005()函数
调用了sub_401020()函数,继续跟进
这个函数获取了传入的参数a1的长度,如果长度大于50就返回1(true)。
所以只需要输入的字符串长度大于50就行了