第八届西湖论剑中国杭州网络安全安全技能大赛初赛 部分wp

ds

easydatalog

分析error.log发现首先上传了木马,然后用蚁剑进行连接

全局搜索发现包含一个zip和jpg

压缩包数据很少直接手动提取出来,图片数据太多用脚本提取出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import re


def extract_jpg_data(log_file):
# 读取日志文件内容
with open(log_file, 'r') as f:
content = f.read()

lines = content.split('\n')
hex_data = []

for line in lines:
# 跳过包含readbytes或bytes的行
if 'readbytes' in line or 'bytes' in line:
continue

# 如果行包含dumpio_in或dumpio_out
if 'dumpio_in' in line or 'dumpio_out' in line:
# 提取冒号后的内容
parts = line.split('dumpio_in (data-HEAP): ', maxsplit=1)
if len(parts) > 1:
data = parts[1].strip()
else:
parts = line.split('dumpio_out (data-HEAP): ', maxsplit=1)
if len(parts) > 1:
data = parts[1].strip()
else:
continue

hex_data.append(data)

data = ''.join(hex_data)

# 查找jpg数据(从FFD8到FFD9)
jpg_pattern = r'FFD8FFE0.*?00FFD9'
jpg_matches = re.findall(jpg_pattern, data)

# 保存找到的jpg数据
for i, jpg_data in enumerate(jpg_matches):
binary_data = bytes.fromhex(jpg_data)
with open(f'out.jpg', 'wb') as f:
f.write(binary_data)

if __name__ == '__main__':
extract_jpg_data('error.log')

图片盲水印得到密码

用得到的密码dataPersonPass123987解压压缩包得到用户信息表

拼接出张三的身份证号和手机号

30601319731003117X_79159498824

DSASignatureData

tshark筛选出所有的数据

tshark -r data.pcapng -T fields -e http.file_data -e http.request.uri > data.txt

对筛选出来的数据进行整理,转成明文后去重和排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import json


# 将十六进制字符串转换为字节,然后解码为UTF-8字符串
def decode_hex_string(hex_string):
return bytes.fromhex(hex_string).decode('utf-8')


