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;
}