PC小程序反编译工具之unveilr 2.0 免费版

PC小程序反编译工具之unveilr 2.0 免费版

本文转自 小夏 并作补充

由于新版要收费,此版本为unveilr 最后的免费版,留存一下

安装方法

1. 下载可执行文件 【这是一个命令行工具,windows上双击是不行的】

参数详解

  • 子命令是为了后续集成别的平台小程序解包功能
  • 子命令默认为 wx
子命令 参数 解释
-l, --log-level <level> 设置日志等级 debuginfowarnerror 默认 info
-v, --version 打印版本号并退出
wx <packages...> wxapkg的路径,可以是多个,也可以是一个目录
wx -i, --appid <appid> 解密windows上的 wxapkg时需要提供🔥已经支持自动从路径中提取
wx -f, --format 是否需要格式化解析出来的代码
wx --no-clear-decompile 不清除反编译时的残留文件
wx --no-clear-save 不清除之前的编译结果
wx --no-parse 只提取wxapkg中的文件,不进行反编译
wx -d, --depth <depth> 设置从目录中查找wxapkg的深度默认: 1 设置为0时不限制深度
wx -o, --output <path> 设置反编译输出目录
wx --clear-output 当输出目录不为空时程序将终止,提供该参数表示强制清空输出目录

使用示例

  • 如果路径有空格必需加引号
1
2
3
4
5
6
7
8
9
10
# 直接解包整个目录
unveilr.exe "/path/to/wxapkg/dir/"
# 解多个包
unveilr.exe "/path/to/1.wxapkg" "/path/to/2.wxapkg" ...
# 指定wx子命令并指定微信AppId
unveilr.exe wx -i wx11aa22bb33cc44dd "/path/to/wxapkg/dir/"
# 格式化解析出来的代码
unveilr.exe wx -f "/path/to/wxapkg/dir/"
# 只提取源文件不解析进行反编译
unveilr.exe wx --no-parse "/path/to/wxapkg/dir/"

反编译小程序、数据加密解密、sign值绕过

反编译小程序、数据加密解密、sign值绕过

本文转自 sys0ne 并作补充

在一次渗透测试中对客户的小程序进行测试,一抓包就发现重重加密数据,在手机号一键登录数据包中发现泄露了session_key值,但是进行加密处理过,那就反编译小程序进行解密尝试。

反编译小程序

在点击该小程序时,C:\Users\xxx\Documents\WeChat Files\Applet在该目录下下会生成一个新的目录,最好时只留下面两个目录。

image

image

在生成的目录下找到__ APP __.wxapkg文件,使用UnpackMiniApp.exe进行解密,重新生成一个wxapkg文件

image

将生成的wxapkg文件拖到wxapkgconvertor.exe进行反编译,就会在wxapkg文件目录下生成一个新的文件夹,使用微信开发者工具打开就可以看到小程序的源码了

image

image

解密AES函数

发现存在数据加密,编译小程序,分析源码

image

对小程序进行调试,直接全局搜AES字段,发现 AES 的加密密钥硬编码在源代码中。

decryptByAes 是一个用于解密的函数,它使用 AES算法解密输入的密文,返回明文。解密过程需要密文、密钥和初始化向量(IV),并使用 CBC 模式和 PKCS7 填充。

image

根据默认密钥编辑 python 脚本(通用脚本,直接替换key或iv即可)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
import binascii

def decrypt_by_aes(encrypted_hex, key_hex=None, iv_hex=None):

# 默认 Key 和 IV
DEFAULT_KEY_HEX = "31323334353??/414243444566"
DEFAULT_IV_HEX = "3031323334???43444546"

# 如果没有传入 Key 或 IV,使用默认值
key_hex = key_hex if key_hex is not None else DEFAULT_KEY_HEX
iv_hex = iv_hex if iv_hex is not None else DEFAULT_IV_HEX

# 将 Hex 字符串转换为 bytes
key = binascii.unhexlify(key_hex)
iv = binascii.unhexlify(iv_hex)
encrypted_data = binascii.unhexlify(encrypted_hex)

# 初始化 AES-CBC 解密器
cipher = AES.new(key, AES.MODE_CBC, iv)

# 解密并去除 PKCS7 填充
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)

