2025年Solar应急响应公益月赛-3月

2025年Solar应急响应公益月赛-3月

原链接:2025年Solar应急响应公益月赛-3月|n0o0b’s blog

窃密排查-1

题目描述

发现内部数据被窃取,进行紧急上机。请通过黑客遗留痕迹进行排查:
找到黑客窃密工具的账号
容器账号密码:root:Solar@2025_03!

tmp目录下发现megacmd,搜一下得知log日志在~/.megaCmd中,遂而发现登录账户

image-20250329101925754
25solar3abc@habenwir.com

窃密排查-2

题目描述

发现内部数据被窃取,进行紧急上机。请通过黑客遗留痕迹进行排查:
获取黑客账号找到flag

~/.megaCmd/发现sqlite数据库文件megaclient_statecache14_eHlWQTZuLWNFNGf3Nv5gC10JM48JzGHTc8y6.db ,其中包含flag文件痕迹,不过mega对这些信息都加密了

image-20250402152806556

~/.megaCmd/下还存在session文件,找到Forensic Investigation of the MEGAcmd Client这篇文章,奈何方向错误

可能是因为密码被重置过导致session失效

查询该邮箱,发现记录在yopmail.com

image-20250402150954318

访问该公共邮箱平台YOPmail : 临时、匿名的免费邮箱地址。

image-20250402151316282

登录发现有封邮件是recover code恢复密钥

image-20250402151510041

尝试恢复mega账户帐户恢复 - MEGA,会发送重置链接到邮箱

image-20250402152251826

输入刚才的恢复密钥

image-20250402152417485

重置密码

image-20250402152521930

在共享项目中找到flag

image-20250402153333879

flag{h4S8_h4m1_8Wlq_b3Xz}

窃密排查-3

获取黑客最终转移账号找到flag

右上角微信标进入聊天框,发现badguy2503@wishy.fr给我们发来session

image-20250402155014419

利用session直接登录

image-20250402160756125

【签到】和黑客去Battle把!

题目描述

某某文化有限公司被加密啦!老板给了小王5000美元请你帮助小王和黑客谈判争取使用最低的价格买下密钥!
【用户ID为登录青少年CTF平台的手机号】
【本题为模拟请勿当真!禁止攻击平台!】

讲价

image-20250329110926544

溯源排查-1

raw转vmdk

qemu-img convert -f raw .\AFEWgf_m-f8zj02psjoasq9hitdu2_system.raw  -O vmdk .\solar-3.vmdk

R-studio取证可以得知是centOS-7

屏幕截图 2025-03-30 163213

然后vmware新建虚拟机

image-20250331013053209

centOS-7

image-20250331013117864

image-20250331013144136

image-20250331013202127

虚拟磁盘

image-20250331013215355

开机按e修改启动配置

image-20250330165722109

删掉静默模式以及一堆网卡串口配置,添加rw init=/sysroot/bin/sh

不删要不然可能会系统堵塞

image-20250330192558273

系统初始化后到了shell环境

image-20250330192459407

切换一下根目录

mount  -o  remount   rw  /sysroot
chroot   /sysroot
LANG=C

image-20250330194102326

改root密码

touch  /.autorelabel
passwd
exit
reboot

image-20250330194427164

重启登入后ifconfig查看确定有网卡

image-20250330233014219

直接ssh连接,密码为所设密码,抓个包查看是否有外连

image-20250330233939454

156.238.230.167:46578

溯源排查-2

ps查看cpu占用较大的进程

image-20250330234350671

systemctl status查看服务发现同时有两个systemd-journald.service相似,其中systemd-journald为标准日志守护进程,而另一个journaled是伪造成系统进程,多了一个e

image-20250330235746961

image-20250330235028124

R-studio也可以看到该服务比较新

image-20250331001354647

[Unit]
Description=journaled
ConditionFileIsExecutable=/usr/local/systemd/journaled


