fortify sca rules分析

fortify sca rules 一直处于加密状态,只有在扫描的时候才会被加载,网上发现已经有大佬破解了,这里分享给大家,jar包知识星球自取,解密代码如下,自行编译即可:

import java.io.*;import java.nio.file.Files;import java.security.*;import java.util.Properties;import java.util.StringTokenizer;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;
public class Main { // 定义常量 private static final String MESSAGE_DIGEST_ALGORITHM = "SHA-1"; // 消息摘要算法 private static final String CRYPTO_PROVIDER = "SUN"; // 加密提供者 private static final int BUFFER_SIZE = 262144; // 缓冲区大小 private static final String STD = "1fea047f-dee0ac89-b5db25a6-b0c3a4cf"; // 默认密钥
// 构造函数 public Main() { }
// 获取消息摘要算法实例 public static MessageDigest getMessageDigestAlgorithm() { try { return MessageDigest.getInstance(MESSAGE_DIGEST_ALGORITHM, CRYPTO_PROVIDER); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } }
// 计算输入流的摘要 public static byte[] makeDigest(InputStream inStream) throws IOException { return makeDigest(inStream, getMessageDigestAlgorithm()); }
// 计算输入流的摘要,使用指定的消息摘要算法 public static byte[] makeDigest(InputStream inStream, MessageDigest md) throws IOException { md.reset(); DigestInputStream in = new DigestInputStream(inStream, md); return md.digest(); // 返回摘要结果 }
// 加密函数 private static void encrypt(long[] v, long[] k) { long y = v[0]; long z = v[1]; long sum = 0L; long delta = 2654435769L; // 常量 delta long n = 32L; // 迭代次数 long top = 4294967295L; // 掩码
// 加密循环 for (; n-- > 0L; z &= top) { sum += delta; sum &= top; y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1]; y &= top; z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3]; }
v[0] = y; v[1] = z; }
// 解密函数 private static void decrypt(long[] v, long[] k) { long n = 32L; // 迭代次数 long y = v[0]; long z = v[1]; long delta = 2654435769L; // 常量 delta long top = 4294967295L; // 掩码 long sum = delta << 5;
// 解密循环 for (sum &= top; n-- > 0L; sum &= top) { z -= (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3]; z &= top; y -= (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1]; y &= top; sum -= delta; }
v[0] = y; v[1] = z; }
// 加密输入流到输出流 private static void enc(InputStream source, OutputStream dest, long[] usrKey) throws IOException { long[] k = usrKey.clone(); // 克隆密钥 byte[] byteBuf = new byte[8]; // 字节缓冲区 byte[] tail = new byte[]{32, 32, 32, 32, 32, 32, 32, 8}; // 尾部字节 long[] unsigned32Buf = new long[2]; // 无符号32位缓冲区 long top = 4294967295L; // 掩码
int bytesRead; // 读取输入流并加密 while ((bytesRead = source.read(byteBuf)) != -1) { if (bytesRead < 8) { tail[7] = (byte) bytesRead; // 设置尾部字节 }
byteArrayToUnsigned32(byteBuf, unsigned32Buf); // 字节数组转换为无符号32位数组 encrypt(unsigned32Buf, k); // 加密 k[0] = k[0] + 17L & top; // 更新密钥 k[1] = k[1] + 17L & top; k[2] = k[2] + 17L & top; k[3] = k[3] + 17L & top; unsigned32ToByteArray(unsigned32Buf, byteBuf); // 无符号32位数组转换为字节数组 dest.write(byteBuf); // 写入输出流 }
byteArrayToUnsigned32(tail, unsigned32Buf); // 处理尾部字节 encrypt(unsigned32Buf, k); k[0] = k[0] + 17L & top; k[1] = k[1] + 17L & top; k[2] = k[2] + 17L & top; k[3] = k[3] + 17L & top; unsigned32ToByteArray(unsigned32Buf, tail); dest.write(tail); // 写入尾部字节 }
// 解密输入流到输出流 private static void dec(InputStream source, OutputStream dest, long[] usrKey) throws IOException { long[] k = usrKey.clone(); // 克隆密钥 byte[] byteBuf = new byte[8]; // 字节缓冲区 byte[] byteBufDelay = null; // 延迟字节缓冲区 long[] unsigned32Buf = new long[2]; // 无符号32位缓冲区 long top = 4294967295L; // 掩码
int bytesRead; // 读取输入流并解密 while ((bytesRead = source.read(byteBuf)) != -1) { if (bytesRead < 8) { throw new IOException("invalid encrypted stream"); // 无效的加密流 }
byteArrayToUnsigned32(byteBuf, unsigned32Buf); // 字节数组转换为无符号32位数组 decrypt(unsigned32Buf, k); // 解密 k[0] = k[0] + 17L & top; // 更新密钥 k[1] = k[1] + 17L & top; k[2] = k[2] + 17L & top; k[3] = k[3] + 17L & top; unsigned32ToByteArray(unsigned32Buf, byteBuf); // 无符号32位数组转换为字节数组
if (source.available() == 0) { int bytesToWrite = byteBuf[7]; if (bytesToWrite > 8 || bytesToWrite < 0 || byteBufDelay == null) { throw new IOException("invalid encrypted stream"); // 无效的加密流 }
dest.write(byteBufDelay, 0, bytesToWrite); // 写入延迟字节 }
if (byteBufDelay != null) { dest.write(byteBufDelay, 0, 8); // 写入延迟字节 byte[] t = byteBufDelay; byteBufDelay = byteBuf; byteBuf = t; } else { byteBufDelay = byteBuf; byteBuf = new byte[8]; } } }
// 执行块加密或解密 private static void doBlockCipher(InputStream source, OutputStream dest, boolean encrypt, long[] usrKey) throws IOException { if (encrypt) { enc(source, dest, usrKey); // 加密 } else { dec(source, dest, usrKey); // 解密 } }
// 读取加密流中的头部信息 public static void readHeaders(InputStream encrypted) throws IOException { Properties props = new Properties(); final PushbackInputStream src = new PushbackInputStream(encrypted); props.load(new InputStream() { boolean closed = false;
public int read() throws IOException { if (closed) { return -1; } else { int c = src.read(); if (c == 0) { src.unread(c); closed = true; return -1; } else { return c; } } } });
int read = src.read(); if (read != 0) { throw new IOException("invalid encrypted stream"); // 无效的加密流 } }
// 解密并解压缩加密流中的数据 public static byte[] decryptCompressedAfterHeaders(InputStream encrypted, String keyString) throws IOException { return decryptAfterHeaders(encrypted, keyString, true); }
// 解密加密流中的数据,可以选择是否解压缩 public static byte[] decryptAfterHeaders(InputStream encrypted, String keyString, boolean compressed) throws IOException { long[] key = makeKeyFromString(keyString != null ? keyString : STD); // 生成密钥 ByteArrayOutputStream cleartext = new ByteArrayOutputStream(); doBlockCipher(encrypted, cleartext, false, key); // 解密 cleartext.close(); byte[] bytes = cleartext.toByteArray(); if (compressed) { bytes = uncompressString(bytes); // 解压缩 }
return bytes; }
// 解密并解压缩加密流中的数据 public static byte[] decryptCompressed(InputStream encrypted, String keyString) throws IOException { readHeaders(encrypted); // 读取头部信息 return decryptCompressedAfterHeaders(encrypted, keyString); }
// 加密并压缩明文数据 public static void encryptAndCompress(InputStream cleartext, OutputStream ciphertext, String keyString, Properties properties) throws IOException { if (properties != null) { properties.store(ciphertext, null); // 存储属性 }
ciphertext.write(new byte[]{0}); // 写入分隔符 encryptAfterHeaders(cleartext, ciphertext, keyString, true); // 加密并压缩 }
// 加密明文数据,可以选择是否压缩 public static void encryptAfterHeaders(InputStream stream, OutputStream ciphertext, String keyString, boolean compress) throws IOException { long[] key = makeKeyFromString(keyString != null ? keyString : STD); // 生成密钥 if (compress) { stream = compressInputStream(stream); // 压缩输入流 }
doBlockCipher(stream, ciphertext, true, key); // 加密 stream.close(); }
// 从字符串生成密钥 private static long[] makeKeyFromString(String keyString) { long[] k = new long[4]; String[] splitString = new String[4]; StringTokenizer st = new StringTokenizer(keyString, "-");
int i; for (i = 0; i < splitString.length; ++i) { if (!st.hasMoreTokens()) { throw new Error("invalid key"); // 无效的密钥 }
splitString[i] = st.nextToken(); }
for (i = 0; i < 4; ++i) { try { k[i] = Long.parseLong(splitString[i], 16); // 解析密钥 } catch (NumberFormatException e) { throw new Error("invalid key"); // 无效的密钥 } }
return k; }
// 解压缩字节数组 private static byte[] uncompressString(byte[] in) throws IOException { GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(in)); ByteArrayOutputStream out = new ByteArrayOutputStream(); int bufferSize = 10240; byte[] buffer = new byte[bufferSize];
while (true) { int bytesRead = gis.read(buffer, 0, bufferSize); if (bytesRead == -1) { return out.toByteArray(); // 返回解压缩后的数据 }
out.write(buffer, 0, bytesRead); } }
// 压缩输入流 private static InputStream compressInputStream(InputStream in) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream gz = new GZIPOutputStream(baos); int bufferSize = 10240; byte[] buffer = new byte[bufferSize]; int var5 = 0;
while (true) { int bytesRead = in.read(buffer, 0, bufferSize); if (bytesRead == -1) { gz.close(); return new ByteArrayInputStream(baos.toByteArray()); // 返回压缩后的数据 }
gz.write(buffer, 0, bytesRead); var5 += bytesRead; } }
// 字节数组转换为无符号32位数组 public static void byteArrayToUnsigned32(byte[] byteBuf, long[] unsigned32Buf) { for (int i = 0; i < unsigned32Buf.length; ++i) { unsigned32Buf[i] = ((long) byteBuf[i * 4] & 255L) + (((long) byteBuf[i * 4 + 1] & 255L) << 8) + (((long) byteBuf[i * 4 + 2] & 255L) << 16) + (((long) byteBuf[i * 4 + 3] & 255L) << 24); } }
// 无符号32位数组转换为字节数组 public static void unsigned32ToByteArray(long[] unsigned32Buf, byte[] byteBuf) { for (int i = 0; i < unsigned32Buf.length; ++i) { long l = unsigned32Buf[i]; byteBuf[i * 4] = (byte) ((int) (l & 255L)); byteBuf[i * 4 + 1] = (byte) ((int) (l >> 8 & 255L)); byteBuf[i * 4 + 2] = (byte) ((int) (l >> 16 & 255L)); byteBuf[i * 4 + 3] = (byte) ((int) (l >> 24 & 255L)); } }
// 解密文件 public static void decryptFile(File src, File dst) throws Exception { InputStream inputStream = Files.newInputStream(src.toPath()); byte[] rule = decryptCompressed(inputStream, null); // 解密并解压缩 OutputStream outputStream = Files.newOutputStream(dst.toPath()); outputStream.write(rule); // 写入解密后的数据 outputStream.close(); }
// 主函数 public static void main(String[] args) throws Exception { String rulesDir = "F:\rules\2024.2.1.0003-zh_CN\rules"; String decryptDir = "F:\rules\2024.2.1.0003-zh_CN\decrypt"; File file = new File(rulesDir); if (file.isDirectory()) { File[] files = file.listFiles(); for (File f : files) { if (f.getName().endsWith(".bin")) { decryptFile(f, new File(decryptDir + "/" + f.getName() + ".xml")); // 解密文件 } } } else { decryptFile(file, new File(decryptDir + "/" + file.getName() + ".xml")); // 解密文件 } }}

fortify sca rules分析

原文始发于微信公众号(代码审计SDL):fortify sca rules分析

版权声明:admin 发表于 2024年11月6日 上午10:18。
转载请注明:fortify sca rules分析 | CTF导航

相关文章