# 返回 UTF-8 解码后的明文
return decrypted_data.decode('utf-8')


# 示例用法
if __name__ == "__main__":
encrypted_hex = "30313233343536373839414243444546"

try:
decrypted_text = decrypt_by_aes(encrypted_hex)
print("解密结果:", decrypted_text)
except Exception as e:
print("解密失败:", str(e))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import binascii

def encrypt_by_aes(plaintext, key_hex=None, iv_hex=None):
DEFAULT_KEY_HEX = "31323334353??/414243444566"
DEFAULT_IV_HEX = "3031323334???43444546"

# 如果未提供 key_hex 或 iv_hex,使用默认值
key_hex = key_hex if key_hex is not None else DEFAULT_KEY_HEX
iv_hex = iv_hex if iv_hex is not None else DEFAULT_IV_HEX

# 将十六进制字符串转换为字节
key = binascii.unhexlify(key_hex) # 32 字节密钥
iv = binascii.unhexlify(iv_hex) # 16 字节 IV

# 将明文转换为字节(UTF-8 编码)
plaintext_bytes = plaintext.encode('utf-8')

# 初始化 AES-CBC 加密器
cipher = AES.new(key, AES.MODE_CBC, iv)

# 添加 PKCS7 填充并加密
padded_data = pad(plaintext_bytes, AES.block_size) # PKCS7 填充
ciphertext = cipher.encrypt(padded_data)

# 将密文转换为十六进制字符串
ciphertext_hex = binascii.hexlify(ciphertext).decode('utf-8')

return ciphertext_hex

# 示例用法
if __name__ == "__main__":
# 测试数据
plaintext = "Hello, World!"
try:
# 使用默认密钥和 IV 加密
encrypted_default = encrypt_by_aes(plaintext)
print("加密结果:", encrypted_default)

except Exception as e:
print("加密失败:", str(e))

image

1
encryptedData=1b39aaa7b79f513b2958b671d8b8ad700ce3788963bc8ae3f91b61588cb963f05397695b3405dd75b2b91bc8e922d6918818e0d7eea3a835847b34b998bf5adf892fa1b41a193365a52970d063de10cb2d920aa066695d3187377a63c8efc0db1133cbcbb0f3d4c5def03e4c045a52f1c4401dbf23023e890a37c86773821b698a3f4f82d89840c33c14c0701cc8854b495e9c187106f7c265cd2fae34f320413adcff074bde1f189007c91a451054eee26ad058f3cdc74c67eba9f61ea1e010667b714c4d114559d14e8c9e2afb5c478c44d26c11de9bb88b1ec8e27f48269c&iv=b9d1b5783b906c84d20ae0b1ac1373c9d65e85bafb3922801b1f4681aadb8267&sessionKey=5a556c5a8288afd815bd6ef2a96ddf2e2e7b795abbc4304ac333a2352296d2e9&openId=c9731afaa0966e3778383bfb7bfa58f25ae50bd3edf21082414af311ea9fdb92&thirdType=56e32732df18962b0dab4454799fdd64&encryptFlag=1&timeHashPf=1744596343852&sign=01EC6E15CCE27E17FC5D5E58C1430E96

通过脚本解密出encryptedData、sessionKey、iv 值。

image

获得原始数据。

image

绕过sign值校验

修改手机号,改为任意用户的手机号,在进行加密处理,但是存在 sign 值校验,可以看到sign值时md5加密,不可逆,但是我们可以了解sign值的加密流程,修改数据重新加密sign值,然后替换sign值,进行绕过。

全局搜索sign,分析源码中的 setsigntrue 函数

image

1
2
3
4
5
6
7
setSignature: function(t) {
var n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, r = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : "", a = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : "", i = "";
for (var o in n) t[o] = n[o];
var s = this.objKeySort(t);
for (var u in s) i = "".concat(i).concat(u, "=").concat(t[u]);
return i += "".concat(r).concat(a), e.MD5(i).toString().toUpperCase();
},

