内部赛-2023第三届网络安全攻防大赛个人赛②-复赛WriteUp

Misc

签到

cyberchef打开.
input: 0db584e82fce27bab2e2677e4dd3a95749dddfdf08d52ebe80501df6aac2571fddd3d80dd5df681dc7c57efb831ea5ad
key选utf8 :1234567890abcdef
mode选ECB

爆破的魅力

stegsolve看文件信息提示 I believe in the security of aes&lsb steganography

aes加密和 lsb 文件隐写,用stegsolve看.

alpha0通道提示 pwd in
alpha1通道提示 xato-net-10-million-passwords-10000.txt

但没找到lsb隐写文件.

使用 puzzle 工具bruteforce 打开 img. 使用提示给出的 10000.txt。 爆破跑出flag。

flag在哪里

png修改高度即可显示

flag{4c2664365bc1a66dcf86d333283ef188}

re

check

  sub_140001080("%42s");
  v3 = -1i64;
  do
    ++v3;
  while ( v11[v3] );
  v4 = 0i64;
  v5 = 0xACE1;
  for ( i = 0i64; i < v3; ++i )
  {
    v7 = v5;
    v8 = v5 >> 1;
    v9 = v8 ^ 0xB400;
    if ( (v7 & 1) == 0 )
      v9 = v8;
    v5 = v9;
    v11[i + 80] = v11[i] ^ v9;
  }
  v11[v3 + 80] = 0;
  do
  {
    if ( v11[v4 + 80] != byte_140002288[v4] )
    {
      sub_140001020("err");
      exit(0);
    }
    ++v4;
  }
  while ( v4 < 0x2A );

正常逆向

enc = [0x16, 0x54, 0xFD, 0x29, 0x5C, 0x20, 0xE8, 0xFD, 0x07, 0xD3,
       0x6F, 0x18, 0x2E, 0xA6, 0xA6, 0x5B, 0x88, 0xBE, 0x41, 0xD4,
       0xEC, 0x89, 0x4F, 0x16, 0xA5, 0x79, 0x9F, 0xEA, 0x44, 0x0D,
       0x2E, 0x6F, 0xE5, 0xF4, 0x03, 0x83, 0xE1, 0xD9, 0x4E, 0xDD,
       0xBF, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       ];

v5 = 0xACE1

for i in range(42):
    v7 = v5 & 0xff
    v8 = v5 >> 1
    v9 = (v8 ^ 0xB400)
    if (v7 & 1) == 0:
        v9 = v8
    v5 = v9
    print(chr(enc[i] ^ v9 & 0xff), end='')

z3求解器

直接用z3-sovler 照着写自动求.

from natsort import natsorted
from z3 import *

enc = [0x16, 0x54, 0xFD, 0x29, 0x5C, 0x20, 0xE8, 0xFD, 0x07, 0xD3, 0x6F, 0x18, 0x2E, 0xA6, 0xA6, 0x5B, 0x88, 0xBE, 0x41,
       0xD4, 0xEC, 0x89, 0x4F, 0x16, 0xA5, 0x79, 0x9F, 0xEA, 0x44, 0x0D, 0x2E, 0x6F, 0xE5, 0xF4, 0x03, 0x83, 0xE1, 0xD9,
       0x4E, 0xDD, 0xBF, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
       ];
v11 = [BitVec('s1_%d' % i, 8) for i in range(42)]  # 有时得用int值好使
v4 = 0
v5 = 0xace1
llen = 42

solver = Solver()
for i in range(42):
    v7 = v5
    v8 = v5 >> 1
    v9 = v8 ^ 0xb400
    if ((v7 & 1) == 0):
        v9 = v8
    v5 = v9
    # v11[(i + 80)] = v11[i] ^ v9
    solver.add(v11[i] ^ v9 == enc[i])
    
print(solver.check())
res = solver.model()

# lst = natsorted([(k, res[k]) for k in res], key=lambda x: x)
lst = natsorted([(k, res[k]) for k in res], lambda x: str(x[0]))
for k, v in lst:
    print(chr(v.as_long()), end='')

# flag{3a9eb748-c99f-b7d9-8789-94bc7b3958fb}

直接 c语言输出

#include "defs.h"
#include <stdio.h>

unsigned char byte_7FF64C532288[] =
        {
                0x16, 0x54, 0xFD, 0x29, 0x5C, 0x20, 0xE8, 0xFD, 0x07, 0xD3,
                0x6F, 0x18, 0x2E, 0xA6, 0xA6, 0x5B, 0x88, 0xBE, 0x41, 0xD4,
                0xEC, 0x89, 0x4F, 0x16, 0xA5, 0x79, 0x9F, 0xEA, 0x44, 0x0D,
                0x2E, 0x6F, 0xE5, 0xF4, 0x03, 0x83, 0xE1, 0xD9, 0x4E, 0xDD,
                0xBF, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00
        };


int __cdecl main(int argc, const char **argv, const char **envp) {
    unsigned __int64 v3; // r8
    unsigned __int64 v4; // rax
    unsigned __int16 v5; // r9
    unsigned __int64 i; // r10
    char v7; // cl
    unsigned __int16 v8; // r9
    unsigned __int16 v9; // dx
    char v11[160]; // [rsp+20h] [rbp-B8h]
    setbuf(stdout, NULL);

    v3 = 42;
    v4 = 0;
    v5 = 0xACE1;
    for (i = 0; i < v3; ++i) {
        v7 = v5;
        v8 = v5 >> 1;
        v9 = v8 ^ 0xB400;
        if ((v7 & 1) == 0)
            v9 = v8;
        v5 = v9;
        printf("%c", byte_7FF64C532288[i] ^ v9);
    }
    return 0;
}

