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

【爬虫】网站反debugger、内存爆破以及网站限制开发者工具

【爬虫】网站反debugger、内存爆破以及网站限制开发者工具

本文转自 NPE~ 并作补充

常见情形

目前网站反爬手段有很多,比如:网站反debugger、内存爆破、限制开发者工具等

情况一:debugger(右键不在此停止)

问题: 有部分网站做了反debugger处理,当我们打开开发者工具的时候会直接断点停在某个位置。

image

  • 解决办法:右键点击,选择永不在此停止。然后放过断点,即可继续调试。

前提:该debugger构造函数需要没有内容。如果网站开发者自定义的debugger构造函数后面有内容,是在写入数据的话(不断写入空列表、其他字符等),我们跳过断点会导致持续写入,导致内存溢出,页面卡死。

image

情况二:内存爆破

绝大多数网站反debugger会更加高深,会使用到内存爆破以及混淆技术。导致我们通过简单的右键不在此停止无法破解。

我们使用右键不在此停止,并且跳过断点后,会导致浏览器卡死。

情况三:右键被管理员禁用

部分网站会直接限制我们使用开发者工具,我们右键或者F12打开均无效,都被禁用。

我们想右键,打开开发者工具时,发现被禁用。

image

情况四:监测函数执行时间

image

我们通过快捷键强制打开开发者工具,发现页面提示非法调试。

image

image

最终发现页面是通过判断当前window大小以及函数运行时间来确认是否存在非法调试。

解决办法

方法一:控制台-右键不再此停止

如果我们打开开发者工具后,发现自动进入断点。

  1. 首先尝试,鼠标右击永不在此停止
  2. 放过该断点,即可继续调试

方法二:本地注入JS,覆盖之前老的JS

如果方法一无效:放过断点后会导致浏览器页面卡死。即可使用本地注入JS方法,将debugger构造器置空,覆盖之前的JS。

  • 分析浏览器卡死原因:网站开发者自定义的debugger构造器不为空,在持续写入数据。
  • 本地注入JS不能刷新网站,否则会导致我们本地注入的JS失效。

分析原因:浏览器卡死原因

我们单步执行断点,发现进入了VM虚拟环境,并且该JS是进行了混淆的。

image

下面这种有特殊字符+数字+字母的,基本就是进行过JS混淆的:

image

对于这种混淆过的JS代码,我们需要对其进行还原:

还原方法:复制JS代码,然后在控制台执行即可

1
2
//我们需要进行分段还原,否则一次性全部执行,会报not a function
[s(0, -259, -213, 0, "I#ue") + f(1271, 974, 1135, "e!3a") + "r"](r[f(1221, 1495, 1373, "v&9u")](r[g(1467, 0, 0, "&UOm")], r[n(0, "ujyL", -6)]))[s(0, 13, 12, 0, "7Iko")](r[g(1540, 0, 0, "nX(R")]);

image

还原后JS代码:‘constructor’ apply stateObject => 可以推测出,该自定义构造函数在初始化时,还做了加载某个对象的操作。及时我们右键点击了不再此停止,放过断点,但是依然会有源源不断的对象进行加载,最后导致浏览器卡死。

解决办法:本地注入JS

我们已经定位到了浏览器卡死是因为自定义的debugger构造器不断注入对象导致,那么我们就可以本地执行代码,替换该JS片段,让debugger构造器返回空,无法实现注入对象。

  1. 新建代码片段

image

1
2
3
4
5
6
7
8
9
10
// 将debugger构造函数替换置空,防止内存爆破
// 1. after_debugger_handle 接收我们的构造器
// 2. 判断构造器如果构造了一个debugger的东西,我们就将其置空
after_debugger_handle = Function.prototype.constructor;
Function.prototype.constructor = function(a){
if (a == "debugger") {
return function(){};
}
return after_debugger_handle(a);
};
  1. 点击下方的执行按钮,执行代码片段

image

控制台未报错,表明注入成功,此时我们放过断点,发现浏览器不再卡死,即可继续调试。

注意:

  1. 注入后不能刷新页面,否则页面重新加载会导致之前的注入失效。

image

  1. 注入需要等网页数据全部加载完成后再进行,否则可能会报注入失败,JS函数找不到。

拓展:JS混淆(对网页的JS代码进行处理加密)

概念

网站开发者为了防止我们对网站进行调试或者逆向分析,会对JS代码进行处理、保护。

  • 实际就是对JS代码进行编码、加密处理等。

JS压缩混淆:删除无用空白、缩短变量名

JavaScript 压缩混淆主要通过删除无用的空白字符、注释、缩短变量名等方式减小代码体积。压缩混淆不仅可以减少文件大小,还能在一定程度上增加代码阅读难度。

OB混淆:插入不透明谓词(函数逻辑)

OB 混淆(Opaque Predicate Obfuscation)是一种复杂的混淆技术,通过插入不透明谓词来掩盖代码的真实逻辑,使逆向工程师难以理解代码的实际功能。

原始代码:

1
2
3
if (x > 10) {
console.log("x is greater than 10");
}

OB混淆后:

1
2
3
4
5
6
function isTrue() {
return Math.random() > 0.5; // 不透明谓词
}
if (isTrue() || x > 10) {
console.log("x is greater than 10");
}

在这个示例中,isTrue 函数的返回值是随机的,不透明谓词使得控制流变得更加难以预测。逆向工程师必须理解 isTrue 函数的实现才能准确分析代码逻辑。

变量混淆:重命名函数方法,改为a、b、c等

变量混淆通过重命名变量和函数名来增加代码的阅读难度,使得代码更难以理解。混淆后的变量名通常是无意义的短字符,如 a、b、c 等。

字符串混淆:对字符串进行编码和转换

字符串混淆通过对字符串进行编码和转换,使得字符串的真实内容难以直接查看。常用的字符串混淆技术包括 Base64 编码和字符替换。

属性加密:对部分字段,如:用户名、年龄等进行加密

属性加密通过对对象属性进行加密,保护对象的内部数据。常用的加密方法包括简单的 XOR 操作和更复杂的加密算法。

控制流平坦化:引入虚拟机+状态机,加大代码逻辑复杂度

控制流平坦化通过重构代码的控制流,使得代码逻辑更加复杂和难以理解。平坦化技术常用于保护程序的执行流程。控制流平坦化通过引入虚拟机和状态机来重构代码的控制流。

案例:原始的条件语句被转换为一个状态机,控制流被重构成一系列状态和转换。这种方法使得代码的控制流更加复杂,增加了理解和分析的难度。

原始代码:

1
2
3
4
5
if (x > 10) {
console.log("x is greater than 10");
} else {
console.log("x is 10 or less");
}

控制流平坦化处理后代码:

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
const states = [0, 1];
let state = 0;

function execute() {
switch (state) {
case 0:
if (x > 10) {
state = 2;
return;
} else {
state = 3;
return;
}
case 1:
console.log("x is greater than 10");
state = 4;
return;
case 2:
console.log("x is 10 or less");
state = 4;
return;
case 4:
// end state
return;
}
}

while (state !== 4) {
execute();
}

案例

可以看到下方对有一串字母以及数字,这种情况一般就是JS混淆,让我们无法知晓他JS源代码是什么样子。

image

解决办法:

  • 如果该网站使用的是开源的JS混淆代码,我们可以通过工具进行还原。
  • 如果网站使用的是自定义的混淆逻辑,我们只有手动通过控制台进行处理还原(直接复制混淆代码,然后放入控制台,回车即可进行还原。)

image

参考文章

https://blog.csdn.net/weixin_52392194/article/details/141159872

lspatch及其类似物使用教程

lspatch及其类似物使用教程

本文转自 Chen 并作补充

首先我们要了解lspatch是什么

lspatch是一款基于Android的免root框架,由LSPosed框架的开发者推出。它允许用户在不解锁Bootloader(简称bl锁)或获取Root权限的情况下,将Xposed模块内置到App中,从而实现在Android设备上添加新功能、修改系统设置或改变系统外观等个性化操作。

lspatch兼容大部分Android设备,特别是支持Android 9及其以上版本。它采用从应用内部修改的方案,而传统的Xposed方案则是从外部借助root权限修改。

特点与优势

