feat(maribank): PH 注册 OTP 突破、SG bypass 与中文文档
菲律宾 SeaBank 在 Root+LSPosed+Shamiko 下 register 已通过并触发 OTP;扩展 SG 包名、加密前 Hook、Magisk 设备伪装脚本,并将 docs 整理为中文操作与风控说明。
This commit is contained in:
38
reverse/scripts/dump_sg_safemode.py
Normal file
38
reverse/scripts/dump_sg_safemode.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import subprocess
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
|
||||
DEXDUMP = Path(r"C:\Users\Administrator\AppData\Local\Android\Sdk\build-tools\37.0.0\dexdump.exe")
|
||||
TARGETS = [
|
||||
"Lcom/shopee/bke/lib/safemode/model/ErrorType;",
|
||||
"Lcom/shopee/bke/lib/safemode/activity/SafeModeRecoverActivity;",
|
||||
"Lcom/shopee/bke/lib/safemode/b;",
|
||||
]
|
||||
|
||||
with zipfile.ZipFile(str(APK)) as zf:
|
||||
for name in zf.namelist():
|
||||
if not name.endswith(".dex"):
|
||||
continue
|
||||
data = zf.read(name)
|
||||
if not any(t.replace("L", "").replace(";", "").encode() in data for t in TARGETS):
|
||||
continue
|
||||
tmp = Path(__file__).resolve().parent.parent / "tmp" / "sg_safemode.dex"
|
||||
tmp.parent.mkdir(parents=True, exist_ok=True)
|
||||
tmp.write_bytes(data)
|
||||
out = subprocess.check_output(
|
||||
[str(DEXDUMP), "-d", str(tmp)], universal_newlines=True, errors="replace"
|
||||
)
|
||||
for target in TARGETS:
|
||||
if target.replace("L", "").replace(";", "") not in data.decode("latin1", errors="ignore"):
|
||||
continue
|
||||
print("=" * 60, name, target)
|
||||
cap = False
|
||||
for line in out.splitlines():
|
||||
if f"Class descriptor : '{target}'" in line:
|
||||
cap = True
|
||||
elif cap and line.startswith(" Class descriptor") and target not in line:
|
||||
break
|
||||
if cap and ("name :" in line or "const-string" in line or "ErrorType" in line):
|
||||
print(line.strip()[:140])
|
||||
28
reverse/scripts/find_sg_adb_classes.py
Normal file
28
reverse/scripts/find_sg_adb_classes.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
|
||||
with zipfile.ZipFile(str(APK)) as zf:
|
||||
data = b"".join(zf.read(n) for n in zf.namelist() if n.endswith(".dex"))
|
||||
|
||||
print("=== Adb / SafeMode related classes ===")
|
||||
for m in re.finditer(rb"L[\w$/]*(Adb|ADB|SafeMode|safemode|Recover)[\w$/]*;", data):
|
||||
c = m.group().decode()
|
||||
if "shopee" in c or "bke" in c or "maribank" in c.lower():
|
||||
print(c)
|
||||
|
||||
print("\n=== shpssdk bank ===")
|
||||
for m in re.finditer(rb"Lcom/shopee/shpssdk[\w$/]*;", data):
|
||||
print(m.group().decode())
|
||||
|
||||
print("\n=== api.seabank / maribank hosts ===")
|
||||
for m in re.finditer(rb"https?://[a-zA-Z0-9._/-]{8,80}", data):
|
||||
u = m.group().decode()
|
||||
if "maribank" in u or "seabank" in u:
|
||||
print(u)
|
||||
|
||||
print("\n=== login/register uapi ===")
|
||||
for m in re.finditer(rb"/uapi/[a-zA-Z0-9_/-]+", data):
|
||||
print(m.group().decode())
|
||||
39
reverse/scripts/find_sg_adb_strings.py
Normal file
39
reverse/scripts/find_sg_adb_strings.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
|
||||
with zipfile.ZipFile(str(APK)) as zf:
|
||||
data = b"".join(zf.read(n) for n in zf.namelist() if n.endswith(".dex"))
|
||||
|
||||
for pat in [
|
||||
b"Does not support",
|
||||
b"Turn Off ADB",
|
||||
b"Wireless ADB",
|
||||
b"ADB/Wireless",
|
||||
b"support root",
|
||||
b"RISK_USB_ADB",
|
||||
b"RISK_WIFI_ADB",
|
||||
b"KEY_ALLOW_ADB",
|
||||
b"SafeModeRecover",
|
||||
b"sg.com.maribank",
|
||||
]:
|
||||
print(pat.decode(), "->", data.count(pat))
|
||||
|
||||
print("\n--- UI strings ---")
|
||||
for m in re.finditer(rb"[\x20-\x7e]{10,200}", data):
|
||||
s = m.group().decode("ascii", "ignore")
|
||||
sl = s.lower()
|
||||
if ("adb" in sl and ("detect" in sl or "turn" in sl or "wireless" in sl or "debug" in sl)) or "does not support root" in sl:
|
||||
print(s)
|
||||
|
||||
print("\n--- Application ---")
|
||||
for m in re.finditer(rb"Lcom/shopee/bke/[\w$/]*Application[\w$/]*;", data):
|
||||
print(m.group().decode())
|
||||
|
||||
print("\n--- ADB risk classes ---")
|
||||
for m in re.finditer(rb"L[\w$/]*(adb|Adb|ADB)[\w$/]*;", data):
|
||||
c = m.group().decode()
|
||||
if "shopee" in c.lower() or "bke" in c.lower() or "shps" in c.lower():
|
||||
print(c)
|
||||
82
reverse/scripts/scan_maribank_sg.py
Normal file
82
reverse/scripts/scan_maribank_sg.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Quick DEX scan for MariBank SG detection / auth strings."""
|
||||
import re
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
APK = Path(__file__).resolve().parent.parent / "apks" / "maribank_sg_base.apk"
|
||||
if len(sys.argv) > 1:
|
||||
APK = Path(sys.argv[1])
|
||||
|
||||
needles = [
|
||||
b"ADB",
|
||||
b"Wireless ADB",
|
||||
b"USB debugging",
|
||||
b"Wireless debugging",
|
||||
b"Does not support root",
|
||||
b"root device",
|
||||
b"rooted",
|
||||
b"jailbroken",
|
||||
b"safemode",
|
||||
b"SafeMode",
|
||||
b"shpssdk",
|
||||
b"SHPSSDK",
|
||||
b"getRiskToken",
|
||||
b"requestDefense",
|
||||
b"BkeApplication",
|
||||
b"errorcodehandler",
|
||||
b"4067012",
|
||||
b"4067004",
|
||||
b"/uapi/",
|
||||
b"/dfp/",
|
||||
b"register",
|
||||
b"login",
|
||||
b"auth/precheck",
|
||||
]
|
||||
|
||||
class_needles = [
|
||||
rb"Lcom/shopee/bke/[\w$/]+;",
|
||||
rb"Lcom/shopee/shpssdk[\w$/]*;",
|
||||
]
|
||||
|
||||
with zipfile.ZipFile(str(APK)) as zf:
|
||||
data = b"".join(zf.read(n) for n in zf.namelist() if n.endswith(".dex"))
|
||||
print("APK:", APK.name, "dex bytes:", len(data))
|
||||
print("\n=== string hits ===")
|
||||
for n in needles:
|
||||
c = data.count(n)
|
||||
if c:
|
||||
print(f" {n.decode(errors='replace')!r}: {c}")
|
||||
|
||||
print("\n=== api paths (sample) ===")
|
||||
paths = sorted(set(m.group().decode() for m in re.finditer(rb"/v[0-9]/[a-zA-Z0-9_/-]{4,80}", data)))
|
||||
for p in paths:
|
||||
pl = p.lower()
|
||||
if any(k in pl for k in ("auth", "login", "register", "otp", "dfp", "user", "mobile", "pin")):
|
||||
print(" ", p)
|
||||
|
||||
print("\n=== shopee/bke classes (sample) ===")
|
||||
classes = sorted(set(m.group().decode() for m in re.finditer(rb"Lcom/shopee/bke/[\w$/]{8,120};", data)))
|
||||
keywords = ("safemode", "risk", "adb", "debug", "root", "error", "user", "digitalbank", "Application")
|
||||
shown = 0
|
||||
for c in classes:
|
||||
cl = c.lower()
|
||||
if any(k in cl for k in keywords):
|
||||
print(" ", c)
|
||||
shown += 1
|
||||
if shown >= 40:
|
||||
break
|
||||
print(f" ... total bke classes: {len(classes)}")
|
||||
|
||||
print("\n=== context: ADB Detected ===")
|
||||
idx = data.find(b"ADB")
|
||||
while idx >= 0 and idx < len(data):
|
||||
chunk = data[max(0, idx - 30) : idx + 80]
|
||||
if b"Detect" in chunk or b"debug" in chunk.lower() or b"Wireless" in chunk:
|
||||
s = re.sub(rb"[^\x20-\x7e]+", b" ", chunk).decode("ascii", "ignore").strip()
|
||||
if len(s) > 20:
|
||||
print(" ", s[:120])
|
||||
idx = data.find(b"ADB", idx + 1)
|
||||
if idx > 0 and data.find(b"ADB", idx + 1) == -1:
|
||||
break
|
||||
Reference in New Issue
Block a user