CTFZone 2022 Writeup

この大会は2022/8/25 0:00(JST)~2022/8/27 0:00(JST)に開催されました。
今回もチームで参戦。結果は1166点で145チーム中51位でした。
自分で解けた問題をWriteupとして書いておきます。

statham (misc)

[Let's go]ボタンをクリックして、開始する。

Task 1から順に解いていく必要がありそう。Task 1はkdbxのパスワードをクラックする。

$ keepass2john Database.kdbx > hash.txt

hash.txtの先頭の"Database:"を削除して、hashcatでクラックする。

>hashcat -a 0 -m 13400 hash.txt dict/rockyou.txt
hashcat (v6.2.4) starting

OpenCL API (OpenCL 3.0 ) - Platform #1 [Intel(R) Corporation]
=============================================================
* Device #1: Intel(R) UHD Graphics 630, 3200/6484 MB (1621 MB allocatable), 24MCU

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Optimizers applied:
* Zero-Byte
* Single-Hash
* Single-Salt

Watchdog: Hardware monitoring interface not found on your system.
Watchdog: Temperature abort trigger disabled.

Host memory required for this attack: 974 MB

Dictionary cache hit:
* Filename..: dict/rockyou.txt
* Passwords.: 14344384
* Bytes.....: 139921497
* Keyspace..: 14344384

[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit =>

Session..........: hashcat
Status...........: Running
Hash.Mode........: 13400 (KeePass 1 (AES/Twofish) and KeePass 2 (AES))
Hash.Target......: $keepass$*2*60000*0*9ad1c2e55b2ebabd1f4b6c4e89f0606...43f238
Time.Started.....: Thu Aug 25 23:43:49 2022 (13 hours, 7 mins)
Time.Estimated...: Fri Aug 26 23:48:47 2022 (10 hours, 57 mins)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (dict/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:      166 H/s (9.01ms) @ Accel:64 Loops:8 Thr:16 Vec:1
Recovered........: 0/1 (0.00%) Digests
Progress.........: 7815168/14344384 (54.48%)
Rejected.........: 0/7815168 (0.00%)
Restore.Point....: 7815168/14344384 (54.48%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:22600-22608
Candidate.Engine.: Device Generator
Candidates.#1....: goooo3 -> gocubs25

$keepass$*2*60000*0*9ad1c2e55b2ebabd1f4b6c4e89f06062aa0a4c78e21f69a9b13a7267310843df*770a9fee79c3283537a6fc1d452288a0705020a8c8b221d5efd31810be96f59b*eba5d5a0efb17466b63931db6d75ee0b*21a1ac356b03ba2b7485267f0aab1d928bc8e403268ff11f17977d58a93dc436*c95a63c7f541889409d844a73e35b94ee298c5b5a20b782942151f968e43f238:g33kpop

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 13400 (KeePass 1 (AES/Twofish) and KeePass 2 (AES))
Hash.Target......: $keepass$*2*60000*0*9ad1c2e55b2ebabd1f4b6c4e89f0606...43f238
Time.Started.....: Thu Aug 25 23:43:49 2022 (13 hours, 16 mins)
Time.Estimated...: Fri Aug 26 13:00:04 2022 (0 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (dict/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:      168 H/s (9.00ms) @ Accel:64 Loops:8 Thr:16 Vec:1
Recovered........: 1/1 (100.00%) Digests
Progress.........: 8011776/14344384 (55.85%)
Rejected.........: 0/8011776 (0.00%)
Restore.Point....: 7987200/14344384 (55.68%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:59992-60000
Candidate.Engine.: Device Generator
Candidates.#1....: g3ni3ll3 -> fucku7615

Started: Thu Aug 25 23:43:37 2022
Stopped: Fri Aug 26 13:00:05 2022

パスワードは"g33kpop"。KeePassで開き、Master passwordに"g33kpop"を指定すると、ログインできる。中には7つのパスワードが設定されている。Title: Secretの情報は以下の通り。

User Name: Jason_Statham
Password: DefInIte1y_inc0rrect_Pa$$w0rd

[Task 2]ボタンをクリックし、このID/PWを入力しても、認証されない。KeePassのSecretの情報をよく見ると、パスワードは一回変更されていて、前のパスワードは以下の通り。

Y0u_@re_@1m0st_theRe

このパスワードでもダメだった。さらによく見ると、Advancedにreal_password.pngが添付されている。

この画像を見ると、こう書いてある。

6fV6bwYm4b0VUHPp

これをパスワードとして、Jason_Statham / 6fV6bwYm4b0VUHPp でログインする。

ようやくTask 2に進める。Task 2 のIDは"I_L0ve_Pies"と指定されている。パスワードは円周率の部分文字列"1337"の1337番目の位置。Pythonでsympyライブラリを使って算出する。

#!/usr/bin/env python3
import sympy

pi = str(sympy.pi.evalf(100000000))

count = 0
idx = 0
while True:
    idx = pi[1:].find('1337', idx)
    if idx > 0:
        count += 1
    else:
        print('Error! idx=', idx)
        break
    if count == 1337:
        break
    idx += 1

print(idx)

実行結果は以下の通り。

13578220

[Task 3]ボタンをクリックし、I_L0ve_Pies / 13578220 を入力する。

するとログインでき、Task 3のページに入れる。このページの下部に[Flag]ボタンがあるので、これで最後のようだ。何重にもzip圧縮されているので、解凍していく。その際ファイル名に意味がありそうなので、連結していく。

#!/usr/bin/env python3
import zipfile

zips = ['1_Ever.zip']

while True:
    try:
        with zipfile.ZipFile(zips[-1]) as zf:
            name = zf.namelist()[0]
            zips.append(name)
            zf.extractall('')
    except:
        break

msg = ''
i = 1
for zip in zips:
    num = int(zip.split('_')[0])
    if i == num:
        msg += zip.split('_')[1].split('.')[0] + ' '
    else:
        break
    i += 1

msg = msg[:-1]
print(msg)

実行結果は以下の通り。

Ever since the railroad had been officially inaugurated and had begun to arrive with regularity on Wednesdays at eleven oΓÇÖclock and the primitive wooden station with a desk, a telephone, and a ticket window had been built, on the streets of Macondo men and women were seen who had adopted everyday and normal customs and manners but who really looked like people out of a circus; In a town that had chafed under the tricks of the gypsies there was no future for those ambulatory acrobats of commerce who with equal effrontery offered a whistling kettle and a daily regime that would assure the salvation of the soul on the seventh day; but from those who let themselves be convinced out of fatigue and the ones who were always unwary, they reaped stupendous benefits; Among those theatrical creatures, wearing riding breeches and leggings, a pith helmet and steel-rimmed glasses, with topaz eyes and the skin of a thin rooster, there arrived in Macondo on one of so many Wednesdays the chubby and smiling Mr; Herbert, who ate at the house; No one had noticed him at the table until the first bunch of bananas had been eaten; Aureliano Segundo had come across him by chance as he protested In broken Spanish because there were no rooms at the Hotel Jacob, and as he frequently did with strangers, he took him home; Actually, the key you are looking for is in the file number one thousand two hundred fifty two; He was in the captive-balloon business, which had taken him halfway around the world with excellent profits, but he had not succeeded in taking anyone up in Macondo because they considered that invention backward after having seen and tried the gypsiesΓÇÖ flying carpets; He was leaving, therefore, on the next train; When they brought to the table the tiger-striped bunch of bananas that they were accustomed to hang in the dining room during lunch, he picked the first piece of fruit without great enthusiasm; But he kept on eating as he spoke, tasting, chewing, more with the distraction of a wise man than with the delight of a good eater, and when he finished the first bunch he asked them to bring him another; Then he took a small case with optical instruments out of the toolbox that he always carried with him; With the auspicious attention of a diamond merchant he examined the banana meticulously, dissecting it with a special scalpel, weighing the pieces on a pharmacistΓÇÖs scale, and calculating its breadth with a gunsmithΓÇÖs calipers; Then he took a series of instruments out of the chest with which he measured the temperature, the level of humidity in the atmosphere, and the intensity of the light; It was such an intriguing ceremony that no one could eat in peace as everybody waited for Mr; Herbert to pass a final and revealing judgment, but he did not say anything that allowed anyone to guess his intentions; On the days that followed he was seen with a net and a small basket hunting butterflies on the outskirts of town; On Wednesday a group of engineers, agronomists, hydrologists, topographers, and surveyors arrived who for several weeks explored the places where Mr; Herbert had hunted his butterflies; Later on Mr; Jack Brown arrived in an extra coach that had been coupled onto the yellow train and that was silver-plated all over, with seats of episcopal velvet, and a roof of blue glass; Also arriving on the special car, fluttering around Mr; Brown, were the solemn lawyers dressed in black who in different times had followed Colonel Aureliano Buendia everywhere, and that led the people to think that the agronomists, hydrologists, topographers, and surveyors, like Mr; Herbert with his captive balloons and his colored butterflies and Mr; Brown with his mausoleum on wheels and his ferocious German shepherd dogs, had something to do with the war; There was not much time to think about it, however, because the suspicious inhabitants of Macondo barely began to wonder what the devil was going on when the town had already become transformed into an encampment of wooden houses with zinc roofs inhabited by foreigners who arrived on the train from halfway around the world, riding not only on the seats and platforms but even on the roof of the coaches; The gringos, who later on brought their languid wives in muslin dresses and large veiled hats, built a separate town across the railroad tracks with streets lined with palm trees, houses with screened win┬¼ dows, small white tables on the terraces, and fans mounted on the ceilings, and extensive blue lawns with peacocks and quails; The section was surrounded by a metal fence topped with a band of electrified chicken wire which during the cool summer mornings would be black with roasted swallows; No one knew yet what they were after, or whether they were actually nothing but philanthropists, and they had already caused a colossal disturbance, much more than that of the old gypsies, but less transitory and understandable; Endowed with means that had been reserved for Divine Providence in former times, they changed the pattern of the rams, accelerated the cycle of harvest, and moved the river from where it had always been and put it with its white stones and icy currents on the other side of the town, behind the cemetery; It was at that time that they built a fortress of reinforced concrete over the faded tomb of Jose Arcadio, so that the corpses smell of powder would not contaminate the waters; For the foreigners who arrived without love they converted the street of the loving matrons from France into a more extensive village than it had been, and on one glorious Wednesday they brought in a trainload of strange whores, Babylonish women skilled in age-old methods and in possession of all manner of unguents and devices to stimulate the unaroused, to give courage to the timid, to satiate the voracious, to exalt the modest man, to teach a lesson to repeaters, and to correct solitary people; The Street of the Turks, enriched by well-lit stores with products from abroad, displacing the old bazaars with their bright colors, overflowed on Saturday nights with the crowds of adventurers who bumped into each other among gambling tables, shooting galleries, the alley where the future was guessed and dreams interpreted, and tables of fried food and drinks, and on Sunday mornings there were scattered on the ground bodies that were sometimes those of happy dmnkards and more often those of onlookers felled by shots, fists, knives, and bottles during the brawls; It was such a tumultuous and intemperate invasion that during the first days it was impossible to walk through the streets because of the furniture and trunks, and the noise of the carpentry of those who were building their houses in any vacant lot without asking anyoneΓÇÖs permission, and the scandalous behavior of couples who hung their hammocks between the almond trees and made love under the netting in broad daylight and in view of everyone; The only serene corner had been established by peaceful West Indian Negroes, who built a marginal street with wooden houses on piles where they would sit in the doors at dusk singing melancholy hymns in their disordered gabble; So many changes took place in such a short time that eight months after Mr; HerbertΓÇÖs visit the old inhabitants had a hard time recognizing their own town; ΓÇ£Look at the mess weΓÇÖve got ourselves into,ΓÇ\ Colonel Aureliano Buendia said at that time, ΓÇ£just because we invited a gringo to eat some bananas;ΓÇ\ Aureliano Segundo, on the other hand, could not contain his happiness over the avalanche of foreigners; The house was suddenly filled with unknown guests, with invincible and worldly carousers, and it became necessary to add bedrooms off the courtyard, widen the dining room, and exchange the old table for one that held sixteen people, with new china and silver, and even then they had to eat lunch in shifts; Fernanda had to swallow her scmples and their guests of the worst sort like kings as they muddied the porch with their boots, urinated in the garden, laid their mats down anywhere to take their siesta, and spoke without regard for the sensitivities of ladies or the proper behavior of gentlemen; Amaranta, was so scandalized with the plebeian invasion that she went back to eating in the kitchen as in olden days; Colonel Aureliano Buendia, convinced that the majority of those who came into Inis workshop to greet him were not doing it because of sympathy or regard but out of the curiosity to meet a historical relic, a museum fossil, decided to shut himself in by barring the door and he was not seen any more except on very rare occasions when he would sit at the street door; Ursula, on the other hand, even during the days when she was already dragging her feet and walking about groping along the walls, felt a juvenile excitement as the time for the arrival of the train approached; ΓÇ£We have to prepare some meat and fish,ΓÇ\ she would order the four cooks, who hastened to have everything ready under the imperturbable direction of Santa Sofia de la Piedad; ΓÇ£We have to prepare everything,ΓÇ\ she insisted, ΓÇ£because we never know what these strangers like to eat;ΓÇ\ The train arrived during the hottest time of day; At lunchtime the house shook with the bustle of a marketplace, and the perspiring guestsΓÇöwho did not even know who their hosts wereΓÇö trooped in to occupy the best places at the table, while the cooks bumped into each other with enormous kettles of soup, pots of meat, large gourds filled with vegetables, and troughs of rice, and passed around the contents of barrels of lemonade with inexhaustible ladles; The disorder was such that Fernanda was troubled by the idea that many were eating twice and on more than one occasion she was about to burst out with a vegetable hawkerΓÇÖs insults because someone at the table in confusion asked her for the check; More than a year had gone by since Mr; HerbertΓÇÖs visit and the only thing that was known was that the gringos were planning to plant banana trees in the enchanted region that Jose Arcadio Buendia and his men had crossed in search of the route to the great inventions; Two other sons of Colonel Aureliano Buendia, with the cross of ashes on their foreheads, arrived, drawn by that great volcanic belch, and they justified their determination with a phrase that may have explained everybodyΓÇÖs reasons; ΓÇ£We came,ΓÇ\ they said, ΓÇ£because everyone is coming;ΓÇ\ Remedios the Beauty was the only one who was immune to the banana plague; She was becalmed in a magnificent adolescence, more and more impenetrable to formality, more and more indifferent to malice and suspicion, happy in her own world of simple realities; She did not understand why women complicated their lives with corsets and petticoats, so she sewed herself a coarse cassock that she simply put over her and without further difficulties resolved the problem of dress, without taking away the feeling of being naked, which according to her lights was the only decent way to be when at home; They bothered her so much to cut the rain of hair that already reached to her thighs and to make rolls with combs and braids with red ribbons that she simply shaved her head and used the hair to make wigs for the saints; The startling thing about her simplifying instinct was that the more she did away with fashion in a search for comfort and the more she passed over conventions as she obeyed spontaneity, the more disturbing her incredible beauty became and the more provocative she became to men; When the sons of Colonel Aureliano Buendfa were in Macondo for the first time, Ursula remembered that in their veins they bore the same blood as her great- granddaughter and she shuddered with a forgotten fright; ΓÇ£Keep your eyes wide open,ΓÇ\ she warned her; ΓÇ£With any of them your children will come out with the tail of a pig;ΓÇ\ The girl paid such little attention to the warning that she dressed up as a man and rolled around in the sand in order to climb the greased pole, and she was at the point of bringing on a tragedy among the seventeen cousins, who were driven mad by the unbearable

文章中に以下の文がある。

Actually, the key you are looking for is in the file number one thousand two hundred fifty two;

鍵はファイル番号1252のファイルにあるということらしい。

$ zipinfo -z 1252_weΓÇÖve.zip 
Archive:  1252_weΓÇÖve.zip
Impressive! login: "Json_Statham_4evar", password: "JpxCDPs7WswzyqPB"
Zip file size: 224580 bytes, number of entries: 1
-rw-r--r--  3.0 unx   224315 bx defX 22-Jun-10 19:35 1253_got.zip
1 file, 224315 bytes uncompressed, 224337 bytes compressed:  0.0%

ID/PWについて、コメントに書いてある。

login: Json_Statham_4evar
password: JpxCDPs7WswzyqPB

[Flag]ボタンをクリックし、Json_Statham_4evar / JpxCDPs7WswzyqPB を入力すると、フラグが表示された。

CTFZone{57@TH4M_cHAiN_M1sk}

Yet Another Des (reverse, crypto)

$ strings main.exe | grep python
4python38.dll

pythonコードからexeにした可能性が高い。まず、pyinstxtractor.pyでモジュールを抽出する。

$ python3 pyinstxtractor.py main.exe
[+] Processing main.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.8
[+] Length of package: 655205 bytes
[+] Found 9 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_subprocess.pyc
[+] Possible entry point: main.pyc
[+] Found 78 files in PYZ archive
[+] Successfully extracted pyinstaller archive: main.exe

You can now use a python decompiler on the pyc files within the extracted directory

次に生成されたディレクトリ配下にあるmain.pycをデコンパイルする。

$ cd main.exe_extracted/
$ uncompyle6 main.pyc
# uncompyle6 version 3.8.0
# Python bytecode 3.8.0 (3413)
# Decompiled from: Python 3.8.10 (default, Jun 22 2022, 20:18:18) 
# [GCC 9.4.0]
# Embedded file name: main.py
import operator
from textwrap import wrap
from functools import reduce
KEY = '8324465191921420'
INITIAL_PERMUTATION = [
 57, 49, 41, 33, 25, 17, 9, 1,
 59, 51, 43, 35, 27, 19, 11, 3,
 61, 53, 45, 37, 29, 21, 13, 5,
 63, 55, 47, 39, 31, 23, 15, 7,
 56, 48, 40, 32, 24, 16, 8, 0,
 58, 50, 42, 34, 26, 18, 10, 2,
 60, 52, 44, 36, 28, 20, 12, 4,
 62, 54, 46, 38, 30, 22, 14, 6]
INVERSE_PERMUTATION = [
 39, 7, 47, 15, 55, 23, 63, 31,
 38, 6, 46, 14, 54, 22, 62, 30,
 37, 5, 45, 13, 53, 21, 61, 29,
 36, 4, 44, 12, 52, 20, 60, 28,
 35, 3, 43, 11, 51, 19, 59, 27,
 34, 2, 42, 10, 50, 18, 58, 26,
 33, 1, 41, 9, 49, 17, 57, 25,
 32, 0, 40, 8, 48, 16, 56, 24]
SUB_BOXES = [
 [
  14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
  0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
  4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
  15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],
 [
  15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
  3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
  0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
  13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],
 [
  10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
  13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
  13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
  1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],
 [
  7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
  13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
  10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
  3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],
 [
  2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
  14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
  4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
  11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
 [
  12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
  10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
  9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
  4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],
 [
  4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
  13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
  1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
  6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],
 [
  13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
  1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
  7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
  2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]
EXPANSION = [
 31, 0, 1, 2, 3, 4,
 3, 4, 5, 6, 7, 8,
 7, 8, 9, 10, 11, 12,
 11, 12, 13, 14, 15, 16,
 15, 16, 17, 18, 19, 20,
 19, 20, 21, 22, 23, 24,
 23, 24, 25, 26, 27, 28,
 27, 28, 29, 30, 31, 0]
PERMUTATION = [
 15, 6, 19, 20, 28, 11, 27, 16,
 0, 14, 22, 25, 4, 17, 30, 9,
 1, 7, 23, 13, 31, 26, 2, 8,
 18, 12, 29, 5, 21, 10, 3, 24]
PERMUTED_CHOICE_1 = [
 56, 48, 40, 32, 24, 16, 8,
 0, 57, 49, 41, 33, 25, 17,
 9, 1, 58, 50, 42, 34, 26,
 18, 10, 2, 59, 51, 43, 35,
 62, 54, 46, 38, 30, 22, 14,
 6, 61, 53, 45, 37, 29, 21,
 13, 5, 60, 52, 44, 36, 28,
 20, 12, 4, 27, 19, 11, 3]
PERMUTED_CHOICE_2 = [
 13, 16, 10, 23, 0, 4,
 2, 27, 14, 5, 20, 9,
 22, 18, 11, 3, 25, 7,
 15, 6, 26, 19, 12, 1,
 40, 51, 30, 36, 46, 54,
 29, 39, 50, 44, 32, 47,
 43, 48, 38, 55, 33, 52,
 45, 41, 49, 35, 28, 31]
ROTATES = [
 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]

def slice_string(string):
    return [i.zfill(16) for i in wrap(''.join([hex(ord(i))[2:] for i in string]), 16)]


def to_bin(s):
    return ''.join([bin(int(i, 16))[2:].zfill(4) for i in s])


def permutation(block, box):
    return ''.join([block[i] for i in box])


def xor(arg_1, arg_2):
    return ''.join([str(int(i) ^ int(j)) for i, j in zip(arg_1, arg_2)])


def concatenate(args):
    return reduce(operator.iadd, args, [])


def rotate_left(block, i):
    return bin(int(block, 2) << i & 268435455 | int(block, 2) >> 28 - i)[2:].zfill(28)


def key_gen(block_1, block_2):
    li = []
    for i in ROTATES:
        block_1 = rotate_left(block_1, i)
        block_2 = rotate_left(block_2, i)
        li.append(permutation(block_1 + block_2, PERMUTED_CHOICE_2))
    else:
        return li


def f(block, key):
    final = []
    for j, i in enumerate(wrap(xor(permutation(block, EXPANSION), key), 6)):
        temp_box = [SUB_BOXES[0][0:16],
         SUB_BOXES[0][16:32],
         SUB_BOXES[0][32:48],
         SUB_BOXES[0][48:64]]
        final.append(bin(temp_box[int(i[0] + i[(-1)], 2)][int(i[1:-1], 2)])[2:].zfill(4))
    else:
        return permutation(''.join(final), PERMUTATION)


def des(block, key_array):
    left, right = block[0:len(block) // 2], block[len(block) // 2:]
    for j, i in zip(range(1, 17), key_array):
        right, left = xor(f(right, i), left), right
    else:
        return wrap(permutation(right + left, INVERSE_PERMUTATION), 8)


def main(string):
    encrypted_list = []
    for i in slice_string(string):
        bin_mess, bin_key = to_bin(i), to_bin(KEY)
        permuted_key, permuted_block = permutation(bin_key, PERMUTED_CHOICE_1), permutation(bin_mess, INITIAL_PERMUTATION)
        key_list = key_gen(permuted_key[:len(permuted_key) // 2], permuted_key[len(permuted_key) // 2:])
        encrypted_list.append(''.join([hex(int(i, 2))[2:].zfill(2).lower() for i in des(permuted_block, key_list)]))
    else:
        return ''.join(encrypted_list)


flag = main(input('Input sentence: '))
print(flag)
flag = '7cd245e589aa384ac19dddfafb189650e8c1e6eb13fd52bc'
input()
# okay decompiling main.pyc

KEYは分かっているので、逆算すればよい。

#!/usr/bin/env python3
from textwrap import wrap

KEY = '8324465191921420'
INITIAL_PERMUTATION = [
    57, 49, 41, 33, 25, 17, 9, 1,
    59, 51, 43, 35, 27, 19, 11, 3,
    61, 53, 45, 37, 29, 21, 13, 5,
    63, 55, 47, 39, 31, 23, 15, 7,
    56, 48, 40, 32, 24, 16, 8, 0,
    58, 50, 42, 34, 26, 18, 10, 2,
    60, 52, 44, 36, 28, 20, 12, 4,
    62, 54, 46, 38, 30, 22, 14, 6]

INVERSE_PERMUTATION = [
    39, 7, 47, 15, 55, 23, 63, 31,
    38, 6, 46, 14, 54, 22, 62, 30,
    37, 5, 45, 13, 53, 21, 61, 29,
    36, 4, 44, 12, 52, 20, 60, 28,
    35, 3, 43, 11, 51, 19, 59, 27,
    34, 2, 42, 10, 50, 18, 58, 26,
    33, 1, 41, 9, 49, 17, 57, 25,
    32, 0, 40, 8, 48, 16, 56, 24]

SUB_BOXES = [
    [
        14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
        0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
        4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
        15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],
    [
        15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
        3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
        0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
        13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],
    [
        10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
        13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
        13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
        1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],
    [
        7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
        13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
        10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
        3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],
    [
        2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
        14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
        4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
        11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],
    [
        12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
        10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
        9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
        4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],
    [
        4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
        13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
        1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
        6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],
    [
        13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
        1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
        7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
        2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]]

EXPANSION = [
    31, 0, 1, 2, 3, 4,
    3, 4, 5, 6, 7, 8,
    7, 8, 9, 10, 11, 12,
    11, 12, 13, 14, 15, 16,
    15, 16, 17, 18, 19, 20,
    19, 20, 21, 22, 23, 24,
    23, 24, 25, 26, 27, 28,
    27, 28, 29, 30, 31, 0]

PERMUTATION = [
    15, 6, 19, 20, 28, 11, 27, 16,
    0, 14, 22, 25, 4, 17, 30, 9,
    1, 7, 23, 13, 31, 26, 2, 8,
    18, 12, 29, 5, 21, 10, 3, 24]

PERMUTED_CHOICE_1 = [
    56, 48, 40, 32, 24, 16, 8,
    0, 57, 49, 41, 33, 25, 17,
    9, 1, 58, 50, 42, 34, 26,
    18, 10, 2, 59, 51, 43, 35,
    62, 54, 46, 38, 30, 22, 14,
    6, 61, 53, 45, 37, 29, 21,
    13, 5, 60, 52, 44, 36, 28,
    20, 12, 4, 27, 19, 11, 3]

PERMUTED_CHOICE_2 = [
    13, 16, 10, 23, 0, 4,
    2, 27, 14, 5, 20, 9,
    22, 18, 11, 3, 25, 7,
    15, 6, 26, 19, 12, 1,
    40, 51, 30, 36, 46, 54,
    29, 39, 50, 44, 32, 47,
    43, 48, 38, 55, 33, 52,
    45, 41, 49, 35, 28, 31]

ROTATES = [
    1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1]

def to_bin(s):
    return ''.join([bin(int(i, 16))[2:].zfill(4) for i in s])

def permutation(block, box):
    return ''.join([block[i] for i in box])

def xor(arg_1, arg_2):
    return ''.join([str(int(i) ^ int(j)) for i, j in zip(arg_1, arg_2)])

def rotate_left(block, i):
    return bin(int(block, 2) << i & 268435455 | int(block, 2) >> 28 - i)[2:].zfill(28)

def key_gen(block_1, block_2):
    li = []
    for i in ROTATES:
        block_1 = rotate_left(block_1, i)
        block_2 = rotate_left(block_2, i)
        li.append(permutation(block_1 + block_2, PERMUTED_CHOICE_2))
    else:
        return li

def f(block, key):
    final = []
    for j, i in enumerate(wrap(xor(permutation(block, EXPANSION), key), 6)):
        temp_box = [SUB_BOXES[0][0:16],
         SUB_BOXES[0][16:32],
         SUB_BOXES[0][32:48],
         SUB_BOXES[0][48:64]]
        final.append(bin(temp_box[int(i[0] + i[(-1)], 2)][int(i[1:-1], 2)])[2:].zfill(4))
    else:
        return permutation(''.join(final), PERMUTATION)

def rev_des(block, key_array):
    rl = permutation(block, INITIAL_PERMUTATION)
    right, left = rl[:len(rl) // 2], rl[len(rl) // 2:]
    for j, i in zip(range(16, -1, -1), key_array[::-1]):
        right, left = left, xor(f(left, i), right)
    return left + right

enc_flag = '7cd245e589aa384ac19dddfafb189650e8c1e6eb13fd52bc'
encrypted_list = [enc_flag[i:i+16] for i in range(0, len(enc_flag), 16)]

flag = ''
for encrypted in encrypted_list:
    bin_key = to_bin(KEY)
    permuted_key = permutation(bin_key, PERMUTED_CHOICE_1)
    key_list = key_gen(permuted_key[:len(permuted_key) // 2], permuted_key[len(permuted_key) // 2:])
    rl = ''.join([bin(int(i, 16))[2:].zfill(4) for i in encrypted])

    permuted_block = rev_des(rl, key_list)
    bin_mess = permutation(permuted_block, INVERSE_PERMUTATION)
    s = ''.join([chr(int(bin_mess[i:i+8], 2)) for i in range(0, len(bin_mess), 8)])
    flag += s.lstrip('\x00')

print(flag)
CTFZone{Str0ng_D3S}