ふるつき

v(*'='*)v かに

Securinets Prequals 2K19 writeup

We made a new team zer0pts and attended Securinets Prequals 2K19. We got 23393 points and reached 2nd place!! Thanks to all the admins for this great CTF! I solved some of the challenges and I'm going to write up them.

f:id:Furutsuki:20190325085517p:plain

[Misc 200pts (321 solves)]HIDDEN

description:

My friend asked me to find his hidden flag in this link .. Can you help me? Link

Author:Tr'GFx

The web page of the link just has a simple sentence: "Flag is somewhere here". When I jumped to the link for the first time, Firefox alerted against the self-signed certificate. So I checked the certificate and found the flag at "Verified by" column. Securinets{HiDDeN_D@tA_In_S3lF_S3iGnEd_CeRtifICates}

[Misc 331pts (184 solves)]EZ

description:

Welcome to Securinets, this one is an easy one.

Please make sure you hash the WORD with sha1 (lowercase hash letter)

The final flag is : Securinets{the_hash_of_the_word}

Pic Link

Author:BlueWhale

We were given pic.zip which has an image file pic.png in it. By using stegsolve, I noticed that something is hidden in the Least Significant Bit. I wrote the following script to extract hidden data.

from PIL import Image

img = Image.open("pic.png")
w, h = img.size

s = ''
c = ''
for y in range(3):
    for x in range(w):
        r, g, b = img.getpixel((x, y))
        c += str(r&1) + str(g&1) + str(b&1)
        if len(c) >= 8:
            s += chr(int(c[:8], 2))
            c = c[8:]
print(s.rstrip('\x00'))

Then I got phrases from Sherlock Holmes. <DETELED_WORD> (!) is "memorandum-book", so the flag is Securinets{b47f0d2a8866a75696f94a515d0cdf54c7ea3174}.

--START--
"The fact is that upon his entrance I had instantly recognized the extreme
personal danger in which I lay. The only conceivable escape for him lay in silencing
my tongue. In an instant I had slipped the revolver from the drawer into my
pocket and was covering him through the cloth. At his remark I drew the weapon
out and laid it cocked upon the table. He still smiled and blinked, but there was
something about his eyes which made me feel very glad that I had it there,
"You evidently don't know me,' said he.
"'On the contrary,' I answered, 'I think it is fairly evident that I do. Pray take
a chair. I can spare you five minutes if you have anything to say.'
"'All that I have to say has already crossed your mind,' said he.
"'Then possibly my answer has crossed yours,' I replied.
"'You stand fast?'
"'Absolutely.'
"He clapped his hand into his pocket, and I raised the pistol from the table.
But he merely drew out a <DETELED_WORD> in which he had scribbled some
dates.
"You crossed my path on the fourth of January,' said he. 'On the twenty-third
you incommoded me; by the middle of February I was seriously inconvenienced
by you; at the end of March I was absolutely hampered in my plans; and now, at
the close of April, I find myself placed in such a position through your continual
persecution that I am in positive danger of losing my liberty. The situation is
becoming an impossible one.'
"'Have you any suggestion to make?' I asked.
"'You must drop it, Mr. Holmes,' said he, swaying his face about. 'You really
must, you know.'"
--END--

[Web 964pts (44 solves)]Custom Location

Try to find out the database credentials.

The author changed the location of some files to protect the web application from script kiddies.

Link

Author:TheEmperors

As I tried to access to the path such as https://web0.ctfsecurinets.com/hoge, the debug mode 404 page was shown. It had the function to see the source code. I saw the config/bootstrap.php and found that the env file was /secret_ctf_location/env. So I also saw it from this link: https://web0.ctfsecurinets.com/_profiler/open?file=secret_ctf_location/env. The flag was Securinets{D4taB4se_P4sSw0Rd_My5qL_St0L3n}.

[Crypto 962pts (50 solves)]MAZE

we've intercepted a message that we want to decrypt! but we couldn't find the key! can u help ?

Author : KERRO

The zip file was provided. It included 101 RSA public key files and cipher.txt. My teammate st98 found there were two keys whose gcd was not 1. This fact implied that two keys had the same prime, namely n1 = p * q1 and n2 = p * q2. Since gcd(n1, n2) is p, it can be factorized. The following script decrypted the cipher.txt.

from Crypto.PublicKey import RSA
from Crypto.Util.number import *
from base64 import b64decode
import fractions


