2022 数据安全管理员 学生组、企业组、企业组线上赛

2022年全国行业职业技能竞赛--全国数据安全职业技能竞赛 “美亚柏科杯”数据安全管理员职业技能竞赛

学生组

Misc

修复 docx文件头 50 4b 03 04, 修改扩展名为docx。打开,修改文件字体。得到 flag

Crypto

题目

from Crypto.Util import number
from secret import flag3 as flag

class stream_lcg:
    def __init__(self, seed, a, b, m):
        self.state = seed
        self.a = a
        self.b = b
        self.m = m

    def random(self):
        self.state = (self.state * self.a + self.b) % self.m
        return self.state


a =  978562056823367154661231724324891953762007467621
m =  749016427347710886642154346393313956385679230533
b = number.getRandomInteger(64) 
gen = stream_lcg(number.bytes_to_long(flag),a,b,m)

gift = []
for i in range(2):
    gift.append(gen.random())

print gift

# [659790491777475729494865848448903737196638977914L, 486063966694351430606710544549903497571072525229L]

解题

from Crypto.Util.number import *
import libnum
import binascii

a =  978562056823367154661231724324891953762007467621
n =  749016427347710886642154346393313956385679230533
output1 =  659790491777475729494865848448903737196638977914
output2 =  486063966694351430606710544549903497571072525229
b=(output2-a*output1)%n
plaintext=b
print(plaintext)
# print(long_to_bytes(plaintext))
c =  output1
MMI = lambda A, n,s=1,t=0,N=0: (n < 2 and t%N or MMI(n, A%n, t, s-A//n*t, N or n),-1)[n<1] #逆元计算
ani=MMI(a,n)
seed=c
for i in range(1):
    seed = (ani*(seed-b))%n
print(long_to_bytes(seed))

运维

对redis数据库进行加固

企业组线上赛

re

binwalk -Me fw.bin

得到 part1 flag 和part2提示 /usr/sbin/bd

二进制搜索bd得到 flag2

第3个不会。

misc

运维

linux+apache+mariadb
系统被入侵,请处置并加固系统及数据库。

企业组

misc

找到 zip 文件 50 4b开头的数据。保存为zip

密码提示内容如下,但是看不懂。

password=VV.JN:T.TN:V;VV.N:T.TN:V;VV.TN:T.TN:V;VV:T.JN:V;VV:T.N:V;VV:T.TN:V;VV:T:V;VV:V.JN:V;VV:V.N:V;VT:V.N:V;VT:V.JN:V;VT:T:V;VT:T.TN:V;VT:T.N:V;VT:T.JN:V;VT:R:V;VV:R:V;VX:V.N:V;F.JN:V.N:V;F.N:V.N:V;F.TN:V.N:V;F:V.N:V;F:V.JN:V;F:T:V;F:T.TN:V;F.TN:T.TN:V;F.N:T.TN:V;F.JN:T.TN:V;VX:T.TN:V;VX:T.N:V;VX:T.JN:V;VX:R:V;F.JN:R:V;F.N:R:V;F.TN:R:V;F:R:V;H:V.N:V;H:V.JN:V;H:T:V;H:T.TN:V;H:T.N:V;H:T.JN:V;H:R:V;J.JN:R:V;J.N:R:V;J.TN:R:V;J:R:V;N:T.JN:V;N:T.N:V;N.JN:T.TN:V;N.N:T.TN:V;N.TN:T.TN:V;N:T.TN:V;N:V.N:V;N:V.JN:V;N:T:V;6:T.TN:V;6:R:V;N.JN:R:V;N.N:R:V;N.TN:R:V;N:R:V;R:T.JN:V;R:T.N:V;R:T.TN:V;R:T:V;R:V.JN:V;R.JN:V.N:V;R.N:V.N:V;R.TN:V.N:V;R:V.N:V;P:V.N:V;P:T:V:P:V.JN:V;P:T.TN:V;P:T.N:V;P:T.JN:V;R.JN:T.TN:V;R.N:T.TN:V;R.TN:T.TN:V;P:R:V;R.JN:R:V;R.N:R:V;R.TN:R:V;R:R:V;T:V.N:V;V.JN:V.N:V;V.N:V.N:V;V.TN:V.N:V;V:V.N:V;T:T.TN:V;V.JN:T.TN:V;V.N:T.TN:V;V.TN:T.TN:V;V:T.TN:V;V:V.N:V;V:V.JN:V;V:T:V;V:T.TN:V;V:T.N:V;V:T.JN:V;T:R:V;V:R:V;V.TN:R:V;V.N:R:V;V.JN:R:V

爆破大写字母+数字: E8F72H
解压文件得到

flag{ump0r0rijq4m94gnjgnglf8hkv5yj9da}

运维

linux+apache+mysql
系统被入侵,请处置并加固系统及数据库。

web

dirsearch扫到源码。

page2.php

<?php
include "flag.php";                                               
$_403 = "login error";
$_200 = "Welcome Admin";
$username=$_POST["a"];
$password=$_POST["b"];
$password2=md5($_POST["c"]);
if ($_SERVER["REQUEST_METHOD"] != "POST")     
	{
		echo"<script>";
		echo"alert('GET is error !!!');";
		echo"location.href='login.html';"; 
		echo"</script>";
	}else{
		foreach ($_GET as $key => $value)
			{
				$$key = $$value; 
			}                     
		foreach ($_POST as $key => $value)
			{
				$$key = $value;
			}
		if ( strcmp($username,"Admin")==0 && strcmp($password,$flag)==0 && strcmp($password2,"5a690d842935c51f26f473e025c1b97a")==0 )
			{
				echo "This is your flag1{xxxxxx} :        ". $flag . "\n\n";
				die($_200);
				
			}else
			{
				echo"<script>";
				echo"alert('Wrong !!!');";
				echo"location.href='login.html';"; 
				echo"</script>";
			}
		}
?>

flag2.php

<?php 
$flag="flag2{xxxxxx}";   
?>

http://192.168.63.27/ctf/page2.php
username=Admin&password=0&password2=5a690d842935c51f26f473e025c1b97a&flag=0
This is your flag{AE2CB8C0F4961D30575E6596E97A0432} : 0 Welcome Admin

rockyou 破解得到 1qazxsw2

re

1.在生成随机码的函数,修改生成后的值为123456,再计算校验码。
2.修改对应的 srand的seed值,得到flag3。
根据算法逆向 卡数据"712DA50903F0451B9E383FC05C1B7DA8"对应的员工编号。

712DA50903F0451B9E383FC05C1B7DA8 取反后为 8ED25AF6FC0FBAE461C7C03FA3E48257

0-6 :    8ED25AF6FC0F   
6-12:    BAE461C7C03F
12-16:   A3E48257       -- hash值, 注意这里小端序,hash值为 0x5782E4A3

爆破时间求得

seed: 1669268303
// 2022-11-24 13:38:23 比较可靠, re1.exe程序的日期是 2022/11/25 15:24:05

关键函数

int __cdecl sub_4011C0(int uid, int out)
{
  int result; // eax
  int m; // [esp+0h] [ebp-40h]
  int k; // [esp+4h] [ebp-3Ch]
  int j; // [esp+8h] [ebp-38h]
  int i; // [esp+Ch] [ebp-34h]
  char enc[16]; // [esp+10h] [ebp-30h] BYREF
  int l; // [esp+20h] [ebp-20h]
  int hash; // [esp+24h] [ebp-1Ch]
  char TABLE[20]; // [esp+28h] [ebp-18h] BYREF

  memset(enc, 0, sizeof(enc));
  l = 0;
  hash = 1;
  for ( i = 0; i < 6; ++i )
  {
    enc[l] = rand();
    hash *= 31;
    hash += (unsigned __int8)enc[l++];          // 前6个为 rand 即得到的 8E,D2,5A,F6,FC,0F
  }
  for ( j = 0; j < 6; ++j )
  {
    enc[l] = j ^ enc[j] ^ *(_BYTE *)(j + uid);
    hash *= 31;
    hash += (unsigned __int8)enc[l++];          // 6-12为 异或值
  }
  *(_DWORD *)&enc[l] = hash;                    // 16-24 位为 hash值 小端序
  for ( k = 0; k < 16; ++k )
    enc[k] = ~enc[k];                           // 前16取反
  strcpy(TABLE, "0123456789ABCDEF");
  result = 0x42413938;
  for ( m = 0; m < 16; ++m )                    // 转16进制字符
  {
    *(_BYTE *)(out + 2 * m) = TABLE[(int)(unsigned __int8)enc[m] >> 4];
    *(_BYTE *)(out + 2 * m + 1) = TABLE[enc[m] & 0xF];
    result = m + 1;
  }
  return result;
}

使用z3解题如下。

from natsort import natsorted
from z3 import BitVec, Solver

hash = 1
l6 = [0x8E, 0xD2, 0x5A, 0xF6, 0xFC, 0x0F]
for i in range(6):
    hash = (hash * 31) & 0xffffffff
    hash = (hash + l6[i]) & 0xffffffff
print(hash)  # 854740660

uid = [BitVec('s1_%d' % i, 8) for i in range(6)]
solver = Solver()

con1 = bytes.fromhex('BAE461C7C03F')
for j in range(6):
    hash *= 31;
    tmp = j ^ l6[j] ^ uid[j]
    hash = (hash * 31) & 0xffffffff
    hash = (hash + tmp) & 0xffffffff
    solver.add(tmp == con1[j])
print(solver.check())
res = solver.model()

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='')
# 479285

C语言解题如下

#include "stdio.h"

int cmp(int *hash, char *enc, const char *uid_str) {
    int l = 6;
    char con1[] = {0xBA, 0xE4, 0x61, 0xC7, 0xC0, 0x3F};

    for (int j = 0; j < 6; j++) {
        unsigned char s = uid_str[j];
        enc[l] = j ^ enc[j] ^ s;
        if (enc[l] != con1[j]) {
            return 0;
        }
        *hash *= 31;
        *hash += (unsigned __int8) enc[l++];          // 6-12为 异或值
    }
    return 1;
}

int main(int argc, char *argv[], char **env) {
    setbuf(stdout, NULL);

    int hash = 1;
    char enc[16] = {};
    int l = 0;

    char lst[] = {0x8E, 0xD2, 0x5A, 0xF6, 0xFC, 0x0F};
    for (int i = 0; i < 6; ++i) {
        enc[l] = lst[i];
        hash *= 31;
        hash += (unsigned __int8) enc[l++];          // 前6个为 rand
    }
    printf("hash: %d, 0x%X\n", hash, hash); // 854740660, 0x32f24eb4
    int orihash = hash;

    for (int uid = 1; uid < 1000000; ++uid) {
        hash = orihash;
        char uid_str[6];
        snprintf(uid_str, 6 + 1, "%06d", uid);  // 需要 \0 占位所以 6+1

        if (!cmp(&hash, enc, uid_str))
            continue;

        if (hash == 0x5782E4A3) {
            printf("uid is : %d", uid);
            return 0;
        }
    }
    return 0;
}
posted @ 2022-12-22 21:10  wgf4242  阅读(753)  评论(0编辑  收藏  举报