[jule2022] warmup 部分

jule2022这个比赛到目前才30+人参赛,比赛时间有9天,正赛还没有结束,所以先不写。这是比赛前的热身部分。这部分不计分。

估计有些人是因为找不到入口链接,又是国外的比赛,不放脑瓜顶上确实不好找。

01

这个忘了叫啥名了,给了一篇全大写的文章,字母被替换了。字频好像不大准还不如眼准。比如单个字符也就是I,a,两个的in,on,of,an,还有最常见的the,手工换完得到一个转换表。

ABCDEFGHIJKLMNOPQRSTUVWXYZ
rfdscobqlgtmawkpxhenzuyvji

根据这个表把加密的flag转一下,再包上壳就OK了

nsii_nsii_nsii_rfn_krs_kvatkmgisd
well_well_well_how_the_turntables

02 I was tangled in.. in.. strings

这是个逆向题,内容比较简单,IDA打开找到密码,输入密码就给flag

int __cdecl main(int argc, const char **argv, const char **envp)
{
  unsigned int i; // [esp+0h] [ebp-C4h]
  size_t v5; // [esp+4h] [ebp-C0h]
  int v6[9]; // [esp+8h] [ebp-BCh]
  __int16 v7; // [esp+2Ch] [ebp-98h]
  int v8[9]; // [esp+2Eh] [ebp-96h]
  __int16 v9; // [esp+52h] [ebp-72h]
  char s[100]; // [esp+54h] [ebp-70h] BYREF
  unsigned int v11; // [esp+B8h] [ebp-Ch]
  int *p_argc; // [esp+BCh] [ebp-8h]

  p_argc = &argc;
  v11 = __readgsdword(0x14u);
  printf("=== Legionnaire OS v2.31 ===\n\nPASSWORD PROTECTED\nEnter password: ");
  fgets(s, 100, stdin);
  v5 = strlen(s);
  if ( v5 && s[v5 - 1] == 10 )
    s[v5 - 1] = 0;
  puts("Checking password...");
  sleep(2u);
  if ( !strcmp(pass, s) )
  {
    v6[0] = -1217341131;
    v6[1] = 395690639;
    v6[2] = -1332891898;
    v6[3] = -1612059337;
    v6[4] = 1522026396;
    v6[5] = -477460208;
    v6[6] = 689504828;
    v6[7] = 933803535;
    v6[8] = 689362930;
    v7 = 30952;
    v8[0] = -868840074;
    v8[1] = 603823550;
    v8[2] = -989925278;
    v8[3] = -125313979;
    v8[4] = 802822374;
    v8[5] = -739977628;
    v8[6] = 1143496011;
    v8[7] = 1390071888;
    v8[8] = 443790017;
    v9 = 1421;
    for ( i = 0; i <= 0x25; ++i )
      putchar((char)(*((_BYTE *)v6 + i) ^ *((_BYTE *)v8 + i)));
    putchar(10);
  }
  else
  {
    puts("YOU ARE NOT WORTHY!!");
  }
  return 0;
}

当然也可以把这些变量转字符,注意小端。(显然不是专为本次比赛出的题,flag壳都不一样)

┌──(kali㉿kali)-[~/ctf/other]
└─$ ./legionnaire                              
=== Legionnaire OS v2.31 ===

PASSWORD PROTECTED
Enter password: AV3ryL0ngAndH4rdc0dedP4ssw0rd
Checking password...
CTF{1_h4d_str1ngz_but_n0w_1m_fre3ee3e}

03 ZopCrypti

这是个misc题,附件是个压缩包,打开是一个文件和一个带密码的压缩包,这个文件在压缩包里也有一个相同的。显然是zip的明文攻击,不过包是unix格式找的。在win上软件处理不了,但在linux 下用pkcrack也报错。

04 secret words

又回到逆向,是个异或题,密文和key都给出

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v3; // r12
  size_t v4; // rax
  int i; // [rsp+4h] [rbp-6Ch]
  char s1[5]; // [rsp+Bh] [rbp-65h] BYREF
  char v8[8]; // [rsp+10h] [rbp-60h] BYREF
  __int64 v9; // [rsp+18h] [rbp-58h]
  int v10; // [rsp+20h] [rbp-50h]
  char s[40]; // [rsp+30h] [rbp-40h] BYREF
  unsigned __int64 v12; // [rsp+58h] [rbp-18h]

  v12 = __readfsqword(0x28u);
  *(_QWORD *)v8 = 0x5F1D1D1F15285B3FLL;
  v9 = 0x5A1F045C0D300E02LL;
  v10 = 0x125A3E;
  strcpy(s1, "lion");
  printf("What is the secret word? ");
  fgets(s, 32, stdin);
  s[strlen(s) - 1] = 0;
  if ( !strcmp(s1, s) )
  {
    puts("Correct!");
    for ( i = 0; i < strlen(v8); ++i )
    {
      v3 = v8[i];
      v4 = strlen(s1);
      putchar(v3 ^ (unsigned __int8)s1[i % v4]);
    }
    putchar(10);
  }
  else
  {
    puts("Wrong!");
  }
  return 0;
}