web

ezlavaariel | 未完成

扫描下载源码 /www.zip



ezcms

扫描下载源码 /www.zip

/admin.php 根据提示 admin/123456登录。

根据提示:在后台/admin.php?m=Book&a=reply&id=1存在注入漏洞。利用报错注入可读取文件

开始没测出来。本地搭建环境找到 selectdb 这里 where uid in ($input$) 在这里进行报错注入。 后面会自动补一个括号 。

// www\m\BookModel.class.php #56
$param['where'] = 'uid in('.$id.')';  // uid in ( id )

payload: 1 or updatexml(1,concat(0x7e,version(),0x7e),1

使用 load_file来读取flag 1) or updatexml(1,concat(0x7e,load_file("/flag"),0x7e),1

Crypto

essential

本题wp来自 cyyc_zhy

因为数字特别大,所以可以把 p,q 近似看成下面的值。

\[\begin{align} & p = 13*a \\ & q = 25*a \\ & n = p*q = 13 * 25 * a^2 \\ & a = \sqrt{n \ / 13 \ / \ 25} \\ \end{align} \]

去check一下,如果p,q值不对,根据 p * q - n 的结果 去找a的上一个素数 或者下一个素数

p = sympy.nextprime(13 * a)
q = sympy.prevprime(25 * a)
e = 0xe18e
phin = (p - 1) * (q - 1)

assert gmpy2.gcd(e, phin) == 2 # 不互素

\[\begin{multline} \shoveleft \begin{aligned} & c = m^e mod \ n & & \# 前提是 e和 \phi(n) 是互素的, 现在gcd为2 \\ & c = m^{2 * \frac e 2} mod \ n & & \# m^2 替换为X, \frac e 2 替换为e1\\ & c = X^{e1} mod \ n \\ & m = \sqrt X & & 可求flag2\\ \end{aligned} \\ \end{multline} \]

crypto01

def crypto01(flag1, number1, n):
    tmp = 1
    while number1 > 0:
        if number1 % 2:
            tmp = (tmp * flag1) % n
        flag1 = flag1 ** 2 % n
        number1 //= 2
    return tmp

\[\begin{multline} \shoveleft \begin{aligned} & round1, number4 = m \% n , && m = m^2 \% n \\ & round2, number4 = m^2 \% n , && m = m^{2*2} \% n = m^4 \% n \\ ... & roundk, number4 = m^{2k} \% n , k=e/2 => \\ & roundk, number4 = m^e \% n \\ & 即 c1 = m^e \% n \end{aligned} \\ \end{multline} \]

import gmpy2
import sympy
from Crypto.Util.number import long_to_bytes


def crypto01(flag1, e, n):  # flag1 num1 num2
    number4 = 1
    while e > 0:
        if e % 2:
            number4 = (number4 * flag1) % n
        flag1 = flag1 ** 2 % n
        e //= 2
    return number4


number1 = 6035830951309638186877554194461701691293718312181839424149825035972373443231514869488117139554688905904333169357086297500189578624512573983935412622898726797379658795547168254487169419193859102095920229216279737921183786260128443133977458414094572688077140538467216150378641116223616640713960883880973572260683
number2 = 20163906788220322201451577848491140709934459544530540491496316478863216041602438391240885798072944983762763612154204258364582429930908603435291338810293235475910630277814171079127000082991765275778402968190793371421104016122994314171387648385459262396767639666659583363742368765758097301899441819527512879933947
n = number2

flag1 = 6624758244437183700228793390575387439910775985543869953485120951825790403986028668723069396276896827302706342862776605008038149721097476152863529945095435498809442643082504012461883786296234960634593997098236558840899107452647003306820097771301898479134315680273315445282673421302058215601162967617943836306076
flag2 = 204384474875628990804496315735508023717499220909413449050868658084284187670628949761107184746708810539920536825856744947995442111688188562682921193868294477052992835394998910706435735040133361347697720913541458302074252626700854595868437809272878960638744881154520946183933043843588964174947340240510756356766

a = gmpy2.iroot(number2 // 25 // 13, 2)[0]


def check(a):
    p = sympy.nextprime(13 * a)
    q = sympy.prevprime(25 * a)
    assert p * q == n
    print(a)


# check(a)
a = 7876724580534791771835430594434627088013471560469412207736963203935537053220379418645369259714178145931522503674390087394035229717461111762112820042426116
p = sympy.nextprime(13 * a)
q = sympy.prevprime(25 * a)
phin = (p - 1) * (q - 1)
e = 0xe18e
assert gmpy2.gcd(e, phin) == 2
d = gmpy2.invert(e // 2, phin)
X = pow(flag2, d, n)
m2 = gmpy2.iroot(X, 2)[0]
print(long_to_bytes(m2))

assert gmpy2.gcd(number1, phin) == 1
d1 = gmpy2.invert(number1, phin)
m1 = pow(flag1, d1, n)
print(long_to_bytes(m1))

# flag:flag{75811c6d95770d56092817b75f15df05}
posted @ 2023-07-16 10:49  wgf4242  阅读(401)  评论(0编辑  收藏  举报