lspatch解决了非ROOT设备无法使用模块的痛点,无需解锁BL或获取Root权限,即可使用Xposed模块。它提供了与原版Xposed相同的API,使用YAHFA(或SandHook)进行hook,保证了功能的稳定性和兼容性。lspatch的使用相对简单,即使对于手机操作新手来说,也能轻松上手。

缺陷与不足

由于lspatch实现Xposed功能是基于修改应用安装包实现的,因此,在安装包出现改动后,安装包的签名会发生变化。这会导致一些对签名验证非常严格的应用无法识别到修补后的应用,会对应用本身的使用体验造成极大的影响(例如提示签名与开放平台不一致,导致无法调用微信,对于没有root的机器来说无解)。应用也无法通过应用商店正常更新,无论是更新Xposed模块(ps:本地模式不用)还是更新应用版本,都需要到lspatch内对新版安装包重新修补。

此外,并不是所有的应用都能够进行修补,例如一些被企业数字加固过的安装包在修补过后会出现闪退等现象。对于不同的修补方式,不同的应用也会存在一些兼容性上的问题,导致某些模块无法正常工作或产生不可预期的行为,存在一定的局限性。

最后,lspatch只能使用作用域是应用本身的模块,一些作用域是系统本身的模块是无法使用的,因此玩机资源相较于LSPosed会少很多,部分开发者也对免root框架感到不满(出于防止倒卖以及开发考虑的目的),可能会在功能使用上进行较大的限制。

修补方式的区别

本地模式:模块作用域可以动态更改,用户可以随时更改生效的模块。在仅更新模块时不需要再走一遍修补流程,直接升级模块即可(更新完模块记得重启一下应用)(更新应用依然要重新修补)。但经修补的应用需要lspatch管理器保持后台运行才能正常启动。这意味着用户需要始终确保lspatch在后台运行,否则修补后的应用会出现闪退等情况,无法正常工作。

便携模式:经修补的应用可以在没有管理器的情况下运行(可以不用把lspatch锁后台),修补后的成品安装包也可以直接分享出去,接收者无需进行任何操作就可以使用(网上各种定制包的由来)。但Xposed作用域不能动态管理配置。无论是更新模块还是更新应用都要到lspatch内重新走一遍修补流程。这限制了用户在使用过程中的灵活性和定制性。在目前的大环境下,一些模块并不支持便携/内置模式(被开发者抵制),功能限制更多。

在签名一致的情况下,本地模式可以与便携模式互相转化。

目前主流的版本

lspatch:原版,由由LSPosed框架的开发者推出,现已归档停更。快捷安装功能依赖shizuku。

npatch:lspatch的改版,有第三方作者对其进行维护,与原版区别不是很大,但不大好用。

opatch:lspatch的魔改版本,对原版进行了优化,解决了原版lspatch需要锁后台以保证前台应用正常运行的缺陷(无需锁后台),且脱离了对shizuku的依赖,是目前免root框架最常用的版本。唯一的缺点是启动opatch时会有“原神”的启动动画,对于一些反感原神的用户不太友好。

onpatch:opatch的修改版本,在保留opatch的所有功能特性的基础上,仅去除了“原神”的启动动画,对一些内容也进行了微调。

实机演示

以下演示版本为onpatch,演示应用为微博,Xposed模块为微博猪手

image

onpatch主界面

image

onpatch设置页面(详细注入日志可以关掉)

image

onpatch管理页(应用)

在授权读取应用列表后就可以看到我们目前能被lsp识别到的应用

image

onpatch管理页(模块)

在这里可以看到我们设备上已经安装的模块

image

我们在应用管理页点击右下角的加号,在“选择存储目录”中点击“确定”。

这一步是用来确认我们修补之后的应用安装包会保存在系统的哪个位置

我们在文件管理器中选择一个用于存放修补后安装包的文件夹

image

再次回到应用管理页,点击右下角的加号

如果你的设备还没有安装这个应用,或者是打算更新已修补的应用,就选择第一个选项,在手机存储目录里找到你要使用的安装包。

如果你的设备已经安装了这个应用的原版(注意不是修补版本,因为不能二次修补),那么则选择第二个选项,在提供的应用列表里选择这个应用即可。

image

image

进入此页面后,我们可以调整修补设置。例如“注入文件提供者”推荐打开(配合MT管理器使用),“输出日志到目录”推荐关闭(如果没有反馈需求的话),覆写版本号按需打开(因为部分应用和模块对版本号有强制要求,除非有降级需求不然一般不开,开了之后应用商店会一直提示更新容易逼死强迫症)

本地模式与便携模式的区别在上文有说

image

本地模式下直接点击“开始注入”,此时会输出一个签名不一样的安装包

image

如图,如果我们一开始已经安装了原版应用,就需要卸载原版应用重新安装修补后的安装包。注意备份重要数据。

(如果有核心破解可以忽略,不过都核心破解了谁还用patch)

image

我们回到应用管理页面,可以看到多了一个应用(显示为“本地加载器模式”,“7”代表修补时lspatch的版本,如果后续lspatch更新的话会出现“优化”选项,点击“优化”就可以同步lspatch的版本),点击刚刚安装的应用,选择“模块作用域”

image

在弹出的模块页面里勾选我们需要使用的Xposed模块,勾选后点击右下角的“✔”

image

此时我们在应用设置页面强制停止这个应用,并清理应用缓存(防止出现兼容性问题导致闪退)。完成后进入该应用的设置页面,可以看到模块已成功生效。(一般模块的入口都会在设置页)

image

如果你选择的是便携模式(内置模式),那么点击“嵌入模块”

image

如果你的模块没有安装,或者想直接打包更高版本的模块,就选择第一个,找到你需要嵌入的Xposed模块安装包

如果你已经安装了模块,那么就选择第二个,在弹出的模块列表里勾选你需要注入的模块,勾选后点击右下角的“✔”,点击“开始注入”

image

安装后就可以看到刚刚安装的应用显示的是“内置模式”,不可对其进行本地模式的操作

内容大致就是这些,上文涉及到的 lsp 加载器以及模块可以直接在网上搜,绝大部分都能在爱玩机工具箱、酷安、GitHub 等平台上找到。

简单提供一些下载链接

lsp加载器下载链接

爱玩机工具箱

酷安

希望各位能养成爱动手,善查询,会提问的好习惯!

image

什么是 UPnP?这就是为什么您应该在路由器上禁用它的原因

什么是 UPnP?这就是为什么您应该在路由器上禁用它的原因

本文转自 Windows社区 并作补充

如果您仔细查看过路由器的设置,您可能会发现一种名为“UPnP”的东西。虽然 UPnP 背后的技术旨在让您的生活变得更加方便,但网络犯罪分子可以利用它来攻击您的设备。那么,让我们探讨一下什么是 UPnP 以及为什么应该禁用它。

什么是 UPnP?

UPnP 代表“通用即插即用”。就其本身而言,它不是恶意服务——它的发明是为了让您的生活更轻松。

UPnP 允许本地网络上通过路由器连接的设备相互查找。例如,如果您购买了一台通过 Wi-Fi 运行的全新打印机,您将希望您的设备(例如计算机和手机)能够“看到”它并向其发送打印作业。

如果没有 UPnP,您需要通过其 IP 地址手动告知每个设备您的打印机在网络上的位置。但是,UPnP 允许打印机向所有其他设备广播其存在,以便它们可以“看到”它并使用它进行打印。此外,您的设备会自动处理端口和通信,从而允许最少的用户交互来进行设置。

为什么 UPnP 存在安全风险?

不幸的是,虽然 UPnP 使您的设备更容易找到彼此,但它也为恶意软件和不良行为者访问您的网络打开了大门。

例如,采用专为远程访问而设计的室内摄像机。如果该摄像头的安全性很差,并且允许外部任何人使用 WAN 上的 UPnP(广域网 - 进入您家的互联网)访问它,则黑客可能会跳入并监视内部发生的情况。如果他们知道摄像头中的房子在哪里,他们就可以利用这些信息来了解房主何时外出并实施入室盗窃。或者只是观察您的日常活动。

此外,如果网络上的设备感染了恶意软件,病毒可以检查它是否可以跳转到网络上的其他设备。如果启用了 UPnP,恶意软件可以使用这些开放通道跳转到更多计算机并在您的本地网络中传播。