这个函数接受四个参数:t,n,r,a。根据代码,t是主要的参数,n是可选参数,默认是空对象,r和a也有默认值。函数内部首先将n的属性合并到t中,也就是说,n中的键值对会被添加到t对象里。然后,它调用this.objKeySort(s),这里的s是处理后的t对象。objKeySort的作用是对对象的键进行排序,返回一个排序后的新对象。接下来,函数遍历排序后的对象s,将每个键值对以“key=value”的形式拼接成字符串i。然后,i后面拼接上r和a,最后对这个拼接后的字符串进行MD5加密,并转换为大写字符串返回。

  1. 将传入的n参数合并到t对象中,也就是把额外的参数添加到t里。
  2. 对t对象的所有键进行排序,得到排序后的对象s。
  3. 遍历排序后的s,将每个键值对拼接成“key=value”的字符串,并将这些字符串按顺序连接起来,形成字符串i。
  4. 在i的末尾添加r和a的值,得到最终的拼接字符串。
  5. 对这个最终字符串进行MD5哈希,并将结果转为大写,作为sign值返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import hashlib

params = {
"encryptFlag": "1",
"encryptedData": "1b39aaa7b79f513b2958b671d8b8ad700ce3788963bc8ae3f91b61588cb963f05397695b3405dd75b2b91bc8e922d6918818e0d7eea3a835847b34b998bf5adf892fa1b41a193365a52970d063de10cb2d920aa066695d3187377a63c8efc0db1133cbcbb0f3d4c5def03e4c045a52f1c4401dbf23023e890a37c86773821b698a3f4f82d89840c33c14c0701cc8854b495e9c187106f7c265cd2fae34f320413adcff074bde1f189007c91a451054eee26ad058f3cdc74c67eba9f61ea1e010667b714c4d114559d14e8c9e2afb5c478c44d26c11de9bb88b1ec8e27f48269c",
"iv": "b9d1b5783b906c84d20ae0b1ac1373c9d65e85bafb3922801b1f4681aadb8267",
"openId": "c9731afaa0966e3778383bfb7bfa58f25ae50bd3edf21082414af311ea9fdb92",
"sessionKey": "5a556c5a8288afd815bd6ef2a96ddf2e2e7b795abbc4304ac333a2352296d2e9",
"thirdType": "56e32732df18962b0dab4454799fdd64",
"timeHashPf": "1744596343852"
}

# 按字母顺序排序键
sorted_keys = sorted(params.keys())
# 拼接键值对
raw_str = "".join([f"{key}={params[key]}" for key in sorted_keys])
# 追加固定字符串
raw_str += "zoe-health3f7e609f0a22108e"
# MD5 计算并大写
sign = hashlib.md5(raw_str.encode()).hexdigest().upper()
print(sign)

运行 python 文件,输出的 md5 值和原始数据中的 sign 值一致

image

image

现在流程全部走完了

复现流程

抓取登录数据包,将密文都进行解密处理后,输入任意手机号,加密处理,将加密后的内容放入加密sign脚本文件中生成一个新的sign值,替换sign。就可以实现任意手机号登录。

image

image

image

image

iOS移动命令渗透测试备忘录

iOS移动命令渗透测试备忘录

本文转自 周边 并作补充

注意:iOS应用程序与Android应用程序具有不同的环境,此处的某些命令仅适用于MacOS。

**iOS**指南

Install Brew, 打开 terminal (Finder -> Application -> Utilities -> Terminal) 键入命令 :
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Install XCode, 打开 terminal 并运行命令 :
$ xcode-select --install
或者您可以手动下载 Apple Website

将您的Apple ID注册为Apple Developer Account。您无需为此部分的Apple Developer Program付费,只需将您的帐户注册到Developer中,因为我们只需要获得用于在XCode或其他工具上签名ipa文件的证书即可。

通过USB的(iPROXY)

http://iphonedevwiki.net/index.php/SSH_Over_USB

从应用商店或iPhone/iPad设备下载.ipa文件

需要越狱

Clutch

Clutch

Frida Script

Frida-ios-dump command: $ iproxy 2222 22 $ ./dump.py BundleID

iOS二进制分析

ios-Analysis

Download : ios-analysis

安装 :

1
2
3
$ git clone https://github.com/IAIK/ios-analysis
$ cd ios-analysis
$ git submodule update --init --recursive

如果您遇到这样的错误 : error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 60

运行这个命令: git config http.postBuffer 524288000

