Skip to content

Commit

Permalink
Handle XML encoded ADB keystore and fix parsing bugs (#605)
Browse files Browse the repository at this point in the history
  • Loading branch information
DonnchaC authored Feb 7, 2025
1 parent 4e97e85 commit b184eee
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
41 changes: 38 additions & 3 deletions src/mvt/android/artifacts/dumpsys_adb.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


class DumpsysADBArtifact(AndroidArtifact):
multiline_fields = ["user_keys"]
multiline_fields = ["user_keys", "keystore"]

def indented_dump_parser(self, dump_data):
"""
Expand Down Expand Up @@ -67,9 +67,28 @@ def indented_dump_parser(self, dump_data):

return res

def parse_xml(self, xml_data):
"""
Parse XML data from dumpsys ADB output
"""
import xml.etree.ElementTree as ET

keystore = []
keystore_root = ET.fromstring(xml_data)
for adb_key in keystore_root.findall("adbKey"):
key_info = self.calculate_key_info(adb_key.get("key").encode("utf-8"))
key_info["last_connected"] = adb_key.get("lastConnection")
keystore.append(key_info)

return keystore

@staticmethod
def calculate_key_info(user_key: bytes) -> str:
key_base64, user = user_key.split(b" ", 1)
if b" " in user_key:
key_base64, user = user_key.split(b" ", 1)
else:
key_base64, user = user_key, b""

key_raw = base64.b64decode(key_base64)
key_fingerprint = hashlib.md5(key_raw).hexdigest().upper()
key_fingerprint_colon = ":".join(
Expand Down Expand Up @@ -115,8 +134,24 @@ def parse(self, content: bytes) -> None:
if parsed.get("debugging_manager") is None:
self.log.error("Unable to find expected ADB entries in dumpsys output") # noqa
return

# Keystore can be in different levels, as the basic parser
# is not always consistent due to different dumpsys formats.
if parsed.get("keystore"):
keystore_data = b"\n".join(parsed["keystore"])
elif parsed["debugging_manager"].get("keystore"):
keystore_data = b"\n".join(parsed["debugging_manager"]["keystore"])
else:
parsed = parsed["debugging_manager"]
keystore_data = None

# Keystore is in XML format on some devices and we need to parse it
if keystore_data and keystore_data.startswith(b"<?xml"):
parsed["debugging_manager"]["keystore"] = self.parse_xml(keystore_data)
else:
# Keystore is not XML format
parsed["debugging_manager"]["keystore"] = keystore_data

parsed = parsed["debugging_manager"]

# Calculate key fingerprints for better readability
key_info = []
Expand Down
25 changes: 25 additions & 0 deletions tests/android/test_artifact_dumpsys_adb.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,28 @@ def test_parsing(self):
user_key["fingerprint"] == "F0:A1:3D:8C:B3:F4:7B:09:9F:EE:8B:D8:38:2E:BD:C6"
)
assert user_key["user"] == "user@linux"

def test_parsing_adb_xml(self):
da_adb = DumpsysADBArtifact()
file = get_artifact("android_data/dumpsys_adb_xml.txt")
with open(file, "rb") as f:
data = f.read()

da_adb.parse(data)

assert len(da_adb.results) == 1

adb_data = da_adb.results[0]
assert "user_keys" in adb_data
assert len(adb_data["user_keys"]) == 1

# Check key and fingerprint parsed successfully.
expected_fingerprint = "F0:0B:27:08:E3:68:7B:FA:4C:79:A2:B4:BF:0E:CF:70"
user_key = adb_data["user_keys"][0]
user_key["fingerprint"] == expected_fingerprint
assert user_key["user"] == "user@laptop"

key_store_entry = adb_data["keystore"][0]
assert key_store_entry["user"] == "user@laptop"
assert key_store_entry["fingerprint"] == expected_fingerprint
assert key_store_entry["last_connected"] == "1628501829898"
16 changes: 16 additions & 0 deletions tests/artifacts/android_data/dumpsys_adb_xml.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-------------------------------------------------------------------------------
DUMP OF SERVICE adb:
ADB MANAGER STATE (dumpsys adb):
{
debugging_manager={
connected_to_adb=true
user_keys=QAAAAAcgbytJst31DsaSP7hn8QcBXKR9NPVPK9MZssFVSNIP user@laptop

keystore=<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<keyStore version="1">
<adbKey key="QAAAAAcgbytJst31DsaSP7hn8QcBXKR9NPVPK9MZssFVSNIP user@laptop" lastConnection="1628501829898" />
</keyStore>

}
}
--------- 0.012s was the duration of dumpsys adb, ending at: 2025-02-04 20:25:58

0 comments on commit b184eee

Please sign in to comment.