通过 UPnP 进行攻击有多现实?

这听起来可能很可怕,但您遇到 UPnP 攻击的可能性有多大?

如果您的路由器性能良好,它不会支持 WAN 上的 UPnP,这就排除了黑客使用该技术进行远程攻击的可能性。您更容易受到 LAN(局域网 - 您家中的本地网络)的攻击,其中一台设备被感染并在整个网络中传播。

但是,如果您确保设备免受恶意软件的侵害、安全地浏览并安装最好的防病毒程序之一,那么您很有可能相信您的设备不会传播病毒。如果您想确定,可以在路由器上禁用 UPnP。

如果禁用 UPnP 会发生什么?

如果禁用 UPnP,您的路由器将不再自动管理连接到路由器的每个设备的端口。这意味着您需要手动端口转发才能让它们相互通信。

因此,您需要做出决定。您是否更喜欢 UPnP 的便利性,它可以让您轻松地将设备连接到 LAN?或者您是否担心有人利用这些渠道造成损害并窃取数据?如果您喜欢方便,请坚持使用 UPnP 并确保您的设备安全;如果您更喜欢安全性,请手动处理端口转发,这样它们就不会被利用。

如何禁用 UPnP?

如果您决定取消 UPnP,则需要访问路由器。您会经常这样做,因为每次需要转发新端口时(即将新设备连接到网络时),您都需要重新访问它。

我们在保护路由器安全的简单提示中介绍了禁用 UPnP,因此如果您想最大限度地提高路由器的安全性,请务必检查一下。

UPnP 是一项有用的功能,但网络犯罪分子可以利用它。虽然您可以禁用它并执行手动端口转发,但由于良好的浏览习惯和可靠的安全性,有些人可能永远不会遇到 UPnP 的攻击。因此,在决定是否启用 UPnP 时,值得权衡这两个论点。

常见高危端口

常见高危端口

本文转自 blacksunny 并作补充

端口 服务 渗透测试
tcp 20,21 FTP(文件传输协议) 允许匿名的上传下载,爆破,嗅探,win提权,远程执行(proftpd 1.3.5),各类后门(proftpd,vsftp 2.3.4)
tcp 22 SSH (安全外壳协议 ) 可根据已搜集到的信息尝试爆破,v1版本可中间人,ssh隧道及内网代理转发,文件传输等等
tcp 23 Telnet ( 远程终端协议) 爆破,嗅探,一般常用于路由,交换登陆,可尝试弱口令
tcp 25 SMTP(简单邮件传输协议) 邮件伪造,vrfy/expn查询邮件用户信息,可使用smtp-user-enum工具来自动跑
tcp/udp 53 DNS(域名系统) 允许区域传送,dns劫持,缓存投毒,欺骗以及各种基于dns隧道的远控
tcp/udp 69 TFTP (简单文件传送协议 ) 尝试下载目标及其的各类重要配置文件
tcp 80-89,443,8440-8450,8080-8089 各种常用的Web服务端口 可尝试经典的topn,vpn,owa,webmail,目标oa,各类Java控制台,各类服务器Web管理面板,各类Web中间件漏洞利用,各类Web框架漏洞利用等等……
tcp 110 POP3(邮局协议版本3 ) 可尝试爆破,嗅探
tcp 111,2049 NFS(网络文件系统) 权限配置不当
tcp 137,139,445 SMB(NETBIOS协议) 可尝试爆破以及smb自身的各种远程执行类漏洞利用,如,ms08-067,ms17-010,嗅探等……
tcp 143 IMAP(邮件访问协议) 可尝试爆破
udp 161 SNMP(简单网络管理协议) 爆破默认团队字符串,搜集目标内网信息
tcp 389 LDAP( 轻量目录访问协议 ) ldap注入,允许匿名访问,弱口令
tcp 512,513,514 Linux rexec (远程登录) 可爆破,rlogin登陆
tcp 873 Rsync (数据镜像备份工具) 匿名访问,文件上传
tcp 1194 OpenVPN(虚拟专用通道) 想办法钓VPN账号,进内网
tcp 1352 Lotus(Lotus软件) 弱口令,信息泄漏,爆破
tcp 1433 SQL Server(数据库管理系统) 注入,提权,sa弱口令,爆破
tcp 1521 Oracle(甲骨文数据库) tns爆破,注入,弹shell…
tcp 1500 ISPmanager( 主机控制面板) 弱口令
tcp 1723 PPTP(点对点隧道协议 ) 爆破,想办法钓VPN账号,进内网
tcp 2082,2083 cPanel (虚拟机控制系统 ) 弱口令
tcp 2181 ZooKeeper(分布式系统的可靠协调系统 ) 未授权访问
tcp 2601,2604 Zebra (zebra路由) 默认密码zerbra
tcp 3128 Squid (代理缓存服务器) 弱口令
tcp 3312,3311 kangle(web服务器) 弱口令
tcp 3306 MySQL(数据库) 注入,提权,爆破
tcp 3389 Windows rdp(桌面协议) shift后门[需要03以下的系统],爆破,ms12-020
tcp 3690 SVN(开放源代码的版本控制系统) svn泄露,未授权访问
tcp 4848 GlassFish(应用服务器) 弱口令
tcp 5000 Sybase/DB2(数据库) 爆破,注入
tcp 5432 PostgreSQL(数据库) 爆破,注入,弱口令
tcp 5900,5901,5902 VNC(虚拟网络控制台,远控) 弱口令爆破
tcp 5984 CouchDB(数据库) 未授权导致的任意指令执行
tcp 6379 Redis(数据库) 可尝试未授权访问,弱口令爆破
tcp 7001,7002 WebLogic(WEB应用系统) Java反序列化,弱口令
tcp 7778 Kloxo(虚拟主机管理系统) 主机面板登录
tcp 8000 Ajenti(Linux服务器管理面板) 弱口令
tcp 8443 Plesk(虚拟主机管理面板) 弱口令
tcp 8069 Zabbix (系统网络监视) 远程执行,SQL注入
tcp 8080-8089 Jenkins,JBoss (应用服务器) 反序列化,控制台弱口令
tcp 9080-9081,9090 WebSphere(应用服务器) Java反序列化/弱口令
tcp 9200,9300 ElasticSearch (Lucene的搜索服务器) 远程执行
tcp 11211 Memcached(缓存系统) 未授权访问
tcp 27017,27018 MongoDB(数据库) 爆破,未授权访问
TCP 50000tcp 50070,50030 SAP Managenment ConsoleHadoop(分布式文件系统) 远程执行默认端口未授权访问

22端口渗透剖析

SSH 是协议,通常使用 OpenSSH 软件实现协议应用。SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定;SSH 为建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其它网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。

