NepCTF2025 Writeup

NepBotEvent

根据文件名以及题目描述,文件是某种日志。观察十六进制可以发现具有某些循环规律,直接暴露了文件格式,这是 Linux 内核输入事件(/dev/input/event*) 的原始日志,也就是某个简单 keylogger 直接把 struct input_event 结构体顺序写进了文件

在 64 位 Linux 上(glibc 默认),struct input_event 为 24 字节:

struct input_event {
    struct timeval { long tv_sec; long tv_usec; } time;   // 16 bytes
    unsigned short type;                                  // 2
    unsigned short code;                                  // 2
    unsigned int   value;                                 // 4
};

对照给的开头,再往下同一个时间戳重复一次,

0100 1c00 01000000 => type=0x0001(EV_KEY)
code=0x001c(KEY_ENTER)
value=1(按下)

后面紧跟

0000 0000 0000 0000 => type=0(EV_SYN)

接下来的几组

MSC_SCAN 0x0007001a  -> HID usage 0x1a = 'w'
EV_KEY  code 0x0011 (KEY_W) value=1 -> 按下 w
...
MSC_SCAN 0x0007000b  -> HID usage 0x0b = 'h'
EV_KEY  code 0x0023 (KEY_H) value=1 -> 按下 h
...
MSC_SCAN 0x00070012  -> HID usage 0x12 = 'o'
EV_KEY  code 0x0018 (KEY_O) value=1 -> 按下 o
...
MSC_SCAN 0x00070004  -> HID usage 0x04 = 'a'

后续同理进行解析

import struct

key_map_normal = {
    2: '1', 3: '2', 4: '3', 5: '4', 6: '5',
    7: '6', 8: '7', 9: '8', 10: '9', 11: '0',
    12: '-', 13: '=', 14: '\b',
    16: 'q', 17: 'w', 18: 'e', 19: 'r', 20: 't',
    21: 'y', 22: 'u', 23: 'i', 24: 'o', 25: 'p',
    26: '[', 27: ']', 28: '\n',
    30: 'a', 31: 's', 32: 'd', 33: 'f', 34: 'g',
    35: 'h', 36: 'j', 37: 'k', 38: 'l',
    39: ';', 40: "'", 41: '`',
    44: 'z', 45: 'x', 46: 'c', 47: 'v', 48: 'b',
    49: 'n', 50: 'm', 51: ',', 52: '.', 53: '/',
    57: ' ', 43: '\\'
}

key_map_shift = {
    2: '!', 3: '@', 4: '#', 5: '$', 6: '%',
    7: '^', 8: '&', 9: '*', 10: '(', 11: ')',
    12: '_', 13: '+',
    16: 'Q', 17: 'W', 18: 'E', 19: 'R', 20: 'T',
    21: 'Y', 22: 'U', 23: 'I', 24: 'O', 25: 'P',
    26: '{', 27: '}', 28: '\n',
    30: 'A', 31: 'S', 32: 'D', 33: 'F', 34: 'G',
    35: 'H', 36: 'J', 37: 'K', 38: 'L',
    39: ':', 40: '"', 41: '~',
    44: 'Z', 45: 'X', 46: 'C', 47: 'V', 48: 'B',
    49: 'N', 50: 'M', 51: '<', 52: '>', 53: '?',
    57: ' ', 43: '|'
}

def parse_keylogger(file_path):
    result = []
    shift_pressed = False

    with open(file_path, 'rb') as f:
        while True:
            event = f.read(24)
            if len(event) < 24:
                break

            sec, usec, ev_type, code, value = struct.unpack('qqHHI', event)

            if ev_type == 1:
                if code in (42, 54):
                    shift_pressed = (value == 1)

                if value == 1:
                    if shift_pressed:
                        char = key_map_shift.get(code)
                    else:
                        char = key_map_normal.get(code)

                    if char:
                        result.append(char)

    return ''.join(result)

if __name__ == '__main__':
    log_file = 'NepBot_keylogger'
    typed = parse_keylogger(log_file)
    print("Recovered input:\n", typed)