n1 = 23489536169894875104380319731091524594886928982079989680685140526506816078328377365920912691345973867274127369888617266471562817001630072737234558761977577075038991165371860879920389022518216143091522409148685349425962144785062882226489262290433631048454159440985148197906498710065684391869085391454754106309032049154232850533299594084654876542951785594662744724164946205787746362648504615426049549895862885960678401490612936954071297209796703651121038358809482596283354654704634698014090659491829169711549185505494879482606511678080905510586288124335730218605304747220982982161819303534160762335592895244302851836981
n2 = 23260716557375690457724340517814798553284093383675955753210132374509973258283306822538580132700875733321460692101694179361245119306418651193402512612500111442624876103473535129327037097046343634997541541496318494961543987552228754832236044259856000320983983126129412431801144031562287397570846392952905862981221569085591696654562289384531854207702626277469166158114197478525681143466552721501485707709954322005798540444098755630199517759570465455471064172816576843800829708415595842816666071002921806841594943525213770657127124965423586840200929234600612382079511164305586033156711399178225762365306090386434107266037
p = 168736462866079204789584058199620418225526506348478399447895958829038354002285480486576728303147995561507709511105490546002439968559726489519296139857978907240880718150991015966920369123795034196767754935707681686046233424449917085120027639055362329862072939086970892956139024391556483288415208981014264336691
q1 = 139208418683860744636489594107518498051692876942105482068436575406002091300025595750940476658875774324613311765708231971440632450100860632595797604226237831396754383891914573698131769762436941837224713009721577421233571830899874638297795728204831707647487557389464078420524002550428515370686466308350190419191
q2 = 137852341825115687630372545540234125575043643297743715914372468140743017665122928684176567678186288631724569119078697598260381091322877334920545216266418987980787824645288016924652387350842372904949656504253960440751217710040954075691996893620788950284865727480192510130305432030965910622333944701850333681207
assert(n1 == p * q1)
assert(n2 == p * q2)
phi1 = (p-1) * (q1-1)
phi2 = (p-1) * (q2-1)
e = 65537
d1 = inverse(e, phi1)
d2 = inverse(e, phi2)

C = int(open("cipher.txt", "r").read().strip())

print(long_to_bytes(pow(C, d1, n1)))
print(long_to_bytes(pow(C, d2, n2)))

The flag was securinets{rs4_1s_g00d_s0m3t1m3s!}

[Rev 919pts (65 solves)]AutomateMe

Huuuuge!

Authors : KERRO && Anis_Boss

64-bit ELF file was given. It was a simple crackme challenge. It had so many tiny functions that IDA couldn't show the graph, however, every function was pretty simple and had the same structure. I wrote the following script to recover the correct input.

import re


lines = open("dis.asm").read().splitlines()
i = 0
flagbuf = ['' for _ in range(0x1000)]
while i < len(lines):
    if lines[i] == 'mov    rax,QWORD PTR [rbp-0x20]':
        i += 3

        index = 0
        if lines[i].startswith('add'):
            r = re.findall(r',(.+)$', lines[i])
        else:
            r = re.findall(r'0x(.+)\]', lines[i])
        if len(r) == 1:
            index = int(r[0], 16)

        i += 1
        if lines[i].startswith('cmp'):
            pass
        else:
            i += 1
            if lines[i].startswith('cmp'):
                r = re.findall(r'0x(.+)$', lines[i])
                print(r[0], lines[i])
                flagbuf[index] = chr(int(r[0], 16))
            else:
                r = re.findall(r',0x(.+)$', lines[i])
                xor = r[0]
                i += 1
                r = re.findall(r',0x(.+)$', lines[i])
                c = r[0]
                flagbuf[index] = chr(int(xor, 16) ^ int(c, 16))
    else:
        i += 1
print(''.join(flagbuf))

The flag was included in the correct input securinets{automating_everything_is_the_new_future}.

[Rev 1000pts (7 solves)]Monster

Just give me the flag!

nc 54.87.182.197 1337

Author : KERRO

We were given 32-bit ELF file and dummy flag.txt. If we could input the correct value, the binary would execute cat flag.txt.

I reversed it using IDA's graph view, ghidra's decompiler, and gdb-peda. As I analysed the binary, I found the following facts:

  • the input format is %llx which means it's like d3adb33f
  • it calculate some hash value of tsebehtsignisrever using input as the seed and compare it to ca 3d 3b 5b 4c 9d d2 cb dd 17 8d dc b9 49 3b ea 12 25
  • the seed is used byte to byte

I focused on the last fact. It was possible to give all 256 patterns to the binary and get the first byte of correct seed. The following command did it.

$ for i in `seq 255`; do printf $i; printf '%02x\n' $i | ltrace ./rev 2>&1; done > trace

The first byte was 0xbe and nad the next byte could be found in the same way, which was 0xfe. The correct seed was febe and got the flag securinets{mD5_EncOd1nG_iS_Be4uT1fuL}. It was first blood.