1
2
3
4
(1)弱口令,可使用工具hydra,msf中的ssh爆破模块。
(2)防火墙SSH后门。(https://www.secpulse.com/archives/69093.html)
(3)28退格 OpenSSL
(4)openssh 用户枚举 CVE-2018-15473。(https://www.anquanke.com/post/id/157607)

23端口渗透剖析

telnet是一种旧的远程管理方式,使用telnet工具登录系统过程中,网络上传输的用户和密码都是以明文方式传送的,黑客可使用嗅探技术截获到此类密码。

1
2
(1)暴力破解技术是常用的技术,使用hydra,或者msf中telnet模块对其进行破解。
(2)在linux系统中一般采用SSH进行远程访问,传输的敏感数据都是经过加密的。而对于windows下的telnet来说是脆弱的,因为默认没有经过任何加密就在网络中进行传输。使用cain等嗅探工具可轻松截获远程登录密码。

25/465端口渗透剖析

smtp:邮件协议,在linux中默认开启这个服务,可以向对方发送钓鱼邮件

1
2
3
默认端口:25(smtp)、465(smtps)
(1)爆破:弱口令
(2)未授权访问

53端口渗透剖析

53端口是DNS域名服务器的通信端口,通常用于域名解析。也是网络中非常关键的服务器之一。这类服务器容易受到攻击。对于此端口的渗透,一般有三种方式。

1
2
3
(1)使用DNS远程溢出漏洞直接对其主机进行溢出攻击,成功后可直接获得系统权限。(https://www.seebug.org/vuldb/ssvid-96718)
(2)使用DNS欺骗攻击,可对DNS域名服务器进行欺骗,如果黑客再配合网页木马进行挂马攻击,无疑是一种杀伤力很强的攻击,黑客可不费吹灰之力就控制内网的大部分主机。这也是内网渗透惯用的技法之一。(https://baijiahao.baidu.com/s?id=1577362432987749706&wfr=spider&for=pc)
(3)拒绝服务攻击,利用拒绝服务攻击可快速的导致目标服务器运行缓慢,甚至网络瘫痪。如果使用拒绝服务攻击其DNS服务器。将导致用该服务器进行域名解析的用户无法正常上网。(http://www.edu.cn/xxh/fei/zxz/201503/t20150305_1235269.shtml)(4)DNS劫持。(https://blog.csdn.net/qq_32447301/article/details/77542474)

80端口渗透剖析

80端口通常提供web服务。目前黑客对80端口的攻击典型是采用SQL注入的攻击方法,脚本渗透技术也是一项综合性极高的web渗透技术,同时脚本渗透技术对80端口也构成严重的威胁。

1
2
3
4
5
6
7
(1)对于windows2000的IIS5.0版本,黑客使用远程溢出直接对远程主机进行溢出攻击,成功后直接获得系统权限。
(2)对于windows2000中IIS5.0版本,黑客也尝试利用‘Microsoft IISCGI’文件名错误解码漏洞攻击。使用X-SCAN可直接探测到IIS漏洞。
(3)IIS写权限漏洞是由于IIS配置不当造成的安全问题,攻击者可向存在此类漏洞的服务器上传恶意代码,比如上传脚本木马扩大控制权限。
(4)普通的http封包是没有经过加密就在网络中传输的,这样就可通过嗅探类工具截取到敏感的数据。如使用Cain工具完成此类渗透。
(5)80端口的攻击,更多的是采用脚本渗透技术,利用web应用程序的漏洞进行渗透是目前很流行的攻击方式。
(6)对于渗透只开放80端口的服务器来说,难度很大。利用端口复用工具可解决此类技术难题。
(7)CC攻击效果不及DDOS效果明显,但是对于攻击一些小型web站点还是比较有用的。CC攻击可使目标站点运行缓慢,页面无法打开,有时还会爆出web程序的绝对路径。

135端口渗透剖析

135端口主要用于使用RPC协议并提供DCOM服务,通过RPC可以保证在一台计算机上运行的程序可以顺利地执行远程计算机上的代码;使用DCOM可以通过网络直接进行通信,能够跨包括HTTP协议在内的多种网络传输。同时这个端口也爆出过不少漏洞,最严重的就是缓冲区溢出漏洞,曾经疯狂一时的‘冲击波’病毒就是利用这个漏洞进行传播的。对于135端口的渗透,黑客的渗透方法为:

1
2
(1)查找存在RPC溢出的主机,进行远程溢出攻击,直接获得系统权限。如用‘DSScan’扫描存在此漏洞的主机。对存在漏洞的主机可使用‘ms05011.exe’进行溢出,溢出成功后获得系统权限。(https://wenku.baidu.com/view/68b3340c79563c1ec5da710a.html)
(2)扫描存在弱口令的135主机,利用RPC远程过程调用开启telnet服务并登录telnet执行系统命令。系统弱口令的扫描一般使用hydra。对于telnet服务的开启可使用工具kali链接。(https://wenku.baidu.com/view/c8b96ae2700abb68a982fbdf.html)

139/445端口渗透剖析

139端口是为‘NetBIOS SessionService’提供的,主要用于提供windows文件和打印机共享以及UNIX中的Samba服务。445端口也用于提供windows文件和打印机共享,在内网环境中使用的很广泛。这两个端口同样属于重点攻击对象,139/445端口曾出现过许多严重级别的漏洞。下面剖析渗透此类端口的基本思路。

1
2
3
4
(1)对于开放139/445端口的主机,一般尝试利用溢出漏洞对远程主机进行溢出攻击,成功后直接获得系统权限。利用msf的ms-017永恒之蓝。(https://blog.csdn.net/qq_41880069/article/details/82908131)
(2)对于攻击只开放445端口的主机,黑客一般使用工具‘MS06040’或‘MS08067’.可使用专用的445端口扫描器进行扫描。NS08067溢出工具对windows2003系统的溢出十分有效,工具基本使用参数在cmd下会有提示。(https://blog.csdn.net/god_7z1/article/details/6773652)
(3)对于开放139/445端口的主机,黑客一般使用IPC$进行渗透。在没有使用特点的账户和密码进行空连接时,权限是最小的。获得系统特定账户和密码成为提升权限的关键了,比如获得administrator账户的口令。(https://blog.warhut.cn/dmbj/145.html)
(4)对于开放139/445端口的主机,可利用共享获取敏感信息,这也是内网渗透中收集信息的基本途径。

1433端口渗透剖析

1433是SQLServer默认的端口,SQL Server服务使用两个端口:tcp-1433、UDP-1434.其中1433用于供SQLServer对外提供服务,1434用于向请求者返回SQLServer使用了哪些TCP/IP端口。1433端口通常遭到黑客的攻击,而且攻击的方式层出不穷。最严重的莫过于远程溢出漏洞了,如由于SQL注射攻击的兴起,各类数据库时刻面临着安全威胁。利用SQL注射技术对数据库进行渗透是目前比较流行的攻击方式,此类技术属于脚本渗透技术。

1
2
3
4
(1)对于开放1433端口的SQL Server2000的数据库服务器,黑客尝试使用远程溢出漏洞对主机进行溢出测试,成功后直接获得系统权限。(https://blog.csdn.net/gxj022/article/details/4593015)
(2)暴力破解技术是一项经典的技术。一般破解的对象都是SA用户。通过字典破解的方式很快破解出SA的密码。(https://blog.csdn.net/kali_linux/article/details/50499576)
(3)嗅探技术同样能嗅探到SQL Server的登录密码。
(4)由于脚本程序编写的不严密,例如,程序员对参数过滤不严等,这都会造成严重的注射漏洞。通过SQL注射可间接性的对数据库服务器进行渗透,通过调用一些存储过程执行系统命令。可以使用SQL综合利用工具完成。

1521端口渗透剖析

1521是大型数据库Oracle的默认监听端口,估计新手还对此端口比较陌生,平时大家接触的比较多的是Access,MSSQL以及MYSQL这三种数据库。一般大型站点才会部署这种比较昂贵的数据库系统。对于渗透这种比较复杂的数据库系统,黑客的思路如下:

1
2
3
(1)Oracle拥有非常多的默认用户名和密码,为了获得数据库系统的访问权限,破解数据库系统用户以及密码是黑客必须攻破的一道安全防线。
(2)SQL注射同样对Oracle十分有效,通过注射可获得数据库的敏感信息,包括管理员密码等。
(3)在注入点直接创建java,执行系统命令。(4)https://www.leiphone.com/news/201711/JjzXFp46zEPMvJod.html

2049端口渗透剖析

NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源。在NFS的应用中,本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件,就像访问本地文件一样。如今NFS具备了防止被利用导出文件夹的功能,但遗留系统中的NFS服务配置不当,则仍可能遭到恶意攻击者的利用。

1
未授权访问。(https://www.freebuf.com/articles/network/159468.html) (http://www.secist.com/archives/6192.htm)

3306端口渗透剖析

3306是MYSQL数据库默认的监听端口,通常部署在中型web系统中。在国内LAMP的配置是非常流行的,对于php+mysql构架的攻击也是属于比较热门的话题。mysql数据库允许用户使用自定义函数功能,这使得黑客可编写恶意的自定义函数对服务器进行渗透,最后取得服务器最高权限。对于3306端口的渗透,黑客的方法如下:

1
2
3
(1)由于管理者安全意识淡薄,通常管理密码设置过于简单,甚至为空口令。使用破解软件很容易破解此类密码,利用破解的密码登录远程mysql数据库,上传构造的恶意UDF自定义函数代码进行注册,通过调用注册的恶意函数执行系统命令。或者向web目录导出恶意的脚本程序,以控制整个web系统。
(2)功能强大的‘cain’同样支持对3306端口的嗅探,同时嗅探也是渗透思路的一种。
(3)SQL注入同样对mysql数据库威胁巨大,不仅可以获取数据库的敏感信息,还可使用load_file()函数读取系统的敏感配置文件或者从web数据库链接文件中获得root口令等,导出恶意代码到指定路径等。

3389端口渗透剖析

3389是windows远程桌面服务默认监听的端口,管理员通过远程桌面对服务器进行维护,这给管理工作带来的极大的方便。通常此端口也是黑客们较为感兴趣的端口之一,利用它可对远程服务器进行控制,而且不需要另外安装额外的软件,实现方法比较简单。当然这也是系统合法的服务,通常是不会被杀毒软件所查杀的。使用‘输入法漏洞’进行渗透。

1
2
3
4
(1)对于windows2000的旧系统版本,使用‘输入法漏洞’进行渗透。
(2)cain是一款超级的渗透工具,同样支持对3389端口的嗅探。
(3)Shift粘滞键后门:5次shift后门
(4)社会工程学通常是最可怕的攻击技术,如果管理者的一切习惯和规律被黑客摸透的话,那么他管理的网络系统会因为他的弱点被渗透。(5)爆破3389端口。这里还是推荐使用hydra爆破工具。(6)ms12_020死亡蓝屏攻击。(https://www.cnblogs.com/R-Hacker/p/9178066.html)(7)https://www.cnblogs.com/backlion/p/9429738.html

4899端口渗透剖析

4899端口是remoteadministrator远程控制软件默认监听的端口,也就是平时常说的radmini影子。radmini目前支持TCP/IP协议,应用十分广泛,在很多服务器上都会看到该款软件的影子。对于此软件的渗透,思路如下:

1
2
(1)radmini同样存在不少弱口令的主机,通过专用扫描器可探测到此类存在漏洞的主机。
(2)radmini远控的连接密码和端口都是写入到注册表系统中的,通过使用webshell注册表读取功能可读取radmini在注册表的各项键值内容,从而破解加密的密码散列。

5432端口渗透剖析

PostgreSQL是一种特性非常齐全的自由软件的对象–关系型数据库管理系统,可以说是目前世界上最先进,功能最强大的自由数据库管理系统。包括kali系统中msf也使用这个数据库;浅谈postgresql数据库攻击技术 大部分关于它的攻击依旧是sql注入,所以注入才是数据库不变的话题。

1
2
(1)爆破:弱口令:postgres postgres
(2)缓冲区溢出:CVE-2014-2669。(http://drops.xmd5.com/static/drops/tips-6449.html)(3)远程代码执行:CVE-2018-1058。(https://www.secpulse.com/archives/69153.html)

5631端口渗透剖析

5631端口是著名远程控制软件pcanywhere的默认监听端口,同时也是世界领先的远程控制软件。利用此软件,用户可以有效管理计算机并快速解决技术支持问题。由于软件的设计缺陷,使得黑客可随意下载保存连接密码的*.cif文件,通过专用破解软件进行破解。这些操作都必须在拥有一定权限下才可完成,至少通过脚本渗透获得一个webshell。通常这些操作在黑客界被称为pcanywhere提权技术。

1
PcAnyWhere提权。(https://blog.csdn.net/Fly_hps/article/details/80377199)

5900端口渗透剖析

5900端口是优秀远程控制软件VNC的默认监听端口,此软件由著名的AT&T的欧洲研究实验室开发的。VNC是在基于unix和linux操作系统的免费的开放源码软件,远程控制能力强大,高效实用,其性能可以和windows和MAC中的任何一款控制软件媲美。对于该端口的渗透,思路如下:

1
2
3
(1)VNC软件存在密码验证绕过漏洞,此高危漏洞可以使得恶意攻击者不需要密码就可以登录到一个远程系统。
(2)cain同样支持对VNC的嗅探,同时支持端口修改。
(3)VNC的配置信息同样被写入注册表系统中,其中包括连接的密码和端口。利用webshell的注册表读取功能进行读取加密算法,然后破解。(4)VNC拒绝服务攻击(CVE-2015-5239)。(http://blogs.360.cn/post/vnc%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E6%BC%8F%E6%B4%9Ecve-2015-5239%E5%88%86%E6%9E%90.html)(5)VNC权限提升(CVE-2013-6886)。

6379端口渗透剖析

Redis是一个开源的使用c语言写的,支持网络、可基于内存亦可持久化的日志型、key-value数据库。关于这个数据库这两年还是很火的,暴露出来的问题也很多。特别是前段时间暴露的未授权访问。

1
2
(1)爆破:弱口令
(2)未授权访问+配合ssh key提权。(http://www.alloyteam.com/2017/07/12910/)

7001/7002端口渗透剖析

7001/7002通常是weblogic中间件端口

1
2
3
4
5
(1)弱口令、爆破,弱密码一般为weblogic/Oracle@123 or weblogic
(2)管理后台部署 war 后门
(3)SSRF
(4)反序列化漏洞
(5)weblogic_uachttps://github.com/vulhub/vulhub/tree/master/weblogic/ssrfhttps://bbs.pediy.com/thread-224954.htmhttps://fuping.site/2017/06/05/Weblogic-Vulnerability-Verification/https://blog.gdssecurity.com/labs/2015/3/30/weblogic-ssrf-and-xss-cve-2014-4241-cve-2014-4210-cve-2014-4.html

8080端口渗透剖析

8080端口通常是apache_Tomcat服务器默认监听端口,apache是世界使用排名第一的web服务器。国内很多大型系统都是使用apache服务器,对于这种大型服务器的渗透,主要有以下方法:

1
2
3
4
5
6
(1)Tomcat远程代码执行漏洞(https://www.freebuf.com/column/159200.html)
(2)Tomcat任意文件上传。(http://liehu.tass.com.cn/archives/836)
(3)Tomcat远程代码执行&信息泄露。(https://paper.seebug.org/399/)
(4)Jboss远程代码执行。(http://mobile.www.cnblogs.com/Safe3/archive/2010/01/08/1642371.html)
(5)Jboss反序列化漏洞。(https://www.zybuluo.com/websec007/note/838374)
(6)Jboss漏洞利用。(https://blog.csdn.net/u011215939/article/details/79141624)

27017端口渗透剖析

MongoDB,NoSQL数据库;攻击方法与其他数据库类似

1
2
(1)爆破:弱口令
(2)未授权访问;(http://www.cnblogs.com/LittleHann/p/6252421.html)(3)http://www.tiejiang

如何使用Git-Dumper从站点中导出一个Git库

如何使用Git-Dumper从站点中导出一个Git库

本文转自 Alpha_h4ck 并作补充

关于Git-Dumper

Git-Dumper是一款功能强大的代码导出工具,在该工具的帮助下,广大研究人员可以轻松从一个网站中导出目标Git库,并存储到本地设备中进行分析和研究。

工具运行机制

该工具首先会检测提供的目录列表是否可用,如果可用,该工具将会以递归的方式下载目标站点中所有的.git目录(该功能与使用wget效果相同)。

如果目录列表不可用,那么该工具将使用多种方法来尽可能地查找更多的文件,具体操作步骤如下:

1、获取所有的常见文件,例如.gitignore、.git/HEAD和.git/index等;

2、通过分析.git/HEAD、.git/logs/HEAD、.git/config和.git/packed-refs等文件来查找尽可能多的refs,例如refs/heads/master和refs/remotes/origin/HEAD;

3、通过分析.git/packed-refs、.git/index、.git/refs/*和.git/logs/*来寻找尽可能多的对象(sha1);

4、递归获取所有的对象,并分析每一个commit来查找父组件;

5、运行“git checkout .”命令来恢复当前工作树;

工具依赖

本项目基于Python 开发,因此广大研究人员首先需要在本地设备上安装并配置好Python环境。

工具下载

GitHub安装

广大研究人员可以使用下列命令将该项目源码克隆至本地:

1
git clone https://github.com/arthaud/git-dumper.git

pip安装

我们还可以使用pip来直接安装Git-Dumper:

1
pip install git-dumper

源码构建

下载好Git-Dumper之后,可以使用pip命令来安装工具依赖组件:

1
pip install -r requirements.txt

接下来,直接运行下列命令即可:

1
./git_dumper.py http://website.com/.git ~/website

工具帮助信息

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
usage: git-dumper [options] URL DIR

Dump a git repository from a website.

positional arguments:

URL url

DIR output directory

optional arguments:

-h, --help show this help message and exit

--proxy PROXY use the specified proxy

-j JOBS, --jobs JOBS number of simultaneous requests

-r RETRY, --retry RETRY

number of request attempts before giving up

-t TIMEOUT, --timeout TIMEOUT

maximum time in seconds before giving up

-u USER_AGENT, --user-agent USER_AGENT

user-agent to use for requests

-H HEADER, --header HEADER

additional http headers, e.g `NAME=VALUE`

命令解释

-h, –help:显示工具帮助信息和退出;

–proxy PROXY:设置使用指定的代理;

-j JOBS, –jobs JOBS:设置同时发送的请求数量;

-r RETRY, –retry RETRY:设置请求发送尝试的最大次数;

-t TIMEOUT, –timeout TIMEOUT:设置最大超时时间,单位为秒;

-u USER_AGENT, –user-agent USER_AGENT:设置用于发送请求的用户代理;

-H HEADER, –header HEADER:设置需要添加的额外HTTP Header;

工具使用样例

下列命令可以从目标站点直接导出Git库:

1
git-dumper http://website.com/.git ~/website

项目地址

Git-Dumper:GitHub传送门

gitleaks 扫描git存储库文件和目录中的敏感信息

gitleaks 扫描git存储库文件和目录中的敏感信息

本文转自 雨苁 并作补充

Gitleaks简介

Gitleaks 是一款 SAST 工具,用于检测防止git repos 中的密码、API 密钥和令牌等硬编码机密。Gitleaks 是一款易于使用的一体化解决方案,用于检测代码中过去或现在的机密。

Gitleaks 是一款开源秘密扫描器,用于扫描 git 存储库、文件和目录。Gitleaks 拥有超过 1600 万次 docker 下载、1.7 万个 GitHub 星标、900 万次 GitHub 下载、每周数千次克隆和超过 70 万次自制软件安装,是安全专家、企业和开发人员最信赖的开源秘密扫描器。Gitleaks 由 Zach Rice维护。

image

使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
➜  ~/code(master) gitleaks git -v


│╲
│ ○
○ ░
░ gitleaks


Finding: "export BUNDLE_ENTERPRISE__CONTRIBSYS__COM=cafebabe:deadbeef",
Secret: cafebabe:deadbeef
RuleID: sidekiq-secret
Entropy: 2.609850
File: cmd/generate/config/rules/sidekiq.go
Line: 23
Commit: cd5226711335c68be1e720b318b7bc3135a30eb2
Author: John
Email: john@users.noreply.github.com
Date: 2022-08-03T12:31:40Z
Fingerprint: cd5226711335c68be1e720b318b7bc3135a30eb2:cmd/generate/config/rules/sidekiq.go:sidekiq-secret:23

入门

Gitleaks 可以使用 Homebrew、Docker 或 Go 安装。Gitleaks 还提供了适用于许多流行平台和操作系统类型的二进制版本,发布页面上提供。此外,Gitleaks 可以直接在您的存储库中作为预提交钩子实现,也可以使用Gitleaks-Action作为 GitHub 操作实现。

安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# MacOS
brew install gitleaks

# Docker (DockerHub)
docker pull zricethezav/gitleaks:latest
docker run -v ${path_to_host_folder_to_scan}:/path zricethezav/gitleaks:latest [命令] [选项] [源路径]

# Docker (ghcr.io)
docker pull ghcr.io/gitleaks/gitleaks:latest
docker run -v ${path_to_host_folder_to_scan}:/path ghcr.io/gitleaks/gitleaks:latest [命令] [选项] [源路径]

# 从源码安装 (确保已安装 go)
git clone https://github.com/gitleaks/gitleaks.git
cd gitleaks
make build

GitHub action

查看官方Gitleaks GitHub Action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
name: gitleaks
on: [pull_request, push, workflow_dispatch]
jobs:
scan:
name: gitleaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE}} # Only required for Organizations, not personal accounts.

Pre-Commit

  1. 从https://pre-commit.com/#install安装 precommit
  2. .pre-commit-config.yaml在存储库的根目录创建一个包含以下内容的文件:repos: - repo: https://github.com/gitleaks/gitleaks rev: v8.19.0 hooks: - id: gitleaks 用于本机执行 GitLeaks或使用gitleaks-docker预提交 ID通过官方 Docker 镜像执行 GitLeaks
  3. 通过执行自动更新配置到最新的版本pre-commit autoupdate
  4. 安装pre-commit install
  5. 现在您已经一切就绪!
1
2
➜ git commit -m "this commit contains a secret"
Detect hardcoded secrets.................................................Failed

注意:要禁用 gitleaks 预提交钩子,你可以SKIP=gitleaks在提交命令前面添加,这样它就会跳过运行 gitleaks

1
2
➜ SKIP=gitleaks git commit -m "skip gitleaks check"
Detect hardcoded secrets................................................Skipped

用法

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
用法:
gitleaks [命令]

可用命令:
completion 为指定的 shell 生成自动补全脚本
dir 扫描目录或文件中的敏感信息
git 扫描 Git 仓库中的敏感信息
help 查看任意命令的帮助
stdin 从标准输入中检测敏感信息
version 显示 gitleaks 版本

选项:
-b, --baseline-path string 忽略某些问题的基准文件路径
-c, --config string 配置文件路径
优先级顺序:
1. --config/-c
2. 环境变量 GITLEAKS_CONFIG
3. (目标路径)/.gitleaks.toml
如果以上三者都未设置,gitleaks 将使用默认配置
--enable-rule strings 仅启用指定 ID 的规则
--exit-code int 检测到泄露信息时的退出代码(默认值为 1)
-i, --gitleaks-ignore-path string .gitleaksignore 文件或包含此文件的文件夹路径(默认值为 ".")
-h, --help gitleaks 帮助
--ignore-gitleaks-allow 忽略 gitleaks:allow 注释
-l, --log-level string 日志级别(trace, debug, info, warn, error, fatal)(默认 "info")
--max-decode-depth int 允许递归解码的最大深度(默认 "0",不进行解码)
--max-target-megabytes int 跳过大于该大小的文件
--no-banner 禁止显示横幅
--no-color 禁用彩色输出
--redact uint[=100] 在日志和标准输出中隐藏敏感信息。仅隐藏部分敏感信息可以设置百分比,例如 --redact=20(默认隐藏 100%)
-f, --report-format string 输出格式(json, csv, junit, sarif)(默认 "json")
-r, --report-path string 报告文件路径
-v, --verbose 显示扫描的详细输出
--version 显示 gitleaks 的版本信息

使用 "gitleaks [command] --help" 获取有关某个命令的更多信息。

命令

⚠️v8.19.0 引入了一项更改,即弃用了detectprotect。这些命令仍然可用,但隐藏在--help菜单中。查看此要点以轻松进行命令翻译。如果您发现 v8.19.0 破坏了现有命令 ( detect/ protect),请打开问题。

扫描模式有三种:gitdirstdin

Git

git命令允许您扫描本地 git 存储库。在底层,gitleaks 使用命令来扫描补丁。您可以使用选项git log -p配置的行为。例如,如果您想对一系列提交运行 gitleaks,则可以使用以下命令:。有关更多信息,请参阅git log文档。如果没有将目标指定为位置参数,则 gitleaks 将尝试将当前工作目录扫描为 git 存储库。git log -p``log-opts``gitleaks git -v --log-opts="--all commitA..commitB" path_to_repo

目录

dir(别名包括files, )命令directory允许您扫描目录和文件。例如:gitleaks dir -v path_to_directory_or_file。如果没有将目标指定为位置参数,则 gitleaks 将扫描当前工作目录。

标准输入

你也可以用以下命令将数据传输到 gitleaks stdin。例如:cat some_file | gitleaks -v stdin

创建基线

扫描大型存储库或具有较长历史的存储库时,使用基线会很方便。使用基线时,gitleaks 将忽略基线中存在的任何旧发现。基线可以是任何 gitleaks 报告。要创建 gitleaks 报告,请使用参数运行 gitleaks --report-path

1
gitleaks git --report-path gitleaks-report.json # This will save the report in a file called gitleaks-report.json

一旦创建基线,就可以在再次运行检测命令时应用它:

1
gitleaks git --baseline-path gitleaks-report.json --report-path findings.json

使用 –baseline-path 参数运行detect命令后,报告输出(findings.json)将只包含新问题。

预提交钩子

pre-commit.py您可以将示例脚本复制到目录中,以将 Gitleaks 作为预提交钩子运行.git/hooks/

配置

Gitleaks 提供了一种配置格式,您可以按照该格式编写自己的秘密检测规则:

1
# Title for the gitleaks configuration file.title = "Gitleaks title"# Extend the base (this) configuration. When you extend a configuration# the base rules take precedence over the extended rules. I.e., if there are# duplicate rules in both the base configuration and the extended configuration# the base rules will override the extended rules.# Another thing to know with extending configurations is you can chain together# multiple configuration files to a depth of 2. Allowlist arrays are appended# and can contain duplicates.# useDefault and path can NOT be used at the same time. Choose one.[extend]# useDefault will extend the base configuration with the default gitleaks config:# https://github.com/gitleaks/gitleaks/blob/master/config/gitleaks.tomluseDefault = true# or you can supply a path to a configuration. Path is relative to where gitleaks# was invoked, not the location of the base config.path = "common_config.toml"# An array of tables that contain information that define instructions# on how to detect secrets[[rules]]# Unique identifier for this ruleid = "awesome-rule-1"# Short human readable description of the rule.description = "awesome rule 1"# Golang regular expression used to detect secrets. Note Golang's regex engine# does not support lookaheads.regex = '''one-go-style-regex-for-this-rule'''# Int used to extract secret from regex match and used as the group that will have# its entropy checked if `entropy` is set.secretGroup = 3# Float representing the minimum shannon entropy a regex group must have to be considered a secret.entropy = 3.5# Golang regular expression used to match paths. This can be used as a standalone rule or it can be used# in conjunction with a valid `regex` entry.path = '''a-file-path-regex'''# Keywords are used for pre-regex check filtering. Rules that contain# keywords will perform a quick string compare check to make sure the# keyword(s) are in the content being scanned. Ideally these values should# either be part of the identiifer or unique strings specific to the rule's regex# (introduced in v8.6.0)keywords = [  "auth",  "password",  "token",]# Array of strings used for metadata and reporting purposes.tags = ["tag","another tag"]    # ⚠️ In v8.21.0 `[rules.allowlist]` was replaced with `[[rules.allowlists]]`.    # This change was backwards-compatible: instances of `[rules.allowlist]` still  work.      #    # You can define multiple allowlists for a rule to reduce false positives.    # A finding will be ignored if _ANY_ `[[rules.allowlists]]` matches.    [[rules.allowlists]]    description = "ignore commit A"    # When multiple criteria are defined the default condition is "OR".    # e.g., this can match on |commits| OR |paths| OR |stopwords|.    condition = "OR"    commits = [ "commit-A", "commit-B"]    paths = [      '''go\.mod''',      '''go\.sum'''    ]    # note: stopwords targets the extracted secret, not the entire regex match    # like 'regexes' does. (stopwords introduced in 8.8.0)    stopwords = [      '''client''',      '''endpoint''',    ]    [[rules.allowlists]]    # The "AND" condition can be used to make sure all criteria match.    # e.g., this matches if |regexes| AND |paths| are satisfied.    condition = "AND"    # note: |regexes| defaults to check the _Secret_ in the finding.    # Acceptable values for |regexTarget| are "secret" (default), "match", and "line".    regexTarget = "match"    regexes = [ '''(?i)parseur[il]''' ]    paths = [ '''package-lock\.json''' ]# You can extend a particular rule from the default config. e.g., gitlab-pat# if you have defined a custom token prefix on your GitLab instance[[rules]]id = "gitlab-pat"# all the other attributes from the default rule are inherited    [[rules.allowlists]]    regexTarget = "line"    regexes = [ '''MY-glpat-''' ]# This is a global allowlist which has a higher order of precedence than rule-specific allowlists.# If a commit listed in the `commits` field below is encountered then that commit will be skipped and no# secrets will be detected for said commit. The same logic applies for regexes and paths.[allowlist]description = "global allow list"commits = [ "commit-A", "commit-B", "commit-C"]paths = [  '''gitleaks\.toml''',  '''(.*?)(jpg|gif|doc)''']# note: (global) regexTarget defaults to check the _Secret_ in the finding.# if regexTarget is not specified then _Secret_ will be used.# Acceptable values for regexTarget are "match" and "line"regexTarget = "match"regexes = [  '''219-09-9999''',  '''078-05-1120''',  '''(9[0-9]{2}|666)-\d{2}-\d{4}''',]# note: stopwords targets the extracted secret, not the entire regex match# like 'regexes' does. (stopwords introduced in 8.8.0)stopwords = [  '''client''',  '''endpoint''',]

请参阅默认gitleaks 配置以获取示例,或者如果您希望为默认配置做出贡献,请遵循贡献指南。此外,您还可以查看这篇涵盖高级配置设置的gitleaks 博客文章。

附加配置

gitleaks:允许

如果你故意提交 gitleaks 会捕获的测试机密,你可以gitleaks:allow在该行中添加注释,指示 gitleaks 忽略该机密。例如:

1
2
class CustomClass:
discord_client_secret = '8dyfuiRyq=vVc3RRr_edRk-fK__JItpZ' #gitleaks:allow

.gitleaksignore

.gitleaksignore您可以通过在存储库根目录下创建一个文件来忽略特定发现。在版本 v8.10.0 中,GitleaksFingerprint为 Gitleaks 报告添加了一个值。每个泄漏或发现都有一个指纹,可以唯一地标识一个秘密。将此指纹添加到.gitleaksignore文件中以忽略该特定秘密。有关示例,请参阅 Gitleaks 的.gitleaksignore。注意:此功能是实验性的,将来可能会发生变化。

解码

有时秘密的编码方式使得仅使用正则表达式很难找到它们。现在您可以告诉 gitleaks 自动查找和解码编码文本。该标志--max-decode-depth启用此功能(默认值“0”表示默认情况下禁用该功能)。

由于解码的文本也可以包含编码的文本,因此支持递归解码。该标志--max-decode-depth设置递归限制。当没有新的编码文本段需要解码时,递归将停止,因此设置非常高的最大深度并不意味着它会进行那么多遍。它只会进行解码文本所需的次数。总体而言,解码只会稍微增加扫描时间。

编码文本的发现与正常发现有以下不同:

  • 该位置指向编码文本的边界
    • 如果规则在编码文本之外匹配,则边界也会调整以包括该文本
  • 匹配和秘密包含解码的值
  • 添加了两个标签decoded:<encoding>decode-depth:<depth>

目前支持的编码:

  • base64(标准和 base64url)

项目地址

GitHub:
https://github.com/gitleaks/gitleaks

教你怎么实现钉钉蓝牙打卡考勤机的远程打卡

教你怎么实现钉钉蓝牙打卡考勤机的远程打卡

本文转自 小刀 并作补充

许多公司都手机考勤了,规定要在公司的蓝牙考勤机5米内才可以打卡签到,绝大多数是用模拟仿真软件完成的,但手机软件常常由于升级了就不能用,十分不便,因此这儿教各位怎样用USB蓝牙盒子(蓝牙打卡神器)模拟信号打卡,硬件配置可以永久用,而且安卓系统和IOS系统都能够用,也比较简单,新手有一定计算机技术和硬件知识就能完成。

准备

1、计算机(WIN7系统以上,64位)

2、USB蓝牙盒子(必须选购)

3、安卓手机

操作步骤

第一步。下载《23款蓝牙盒子设置工具 V1.0.1》这个软件到电脑,安装好驱动软件再打开软件。

下载链接:https://wwc.lanzouq.com/iKPiD1ay326h

密码:8888

image

第二步。安卓手机下载“nrf”这个APP。手机打开“nrf”,查周边的蓝牙信号。有的公司很有可能周边蓝牙信号比较多,一定要找到考勤机相匹配的那一个信号,假如没法鉴别,就只有一个一个试了。有前提的可以查询机器设备包装盒子,或是设施的反面,都是有MAC地址。

如果是钉钉的蓝牙打卡机,找蓝牙信号带TomTom(如图红框)就是,截图就可以破解。

nrf下载链接:https://wwc.lanzouq.com/iywyH04gn61g

image

第三步。打开《23款蓝牙盒子设置工具 V1.0.1》这个修改器软件,将USB蓝牙盒子插进电脑USB口。显示“已连接”,在软件填好MAC地址和广播一(MAC地址不用填“:”,只填数字和英文字母就可以),最后点“写入配置”就可以。

image

第四步。提示“写入成功”就可以把蓝牙打卡器拔下,可以配合转接头插手机上,用手机给打卡器供电,这时发送出来的蓝牙信号,就和公司的信号彻底一样。手机上只需插着这个打卡器,就象在公司一样打卡签到了。

这个方式如果考勤机器发出的蓝牙广播每天都会变一个参数值就没用了感觉,这篇文章也不是用来参考绕过考勤的,而是用才参考有一个用户能到蓝牙机器前,打开程序获取广播报,发送相关包给到远端,远端可以模拟信号发起请求或直接传参(得到广播发出的 serialData,远端模拟一个客户端请求发送给服务端)

fastjson漏洞是否影响安卓

fastjson漏洞是否影响安卓

本文转自 mb_opmktjff 并作补充

fastjson有一些已知的严重RCE漏洞,例如CVE-2017-18349和CVE-2022-25845。一般其影响范围在服务器端,多为Spring Boot框架的服务,而在安卓的影响却没有搜到任何资料。我们来分析一下,如果一个安卓客户端应用使用了老版本的fastjson库,是否可以被攻击。

在查看fastjson 1.1.53.android的maven网页时,发现其标注了存在已知CVE漏洞。

https://mvnrepository.com/artifact/com.alibaba/fastjson/1.1.53.android

image

查看fastjson的github修复公告,却表示安卓环境不涉及此漏洞(CVE-2017-18349)。除此之外,没有找到更多的fastjson漏洞在安卓上的分析。

https://github.com/alibaba/fastjson/wiki/security_update_20170315

image

尽管fastjson出过好几次RCE的漏洞,但是本质上原理相同,仅仅是安全检查绕过的方法不同,因此我们本文先研究最初被发现的RCE,CVE-2017-18349。

分析思路

经过一些搜索,找到了网上一些关于此漏洞的信息,但是没有找到为什么安卓版本不涉及此漏洞。

我发现fastjson发布的版本号中,除了普通的版本还有安卓版本,后缀为“.android”。安卓版是主要针对安卓环境进行优化,除此之外没有特殊改动。

https://github.com/alibaba/fastjson/wiki/Android%E7%89%88%E6%9C%AC

image

部分fastjson安卓版的差异

以目前的信息,可以得到以下两个猜测:

  • 猜测1:fastjson的安卓版本和普通版本有区别,导致安卓版本不受此漏洞影响。
  • 猜测2:安卓运行环境不同,不受此漏洞影响。

为了分析fastjson在安卓上的影响,我们搭建3个环境。

  • 第一个是已知脆弱的环境,其服务为Spring Boot,尝试复现,然后用于比较。
  • 第二个是类似第一个的环境,但是把fastjson的依赖库版本加上“.android”后缀,以测试安卓版本在Spring Boot中是否脆弱。
  • 第三个环境是正常的安卓客户端应用,使用安卓版本的fastjson,除此之外尽可能模仿第一个环境的应用层逻辑。

尝试复现

使用vulhub上的样例可以成功复现,具体参考其wiki。

https://github.com/vulhub/vulhub/tree/master/fastjson/1.2.24-rce

但是这个样例是docker容器,其中包含的jar文件,没有源码。为了能好地分析,我们需要用源码搭建一套复现环境。要找到源码,可以尝试从docker中复制出来然后反编译。

运行其容器后,使用以下命令将里面的jar拷贝到本地宿主机。

1
docker cp <container-id>:<src-path> <dest-path>

然后用jadx打开,找到相关json反序列化入口

image

可见此poc使用的是一个spring boot框架下的普通的json反序列化,没有特殊条件。后续我们将用 JSON.parseObject() 的方式来复现

我们本地也构造这样一个环境试试。首先尝试新建一个spring boot工程,使用较新的jdk 17和spring boot 3.2.2版本,但是老的fastjson 1.2.24。

image

请注意当前的 https://start.spring.io/ 默认初始模板中的依赖是错误的。如果你是用的是其初始模板,需要将build.gradle中“org.springframework.boot:spring-boot-starter”需要改成“org.springframework.boot:spring-boot-starter-web”,否则会编译失败。

使用一个简单的反序列化payload, 在服务器根路径收到get请求时触发

image

在请求localhost:8080后,发现服务器报错

1
java.lang.reflect.InaccessibleObjectException: Unable to make public com.sun.rowset.JdbcRowSetImpl() accessible: module java.sql.rowset does not "exports com.sun.rowset" to unnamed module

搜索此报错,看到如下github issue。

https://github.com/dbgee/fastjson-rce/issues/2

看上去jdk 17是无法构造RCE的,因此尝试换成jdk 1.8 (8u202)。

image

这样修改后编译是失败的,因为spring boot 3.2.2不兼容。由于依赖的环境版本比较老,所以有一些配置需要修改才能正常跑起来。

根据这篇Stack Overflow回答,我们去找spring boot 2.7

https://stackoverflow.com/questions/76467522/cant-compile-spring-boot-on-java-1-8

按照spring boot 2.7的gradle设置,重新修改build.gradle。

https://docs.spring.io/spring-boot/docs/2.7.18/gradle-plugin/reference/htmlsingle/#getting-started

这是我的最终build.gradle。注意第22行不能加,否则在当前的环境中跑不起来。

image

与此同时,如果没有jdk 1.8,去oracle官网创建一个账号,然后下载。

由于我是用gradlew启动的程序,所以在其bash脚本中进行修改,无脑使用了java 1.8

image

在启动nc监听的情况下,再次访问该网页,复现成功。可见右侧的监听收到了rmi的请求。为了更简便地分析调试,我们这里不必使用完整的PoC,而是在收到请求之后就确定是有问题的。

image

我们先尝试一下安卓版本能否复现这个bug。由于描述上写的fastjson版本小于1.2.25都存在这个问题,所以我这里用了1.1.52.android这个版本。现在我们把build.gradle中的fastjson版本修改后重新编译并运行服务器。

然后使用同样的payload,发现服务器依然会去请求jndi。如果我们打断点,是可以看到这次调用栈进入的是1.1.52.android版本的fastjson。

image

那么排除fastjson的安卓版有不同于普通版的地方,所以安卓版是安全的的这个假设。

经过一些搜索,我们可以看到安卓是不支持jndi的。

类似fastjson,log4shell也是在安卓不受影响。其同样利用了jndi的方式进行了RCE。可以看到这篇文章分析得出安卓不影响,原因是安卓不支持jndi。

https://support.nowsecure.com/hc/en-us/articles/4417200289421-Log4Shell-and-Its-Impact-on-Mobile-Security

由于我们尝试的poc是依赖jndi的,因此安卓的老版本确实无法用相同的方式攻击。

我们搭建一个kotlin的安卓项目,并使用fastjson 1.1.52.android,其余均为默认值。

image

image

尝试在安卓应用中使用相同的payload,在activity的onCreate的时候直接运行反序列化。得到以下报错:类无法找到

image

理解此漏洞

由于老版本fastjson在反序列化时,可以指定任意类进行反序列化。在反序列化时也会调用其get、set、constructor等方法,也就相当于代码执行。

任何可以被fastjson反序列化攻击的类称为fastjson gadget,而我们最熟知的便是jndi的类。攻击者能用fastjson执行的代码,仅限于fastjson gadget。具体的反序列化分析不在本文中讨论。

安卓版本不能使用jndi的gadget,但是其他的很多gadget可以使用,也存在很多Spring Boot没有的gadget。目前已知的安卓fastjson gadget中,没有能造成实际影响的。

结论

目前已知的PoC无法攻击安卓应用,因为使用的fastjson gadget是jndi,且安卓不支持jndi。攻击者可以利用fastjson进行代码执行,但是目前(2024-02-26)没有发现可以在安卓上造成实际影响的fastjson gadget。

本次研究的fastjson的安卓版本(后缀为“.android”)和普通版本在服务器端使用都存在RCE漏洞,攻击方式相同。