[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/usr/local/systemd/journaled







Restart=always

RestartSec=120
EnvironmentFile=-/etc/sysconfig/systemd-journaled

[Install]
WantedBy=multi-user.target

该服务的二进制文件/usr/local/systemd/journaled与/root/tmp/hsperfdata_root/2233以及/root/tmp/tomcat-docbase.8848.7206919844684045987/journaled都是同一个文件(后两者被删除),可以相互链接

image-20250331001655598

flag{/usr/local/systemd/journaled}

溯源排查-3

完整服务名称为systemd-journaled

溯源排查-4

题目描述

业务系统已被删除,找出可能存在漏洞的应用

R-studio恢复,发现nacos-server

image-20250329104139410

溯源排查-6

题目描述

找出黑客利用漏洞使用的工具的地址,该工具为开源工具

检索一下nocas RCE漏洞发现c0olw/NacosRce: Nacos JRaft Hessian 反序列化 RCE 加载字节码 注入内存马 不出网利用

项目地址https://github.com/c0olw/NacosRce

溯源排查-5

题目描述

请提交漏洞cve编号

Nacos Hessian 反序列化漏洞

CNVD-2023-45001阿里云漏洞库

明明是cnvd,改成CVE才对

2503逆向

seed为开机时间

image-20250331111501116

qa0wserdf1tg9yuhjio2pklz8xbvcn4mPL7JKOIHUG3YTF6DSREAWQZX5MNCBV伪随机生成十六位key

image-20250331111522101

sub_140001350标准rc4

image-20250331111604772

flag.txt读入明文,flag.txt.freefix输出密文

爆破seed解密,ai搓脚本

c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// 密钥生成使用的字符集
const char charset[] = "qa0wserdf1tg9yuhjio2pklz8xbvcn4mPL7JKOIHUG3YTF6DSREAWQZX5MNCBV";

// 加密数据
const unsigned char encrypted_data[] = {
    0x4C, 0x00, 0x2F, 0xAD, 0x84, 0x10, 0x58, 0xAC,
    0x8D, 0xD1, 0x59, 0x69, 0x79, 0xFB, 0x9D, 0xB5,
    0xC5, 0xFA, 0x60, 0x17, 0xB0, 0x46, 0xE8, 0x75,
    0xD6, 0xCD, 0xDE, 0xD7, 0x57, 0xDC, 0x7C, 0x96,
    0xE1, 0x15, 0xF3, 0xBD, 0xC0, 0x72, 0x98, 0x91,
    0x88, 0x4D, 0x0C, 0xBA, 0x66, 0x04, 0xC9
};

const size_t encrypted_size = sizeof(encrypted_data);

/**
 * 根据给定的种子(TickCount)生成密钥
 * @param seed 随机数种子,来自GetTickCount()
 * @param key 输出参数,存储生成的密钥
 * @param key_length 密钥长度,原程序为16
 */
void generate_key(uint32_t seed, char* key, int key_length) {
    // 设置随机数种子
    srand(seed);
    int count = 0;

    // 生成16个字符的密钥
    while (count < key_length) {
        int r = rand();
        int idx = r % 62; // 与原代码相同的取模操作

        // 确保索引在有效范围内
        if (idx <= 61 && idx < strlen(charset)) {
            key[count] = charset[idx];
            count++;
        }
    }
    key[key_length] = '\0'; // 字符串结束符
}

/**
 * 设置RC4状态数组
 * @param key 密钥
 * @param key_len 密钥长度
 * @param S 输出参数,256字节的状态数组
 */
void setup_rc4(char* key, size_t key_len, unsigned char* S) {
    int i, j = 0;
    unsigned char temp;

    // 初始化S盒
    for (i = 0; i < 256; i++) {
        S[i] = i;
    }

    // 密钥调度算法 (KSA)
    for (i = 0; i < 256; i++) {
        // 使用密钥更新j
        j = (j + S[i] + key[i % key_len]) % 256;
        // 交换S[i]和S[j]
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }
}

/**
 * 使用RC4算法解密数据
 * @param encrypted 加密数据
 * @param decrypted 输出参数,解密后的数据
 * @param data_len 数据长度
 * @param key 密钥
 * @param key_len 密钥长度
 */
void rc4_decrypt(const unsigned char* encrypted, unsigned char* decrypted,
    size_t data_len, char* key, size_t key_len) {
    unsigned char S[256];
    int i = 0, j = 0;
    unsigned char temp;

    // 设置RC4状态
    setup_rc4(key, key_len, S);

    // 解密 (PRGA - 伪随机生成算法)
    for (size_t k = 0; k < data_len; k++) {
        // 更新索引i和j
        i = (i + 1) % 256;
        j = (j + S[i]) % 256;

        // 交换S[i]和S[j]
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;

        // 使用生成的密钥流进行XOR解密
        decrypted[k] = encrypted[k] ^ S[(S[i] + S[j]) % 256];
    }
}

/**
 * 检查解密是否成功
 * @param decrypted 解密后的数据
 * @return 如果前4个字节是"flag"则返回1,否则返回0
 */
int is_flag(const unsigned char* decrypted) {
    // 检查前4个字节是否为'flag'
    return (decrypted[0] == 'f' &&
        decrypted[1] == 'l' &&
        decrypted[2] == 'a' &&
        decrypted[3] == 'g');
}

/**
 * 打印解密后的数据,以十六进制和ASCII格式显示
 * @param decrypted 解密后的数据
 * @param length 数据长度
 */
void print_decrypted(const unsigned char* decrypted, size_t length) {
    printf("解密后(十六进制): ");
    for (size_t i = 0; i < length; i++) {
        printf("%02X ", decrypted[i]);
    }

    printf("\n解密后(ASCII): ");
    for (size_t i = 0; i < length; i++) {
        // 只打印可见字符,其他用点号代替
        if (decrypted[i] >= 32 && decrypted[i] <= 126) {
            printf("%c", decrypted[i]);
        }
        else {
            printf(".");
        }
    }
    printf("\n");
}

int main() {
    char key[17]; // 16个字符 + 结束符
    unsigned char decrypted[encrypted_size];
    uint32_t tick_count;
    uint32_t start_tick = 0;
    uint32_t end_tick = 86400000; // 24小时的毫秒数(根据需要调整)
    uint32_t step = 1; // 先每秒检查一次

    printf("开始暴力破解,TickCount范围从%u到%u\n", start_tick, end_tick);

    // 第一轮 - 每秒检查一次
    for (tick_count = start_tick; tick_count <= end_tick; tick_count += step) {
        // 生成密钥
        generate_key(tick_count, key, 16);
        // 尝试解密
        rc4_decrypt(encrypted_data, decrypted, encrypted_size, key, 16);

        // 检查是否成功解密
        if (is_flag(decrypted)) {
            printf("在TickCount = %u时找到可能的匹配\n", tick_count);
            printf("密钥: %s\n", key);
            print_decrypted(decrypted, encrypted_size);

            // 如果想在找到第一个匹配时退出:
            // return 0;
        }

        // 每百万次尝试显示一次进度
        if (tick_count % 1000000 == 0) {
            printf("进度:已测试TickCount至%u\n", tick_count);
        }
    }

    printf("第一轮完成。未找到匹配。\n");

    // 第二轮 - 如果第一轮失败,进行更细粒度的搜索
    // 如果需要更彻底的搜索,取消下面注释
    /*
    printf("开始第二轮搜索,使用更小的步长...\n");
    step = 100; // 每100毫秒检查一次

    for (tick_count = start_tick; tick_count <= end_tick; tick_count += step) {
        generate_key(tick_count, key, 16);
        rc4_decrypt(encrypted_data, decrypted, encrypted_size, key, 16);

        if (is_flag(decrypted)) {
            printf("在TickCount = %u时找到可能的匹配\n", tick_count);
            printf("密钥: %s\n", key);
            print_decrypted(decrypted, encrypted_size);
            return 0;
        }

        // 进度指示器
        if (tick_count % 1000000 == 0) {
            printf("进度:已测试TickCount至%u\n", tick_count);
        }
    }
    */

    printf("在指定范围内未找到匹配结果。\n");
    return 0;
}

python

import sys

# 假设的字符数组
chars = "qa0wserdf1tg9yuhjio2pklz8xbvcn4mPL7JKOIHUG3YTF6DSREAWQZX5MNCBV"

def cpp_rand(seed):
    seed = (seed * 214013 + 2531011) & 0xFFFFFFFF
    return (seed >> 16) & 0x7FFF, seed

def generate_key(initial_seed):
    key = []
    current_seed = initial_seed
    for _ in range(16):
        current_seed = (current_seed * 214013 + 2531011) & 0xFFFFFFFF
        rand_val = (current_seed >> 16) & 0x7FFF
        index = rand_val % 62
        key.append(chars[index])
    return ''.join(key)

def decrypt_rc4(ciphertext, key):
    s = list(range(256))
    j = 0
    key_bytes = [ord(c) for c in key]
    key_len = len(key_bytes)

    # KSA
    for i in range(256):
        j = (j + s[i] + key_bytes[i % key_len]) % 256
        s[i], s[j] = s[j], s[i]

    # PRGA
    i = j = 0
    plaintext = []
    for byte in ciphertext:
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i], s[j] = s[j], s[i]
        k = s[(s[i] + s[j]) % 256]
        plaintext.append(byte ^ k)
    return bytes(plaintext)

ciphertext = bytes.fromhex("4C002FAD841058AC8DD1596979FB9DB5C5FA6017B046E875D6CDDED757DC7C96E115F3BDC0729891884D0CBA6604C9")

# 遍历种子范围(示例取较小范围)
for seed in range(0, 10000000):
    key = generate_key(seed)
    plaintext = decrypt_rc4(ciphertext, key)
    if plaintext.startswith(b'flag'):
        print(f"Seed: {seed}, Key: {key}, Flag: {plaintext.decode()}")
        sys.exit(0)
print("Flag not found in range.")

c

image-20250329132856690

python

image-20250329133619677

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值