确实是热身,

v8 = b'_\x1D\x1D\x1F\x15([?'[::-1]+b'Z\x1F\x04\\\r0\x0E\x02'[::-1]+b'\x12Z>'[::-1]
from pwn import xor
xor(b'lion', v8)
#b'S2G{str1ng_c0mp4R3}'

05 M4

这是个enigma加密,但是未知参数太多了,不知道怎么弄

from enigma.machine import EnigmaMachine
import string
import random
import datetime
import time

# Wrap the flag inside S2G{...}
flag = 'FAKEFLAG'

morse_code_dict = { 'A':'.-', 'B':'-...', 'C':'-.-.', 'D':'-..', 'E':'.', 'F':'..-.', 'G':'--.', 'H':'....', 'I':'..', 'J':'.---', 'K':'-.-', 'L':'.-..', 'M':'--', 'N':'-.', 'O':'---', 'P':'.--.', 'Q':'--.-', 'R':'.-.', 'S':'...', 'T':'-', 'U':'..-', 'V':'...-', 'W':'.--', 'X':'-..-', 'Y':'-.--', 'Z':'--..'}

with open('german.txt') as f:
    wordlist = [w.strip() for w in f.read().split('\n')]
    wordlist = [w.upper() for w in wordlist]
    wordlist = [w.replace('Ö', 'OE') for w in wordlist]
    wordlist = [w.replace('Ä', 'AE') for w in wordlist]
    wordlist = [w.replace('Ü', 'UE') for w in wordlist]
    wordlist = list(filter(lambda w: len(w) > 0 and all(c in string.ascii_uppercase for c in w), wordlist))