使用Windows登录并安装.ipa

  • 下载altsigner
  • 安装最新的iTunes(注意:使用二进制文件安装,请勿从Microsoft Store安装)
  • 打开Itunes并选择设备以复制设备的UDID
  • 打开altsigner.exe,填写您的[电子邮件,密码,UDID,.ipa文件路径]

使用我们的配置文件签名IPA文件

该工具非常有用:) iOS App Signer基于GUI。要生成我们的配置文件,您可以在安装应用程序时在XCODE上进行配置。

疑难问题

如果您收到这样的错误消息 If you have previously trusted your certificate using Keychain, please set the Trust setting back to the system default

不要惊慌,这样做:

  1. 进入Xcode并从“首选项”中删除您的帐户
  2. 去 ~/Library/MobileDevice/Provisioning 在finder中配置文件并删除其中的文件
  3. 进入钥匙串并删除所有提及Mac Developer,iOS Developer等的个人证书等
  4. 将您的帐户重新添加到Xcode中,然后选择吊销现有证书(如果无法吊销,请保留该证书)
  5. 转到xcode,然后尝试将虚拟应用程序安装到设备中。此步骤将触发苹果生成新的我们的证书。
  6. 然后,打开iOS App Signer

SonarQube-破解

SonarQube-破解

本文转自ny0c 并作补充

新版SonarQube破解

软件版本: sonarqube-9.8.0.63668
Java版本: jdk11
Agent版本: 1.2

帖子上有人求新版破解,花了点时间搞定了通杀的,已经测试过8.9.8 LTS跟9.8.0最新版(笔者注:事实上10.x的版本也可以进行破解)

使用说明

1、把下列信息全部复制,然后base64加密后的内容就是license,注意要包括换行

1
2
3
4
5
6
7
8
9
10
11
Company=Unknown
Digest=NotRequired
Edition=Enterprise
EditionLabel=Enterprise
Expiration=2099-01-01
MaxLoc=9223372036854775806
Plugins=abap,cpp,plsql,security,sonarapex,swift,tsql,vbnet,cobol,pli,rpg,vb
Features=*
ServerId=*
Support=false
Type=ny0c

image

2、修改SonarQube启动参数
解压从官方下载压缩包,根据自身需求配置好数据库链接
然后修改sonarqube-版本号/conf/sonar.properties的内容
其中

1
#sonar.web.javaOpts=-Xmx1G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

改成

1
sonar.web.javaOpts=-javaagent:/你的agent目录/SonarQubeAgent-1.2-SNAPSHOT.jar -Xmx1G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

以及

1
#sonar.ce.javaOpts=-Xmx2G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

改成

1
sonar.ce.javaOpts=-javaagent:/你的agent目录/SonarQubeAgent-1.2-SNAPSHOT.jar -Xmx2G -Xms128m -XX:+HeapDumpOnOutOfMemoryError

3、启动sonarqube
根据官方文档设置好sonarqube后,直接sonar.sh console启动控制台模式,看到app[][o.s.a.SchedulerImpl] Process[web] is up后,sonarqube启动成功

4、设置license
浏览器打开 http://sonarqube-IP地址:sonarqube-端口/ 设置或者登录sonarqube,然后点击最顶上的Administration选项卡,然后点击下面的Configuration,选择License Manager,接着设置License即可

image

旧帖

SonarQube其实很早之前就被我刀了,一直没有机会放出来,理论上能干整个 8.9.x LTS,具体版本是enterprise.

说实在的,看雪真是好地方啊,今天burp破解秒审核通过,那这个我也发了把,具体思路不大记得了,反正也是挺痛苦的过程,等我有时间再补把.

原版 SonarQube Enterprise Edition 8.9.8 LTS下载地址

用法很简单,直接加个javaagent到sonarqube-xxxx/conf/sonar.properties里面,注意web跟ce两个地方都要加

License编码方式
请保留换行,然后整体base64即可

补个图把

image

image

老规矩,不混淆,不加密,有兴趣的自己拆来看.

上传的附件

SonarQubeAgent-1.1-SNAPSHOT.jar

SonarQubeAgent-1.2-SNAPSHOT.jar

SonarQubeAgent-1.2-src.zip