def process_data():
with open('data.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()

result = []
seen = set() # 用于记录已经处理过的数据

for line in lines:
if '/?userid=' in line:

json_hex = line.strip().split('\t')[0] # 提取JSON数据部分
try:
json_str = decode_hex_string(json_hex)
data = json.loads(json_str)
userid = line.split('/?userid=')[1].split()[0]
data['userid'] = userid

unique_key = (data['idcard'], data['phone'])

if unique_key not in seen:
seen.add(unique_key)
result.append(data)
except:
continue

print(f"Found {len(result)} unique records")

result.sort(key=lambda x: int(x['userid']))

with open('data_new.txt', 'w', encoding='utf-8') as f:
for data in result:
line = f"{data['userid']},{data['name']},{data['idcard']},{data['phone']}\n"
f.write(line)


if __name__ == '__main__':
process_data()

得到全部的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
userid,name,idcard,phone
1,侯俊英,532215199108067664,73457647068
2,寇雪,637373199908267850,79311464433
3,南郭映安,516067201404039268,79843161520
4,仲长宗,690694198504259989,78927258687
5,伏羲永琴,968155199102184917,78781034018
6,班涵润,496980198102184431,73056859184
7,丁映安,098529200809222274,79398505211
8,通春雪,838747198907275515,74568181144
...
1996,东关燕子,864371198811109088,75589142337
1997,桂秀慧,921145197101023429,73457033928
1998,车钗,284617199806039673,74960899903
1999,文浩渺,829973198603161976,73871235789
2000,祁陈红,987193201007052887,74518763400

然后与data-sign.csv中的签名数据比较

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import csv
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import dsa, utils
from cryptography.hazmat.primitives.serialization import load_pem_public_key
from cryptography.exceptions import InvalidSignature
import base64


def load_public_key(userid):
"""加载用户的公钥"""
userid_padded = str(userid).zfill(4)
with open(f'public/public-{userid_padded}.pem', 'rb') as f:
key_data = f.read()
return load_pem_public_key(key_data)


def verify_signature(public_key, message, signature):
"""验证签名"""
try:
# 解码Base64签名
signature_bytes = base64.b64decode(signature)

# 提取r和s值
r = int.from_bytes(signature_bytes[:20], 'big')
s = int.from_bytes(signature_bytes[20:], 'big')

# 计算消息哈希并编码签名
message_bytes = message.encode('utf-8')
encoded_signature = utils.encode_dss_signature(r, s)

# 验证签名
public_key.verify(
encoded_signature,
message_bytes,
hashes.SHA256()
)
return True
except (InvalidSignature, Exception):
return False


def verify_records():
"""验证所有记录"""
# 读取原始数据
original_data = {}
with open('data_new.txt', 'r', encoding='utf-8') as f:
next(f) # 跳过标题行
for line in f:
userid, name, idcard, phone = line.strip().split(',')
original_data[userid] = {
'name': name,
'idcard': idcard,
'phone': phone
}

# 读取签名数据
signatures = {}
with open('data-sign.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
userid = row['username']
signatures[userid] = {
'name_signature': row['name_signature'],
'idcard_signature': row['idcard_signature'],
'phone_signature': row['phone_signature']
}

# 验证每条记录
tampered_records = []
for userid, orig_data in original_data.items():
# 加载公钥
try:
public_key = load_public_key(userid)
sig_data = signatures[userid]

# 验证所有字段的签名
name_valid = verify_signature(public_key, orig_data['name'], sig_data['name_signature'])
idcard_valid = verify_signature(public_key, orig_data['idcard'], sig_data['idcard_signature'])
phone_valid = verify_signature(public_key, orig_data['phone'], sig_data['phone_signature'])

# 如果任何字段验证失败,记录该条数据
if not (name_valid and idcard_valid and phone_valid):
tampered_records.append({
'userid': userid,
'name': orig_data['name'],
'idcard': orig_data['idcard'],
'phone': orig_data['phone']
})
except Exception:
continue

return tampered_records


def main():
# 验证记录并获取被篡改的数据
tampered_records = verify_records()

# 将被篡改的记录写入CSV文件
if tampered_records:
with open('tampered_records.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['userid', 'name', 'idcard', 'phone'])
writer.writeheader()
writer.writerows(tampered_records)
print(f"Found {len(tampered_records)} tampered records. Details written to tampered_records.csv")
else:
print("No tampered records found.")


if __name__ == '__main__':
main()

easyrawencode

vol2分析镜像

搜常见后缀

python vol.py -f easyrawencode.raw --profile Win7SP1x64 filescan | grep -E "txt|xml|png|jpg|gif|zip|rar|7z|pdf|doc|docx|php|py|flag"

发现hack.py

python vol.py -f easyrawencode.raw --profile Win7SP1x64 dumpfiles -Q 0x000000003dfdf070 -D ./

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import os
import hashlib
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA

hackkey = os.getenv('hackkey')
if not hackkey:
raise ValueError("Environment variable 'hackkey' is not set")

with open('private.pem', 'r') as f:
private_key = RSA.import_key(f.read())
public_key = private_key.publickey().export_key()

aes_key = hashlib.sha256(hackkey.encode()).digest()

with open('data.csv', 'rb') as f:
data = f.read()

cipher_aes = AES.new(aes_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
cipher_rsa = PKCS1_OAEP.new(RSA.import_key(public_key))
enc_aes_key = cipher_rsa.encrypt(aes_key)

with open('encrypted_data.bin', 'wb') as f:
f.write(ciphertext)

print(enc_aes_key.hex())
print(cipher_aes.nonce.hex())
print(tag.hex())

根据代码分别查看环境变量hackkey private.pem encrypted_data.bin

python vol.py -f easyrawencode.raw --profile Win7SP1x64 envars | grep -E 'hackkey'
python vol.py -f easyrawencode.raw --profile Win7SP1x64 filescan | grep -E "private.pem|encrypted_data.bin"

还需要查看当时运行代码后输出的值

python vol.py -f easyrawencode.raw --profile Win7SP1x64 consoles

根据得到的信息还原出data.csv

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import hashlib
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.PublicKey import RSA

hackkey = '4etz0hHbU3TgKqduFL'
aes_key = hashlib.sha256(hackkey.encode()).digest()

nonce_hex = "d919c229aab6535efa09a52c589c8f47"
nonce = bytes.fromhex(nonce_hex)


with open('encrypted_data.bin', 'rb') as f:
ciphertext = f.read()

try:
# 使用AES密钥解密数据,先不验证MAC
cipher_aes = AES.new(aes_key, AES.MODE_EAX, nonce=nonce)
data = cipher_aes.decrypt(ciphertext)

with open('data.csv', 'wb') as f:
f.write(data)

print("解密完成,数据已保存到 data.csv")

except Exception as e:
print("解密过程中出现错误:", str(e))

得到一份用户数据

1
2
3
4
5
6
7
8
9
10
编号,用户名,密码,姓名,性别,出生日期,个性签名(加密版)
1,sWEbvrLvgyFO9u8,vHBhvVXS2JvLnTTo,胜屠翰池,男,19761023,korvy4fjEBP6AKeDValKDfzBRK9sKDSIHVakq3NXMMU3
2,wangguizhi,3E8vleDJFC,桓玉珂,女,20050814,NF+z3NevQqWILNqNvUznlOFie3KLuhIztQNLFnRy
3,kofxlSO1C3XEXP3QPH1lEg5WQ,4U86p3uzw7xV,崎邱炜,男,20000710,yutW+1ipTbce3pcz+BEIBS48fX7NF5hh8bWEdigYsHca3vo/dQ0Nl+YFmpl5UD4Onga0hGehitNvMrG4XNFdH+lHEg==
4,caijijinotwo1f,PupkzhU9R0g4AoP,禹歆美,女,20120626,t02tKoybGWyIqYL133qtg4+yG3yRvNk=
...
1997,QV1lQhy1eYi6,s6oJFLTbRPG,公刘芳林,男,19950104,QMvnJnbRC8dbNNSBCX4ZJoFul2q4XilJXc9BQ/rG
1998,9tk5p3Y,90909090tianxia,公休生文,男,19790402,RO7+27VoJ3Feb5uPhDmASe27URp9
1999,40utHZEBKPmxiMO7VrE6CMm,vhathQj2XGSB,云阔,女,19930420,aaf/6mkYPho71FZAjGbRzjZOqx//FgT1fzMfLFzyBAtPQZf9KbMu/Teo/ANL9Ur09CgO5N0UV2+Gr1ncqLy5zZv0p+VhqJwvm7U4ypUyovY=
2000,liuguiying,YeE8DXLSPMthwp,沈盈盈,男,19750412,g+1FWgFzuwHOLzZ7Qy1QVWtLhQoRVVQQhUSml8p/d6IeK6NG/8VFV+v0wqCHEIlYFVXtPSncSQ==

根据结构组成猜测aes等加密方法,最后通过rc4解出明文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import pandas as pd
import base64

data = pd.read_csv('data.csv')
password = data['密码']
signature = data['个性签名(加密版)']


def rc4_decrypt(ciphertext, key):
try:
ciphertext = base64.b64decode(ciphertext)
key = key.encode('utf-8')

S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]

i = j = 0
plaintext = bytearray()
for byte in ciphertext:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = S[(S[i] + S[j]) % 256]
plaintext.append(byte ^ k)

return plaintext.decode('utf-8', errors='ignore')
except Exception as e:
print(f"Debug - Key length: {len(key)}, Ciphertext length: {len(ciphertext)}")
return f"Decryption failed: {str(e)}"


for i in range(len(password)):
result = rc4_decrypt(signature[i], password[i])
print(f"Entry {i}: {result}")
if 'DASCTF' in result:
print(f"Found flag in entry {i}: {result}")
break


第八届西湖论剑中国杭州网络安全安全技能大赛初赛 部分wp
https://www.dr0n.top/posts/74a23a1b/
作者
dr0n
发布于
2025年1月18日
更新于
2025年1月18日
许可协议