得到结果如下

Recovered input:
whoami
ifconfig
uanme uname -a
ps -aux
cat /etc/issue
pwd
mysql -uroot -proot
show databases;
use NepCTF-20250725-114514;
show tables;
Enjoy yourself~
See u again.
Hacked By 1cePeak:)
c

得到Flag

NepCTF{NepCTF-20250725-114514}

客服小美

分析流量包可以找到通信的钓鱼木马地址

image-20250727114217266

192.168.27.132:12580

分析给的内存,提取出 关于2025年部分节假日安排.exe 并且可以看到被控机器的用户名,使用进程内存解密cs流量

image-20250727114604561

JohnDoe

image-20250727114459707

首先使用 cs-parse-http-traffic.py 提取加密数据

python3 cs-parse-http-traffic.py -k unknown DESKTOP.pcapng

需要注意的是这里有一些不需要的数据包,我们通过配置过滤器进行筛除

python3 cs-parse-http-traffic.py -Y "http and ip.addr == 192.168.27.132" -k unknown DESKTOP.pcapng

接着使用工具 cs-extract-key.py 提供加密任务(选项 -t)和进程内存转储来尝试解密此数据

python3 cs-extract-key.py -t ecfff639c9a79bbb3c59bbec390fa070335fa6d5b33c7ba752fe9803ee2082296233a5dcd7f76c8adb3a1e404df09447 minidump_pid_6492.dmp

得到的结果如下

image-20250727130311797

解密得到了key

AES Key:  a6f4a04f8a6aa5ff27a5bcdd5ef3b9a7
HMAC Key: 35d34ac8778482751682514436d71e09
SHA256 raw key: 35d34ac8778482751682514436d71e09:a6f4a04f8a6aa5ff27a5bcdd5ef3b9a7

但是这个流量包有一些问题,可以看到一些submit.php的数据长度并不为16的倍数(可能是编码问题,后面解码ca的时候也会出现)

image-20250727130231073

直接使用得到的key进行解码会报错,所以我们对过滤器进行修改,只对部分进行解码

python3 cs-parse-http-traffic-repair.py -Y "http and ip.addr == 192.168.27.132 and http.request.method == POST" -k 35d34ac8778482751682514436d71e09:a6f4a04f8a6aa5ff27a5bcdd5ef3b9a7 DESKTOP.pcapng

在其中一条中可以看到

Packet number: 90
HTTP request POST
http://192.168.27.132:12580/submit.php?id=1389642286
Length raw data: 356
Counter: 3
Callback: 22 TODO
b'\xff\xff\xff\xfe'
----------------------------------------------------------------------------------------------------
C:\Users\JohnDoe\Desktop\*
D       0       01/13/2025 15:31:07     .
D       0       01/13/2025 15:31:07     ..
F       282     01/13/2025 15:19:00     desktop.ini
F       207496  01/13/2025 11:49:56     DumpIt.exe
F       2332    01/13/2025 15:19:01     Microsoft Edge.lnk
F       36      01/13/2025 15:31:02     secret.txt
F       19456   01/13/2025 14:13:11     ¹ØÓÚ2025Ä겿·Ö½Ú¼ÙÈÕ°²ÅŵÄ֪ͨ.exe

----------------------------------------------------------------------------------------------------
Extra packet data: b'\x00'

Packet number: 110
HTTP request POST
http://192.168.27.132:12580/submit.php?id=1389642286
Length raw data: 84
Counter: 4
Callback: 30 OUTPUT
5c1eb2c4-0b85-491f-8d50-4e965b9d8a43

猜测命令是对secret.txt进行了type操作,得到敏感信息

5c1eb2c4-0b85-491f-8d50-4e965b9d8a43

得到Flag

NepCTF{JohnDoe_192.168.27.132:12580_5c1eb2c4-0b85-491f-8d50-4e965b9d8a43}

参考资料:

Cobalt Strike:使用进程内存解密流量 – 第 3 部分 – NVISO Labs

Cobalt Strike流量解密 - 1cePeak

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