fortify sca rules分析

admin 2024年11月6日14:13:06评论8 views字数 8239阅读27分27秒阅读模式

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分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月6日14:13:06
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   fortify sca rules分析https://cn-sec.com/archives/3362929.html

发表评论

匿名网友 填写信息