def generate_machine():
    rotors = [random.choice(['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'Beta', 'Gamma']) for _ in range(3)]
    reflector = random.choice(['B', 'C', 'B-Thin', 'C-Thin'])
    ring_settings = ' '.join([random.choice(string.ascii_uppercase) for _ in range(3)])

    plugboard_chars = list(string.ascii_uppercase)
    random.shuffle(plugboard_chars)
    plugboard_settings = ' '.join(''.join(plugboard_chars[j*10+i] for j in range(2)) for i in range(10))

    machine = EnigmaMachine.from_key_sheet(
           rotors=rotors,
           reflector=reflector,
           ring_settings=ring_settings,
           plugboard_settings=plugboard_settings
    )

    return machine

def generate_daily_machine():
    global daily_machine, daily_machine_display
    daily_machine = generate_machine()
    daily_machine_display = ''.join(random.choice(string.ascii_uppercase) for _ in range(3))  #3个 大写字母

def generate_message():
    message = ''.join(random.choice(wordlist) for _ in range(random.randint(1, 50)))
    message += flag
    return message

def encrypt_message(machine, machine_display, message):
    machine.set_display(machine_display)
    enc = machine.process_text(message)
    
    return ' '.join(map(lambda x: morse_code_dict[x], enc))

start_date = datetime.datetime(1942, 2, 2, 0, 0, 0)
end_date = datetime.datetime(1943, 3, 17, 0, 0, 0)

current_timestamp = time.mktime(start_date.timetuple()) + random.randint(1, 60 * 60 * 3)
end_timestamp = time.mktime(end_date.timetuple())

generate_daily_machine()

messages = []
while current_timestamp < end_timestamp:
    message = encrypt_message(daily_machine, daily_machine_display, generate_message())
    date = datetime.datetime.fromtimestamp(current_timestamp).strftime("%Y-%m-%d %H:%M:%S")

    message = f'[{date}]: {message}'
    messages.append(message)

    last_timestamp = current_timestamp
    current_timestamp += random.randint(1, 60 * 60 * 3)

    if datetime.datetime.fromtimestamp(last_timestamp).date() != datetime.datetime.fromtimestamp(current_timestamp).date():
        generate_daily_machine()

with open('intercepted.txt', 'w') as f:
    f.write('\n'.join(messages))

同一数据加padding 加密N多次,但中间参数不停地取随机数。不知道怎么弄了。

06 Hidden

这个就没的说了,flag文件名是.flag.txt 这在unix下会隐身,但在windows下直接就显示了。

07 Password manager

这个给了一堆密文,但没给远端,光从几个密文上推似乎不大可能,如果有远端???

from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad

passwords_directory = './passwords/'

def encrypt(site, username, password):
    plaintext = pad(f'{username}||{password}'.encode(), AES.block_size)
    with open(f'{passwords_directory}{site}.enc', 'wb') as f:
        ciphertext = cipher.encrypt(plaintext)
        f.write(ciphertext)

def decrypt(site):
    with open(f'{passwords_directory}{site}.enc', 'rb') as f:
        ciphertext = f.read()
        plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size)
        username, password = plaintext.decode().split('||')
        return [username, password]

def print_commands():
    print('Commands:')
    print('\t1. Encrypt')
    print('\t2. Decrypt')
    print('\t0. Exit')

print('Welcome back, Frank!')
master_password = input('Enter your master password to continue: ')
cipher = AES.new(master_password.encode(), AES.MODE_ECB)

print_commands()
while (cmd := input('Enter command: ')) != '0':
    if cmd == '1':
        site     = input('Site: ')
        username = input('Username: ')
        password = input('Password: ')
        encrypt(site, username, password)
        print('Successfully encrypted the username and password!')
    elif cmd == '2':
        site     = input('Site: ')
        username, password = decrypt(site)
        print(f'Username: {username}')
        print(f'Password: {password}')
    else:
        print('Invalid command.')
    print()
    print_commands()

08 RSA

一个p,q都给了的RSA

p = 0xa362776cb254f1d1acd87499eb4eeedbb9e46dcb4c534e82ac6b004c47a062593b408e15d258fae7dd529e80a5f1f50e1bcedd243f8e1f82feacdad83ee83149c7ca518e4f72f149c724175a8ab23aa2cf9b6a4fe5696150820d24d1ef6b817d5ede5889087a030359b5ffb1d0e6909fcfd387cc2bf2f1f43728cc63823b3959
q = 0x84269ba361b3446c90d6f0cf69bd106c2d9ca57e3bdfce2aa39d216eabccbcfe2a5cce0c21d420b15fa4775941dec1368c5495eba1673752dfa66a5fe5670022a05a2ea878a89844cee43ba555f892132d501aff10fae4ca9b4a1731259637c84b98571a8da5d634284f2d5e7c77753fa56cefab72cc8ed92b5f62873e04b605
N = 0x54576986aa71d8401f05e3d5c602068580d152be05841dc76f838e0a00e30914d17be60e16bfe416292316d4c0a4d4efe8523ab675b02fa050a3179ce69df420b0d895d862147eb9ebe643e404751962e62ae0a3a010f34f96f14910319378e615a966d6cd483308ed1e87c4cfd911a505675399a7d41b5aca17b2e3b9f7e64635dfcb4e969594bd0c8cdd3391464b0e030ee61852121593ef3d7b1f8c4971c39b0400370827ba343c0b1bf2cd1b79581ef8484eb5823409f09160179d3d5ea16c98a11e44c59b97b7efd9f5befbef7e62174dacbdb2ad99325df0ccaf59bb38f0e83b70ac3d29dbae9a111cf94ad0646907bac4586d3880f4696d47195164bd
e = 0x10001
c = 0x4660a7e3c58f7597807a454f20c633232ed3ccd263cb48a342fe42b559939565fdc2e6cf7ac240e6d553b5d17f9746902bbc9d33d73bb5a70c697dad138f61a7c6ca524408d05f646f01f782e5aca8f159234619855c65392bf7f050884f3862d7e9e02a78a5cdb7d3809201a75f8ce6b1025a3fdf84f0f918db723bdf24c1980a0bb3a0878596aaaea96fa6f31d2e7e09c6e8638d040ca2786e623a1be5afa8c19a072dae6b34015b86ec057c37c7c625bb2c90dda0fcc877952bace1cb8db0f8f2fc82cadb6115098be05250801b18aa31ce8fa8d12423f1b5674b28de38f2557388b5e0b9569dcef469c295666bbe121d70cf84146119610e316e0945f0f

#sage
phi = (p-1)*(q-1)
d = inverse_mod(e,phi)
m = pow(c,d,N)
bytes.fromhex(hex(m)[2:])
b'S2G{y0U_d3CrYpt3d_Th3_RSA_3NcRyp73d_S3cR3t_m3sS4G3!!!}'

09 Leak

给了一个SQLite3的数据库表文件,打开似乎不大容易还得安装软件,直接按文本打开搜S2G的base64找到

在文件中搜base64('S2G{')   UzJH 

UzJHe2Q0dDRiNHMzX2wzNGshfQ==
S2G{d4t4b4s3_l34k!}

反正是热身赛,都无所谓,作着玩玩。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值