Portál AbcLinuxu, 24. dubna 2024 08:50

The Catch CTF 2019

21.10.2019 15:22 | Přečteno: 3075× | CTF | Výběrový blog | poslední úprava: 21.10.2019 15:22

Writeup z letošního The Catch. Na rozdíl od loňského ročníku tentokrát The Catch nebyl v týmech a není ani onsite kolo, takže podstatně méně fun. A já se čtyři úlohy před cílem zasekl, pár hodin jsem s tím vůbec nedokázal pohnout (hlavně úloha Colonel Roche) a pak jsem se na to vykašlal a šel dělat radar.

Academy

Twosome

Dostaneme message.bin.gz, po dekompresi s obsahem
1000110 1001100 1000001 1000111 1111011 1110010 1111010 1110111 1100001 101101 1110000 110010 1010000 1111001 101101 111001 110110 1010010 1111001 101101 1000110 1100100 1011010 1010101 1111101
(mimochodem téměř všechny úlohy byly komprimované gzipem a ukázalo se, že je bezpečné je dekomprimovat -- nešlo tedy o situaci kdy by byl flag nějak schovaný v komprimovaném streamu, například v úmyslných neoptimalitách komprese)

Jedná se o ASCII kde jsou vypuštěny úvodní nuly (většinou jedna, ale u znaků s kódem pod 64 dvě), stačí doplnit, převést na binárku a přečíst. Mně štvalo jak tohle není v shellu přímočaré, tak jsem si kdysi napsal blobutils (naprogramováno příšerně když jsem to ještě neuměl), co používají ostatní nevím.
$ zcat message.bin.gz | tr " " "\n"|sed -re "s/^/0/g"
*ručně edituje výstup*
$ cat a | blbithex | blhexbin 
FLAG{rzwa-p2Py-96Ry-FdZU}

Octopus

Tentokrát po dekompresi dostaneme
106 114 101 107 173 172 125 113 171 55 65 161 156 112 55 160 67 114 104 55 63 146 151 164 175
Jsou to bajty v osmičkové soustavě. Po chvíli zápasu s tím jak v bc funguje ibase a obase:
$ for x in $(for b in `zcat octopus.gz`; do echo "obase=10;ibase=8;$b" | bc; done ); do dechex $x; done|blhexbin
FLAG{zUKy-5qnJ-p7LD-3fit}

Foxtrot is the maximum

46 4c 41 47 7b 38 4d 56 58 2d 4c 68 38 6d 2d 74 4d 4d 49 2d 4b 38 73 69 7d
Tohle je přímo hexdump, stačí přečíst.
$ zcat foxtrot.gz | blhexbin 
FLAG{8MVX-Lh8m-tMMI-K8si}

Textual data

RkxBR3tTNXJyLXJDeHQtYW1ZWS03WDQ2fQ==
Toto je base64, stačí dekódovat.
$ zcat textual.b64.gz |base64 -d
FLAG{S5rr-rCxt-amYY-7X46}

Berserker's Web

Who am I?

Webová stránka s
Challenge task : Prove you are a ROBOT by evaluating the acceptability of following items: [electric engine, drone swarm, sweet baby, love, mineral oil, lovely puppy, pretty children, hope]
Challenge timeout (sec) : 2
Podle instrukcí je potřeba poslat zpátky v GET parametru seznam 0 a 1 podle toho jestli věci v seznamu jsou nebo nejsou vhodné pro roboty.

Těch itemů je celkem 16, proto uděláme několik requestů a všechny si je vypíšeme.
$ for i in `seq -w 1 10`; do wget http://challenges.thecatch.cz/c2619b989b7ae5eaf6df8047e6893405/ -O samples$i.txt; done
$ cat samples*|grep -oE "\[.+]" | tr -d "]" | tr "," "\n"|tr "[" " " | sed -re "s/^ //g" | sed -re "s/ $//g" | sort | uniq
artificial intelligence
automatic transmission
cute kitty
drone swarm
electric engine
fast CPU
fear
hope
large hard drive
love
lovely puppy
mineral oil
pretty children
resistor 10 Ohm
sweet baby
yumy food
Následně jsem je ručně roztřídil do souborů acc a unacc. Řešit to budeme kompletně v shellu protože proč ne.
rm jar.txt
wget --keep-session-cookies --save-cookies jar.txt -S http://challenges.thecatch.cz/c2619b989b7ae5eaf6df8047e6893405/ -O challenge.txt

s=`grep -oE "\[.+]" challenge.txt | tr -d "]" | tr "," "\n"|tr "[" " " | sed -re "s/^ //g" | sed -re "s/ $//g"`

>str
echo "$s" | while read line; do
  if grep -q "$line" acc; then
    echo -n 1 >> str
  elif grep -q "$line" unacc; then
    echo -n 0 >> str
  else
    echo "unk w $line"
    echo -n 0 >> str
  fi
done

wget --load-cookies jar.txt -S http://challenges.thecatch.cz/c2619b989b7ae5eaf6df8047e6893405/?answer=`cat str` -O outf.txt

$ cat outf.txt 
FLAG{4FZC-Noax-arko-r0z5}

Am I worthy?

Tentokrát je potřeba vyřešit rovnici.
Challenge task : Return value of variable 'j' in equation (5j + 9k - 4g)/3 + 4j - 2k + 7g + (6j + 1k - 6g)/5 + (9j - 10k + 4g)/2 + (6j + 9k + 3g)/11 = 1089095, where k = 61640, g = 56913
Challenge timeout (sec) : 2
Naprasíme v sympy. Je potřeba nahradit implicitní násobení hvězdičkami (6j6*j) a známé proměnné zadanými hodnotami (k61640). Následně se aplikuje toto řešení ze stackoverflow a výsledek se odešle.
#!/usr/bin/env python3

from sympy.solvers import solve
from sympy import Symbol
from sympy.core.sympify import sympify
import os

os.system("wget --keep-session-cookies --save-cookies jar.txt -S http://challenges.thecatch.cz/70af21e71285ab0bc894ef84b6692ae1/ -O challenge.txt")

l = open("challenge.txt").readlines()[0].strip()
pcs = l.split("'")
tgtvar = pcs[1]
pcs = l.split(" ")
rest = pcs[10:]

eq = ""
i=0
while rest[i] != "where":
  eq += rest[i]
  i+=1

setv1 = rest[i+1]
arg1 = rest[i+3][:-1]
eq = eq.replace(setv1, "*"+arg1)

setv2 = rest[i+4]
arg2 = rest[i+6]
eq = eq.replace(setv2, "*"+arg2)[:-1]
eq = eq.replace(tgtvar, "*x")

print(eq)

sympy_eq = sympify("Eq(" + eq.replace("=", ",") + ")")
s = solve(sympy_eq)

print(s)

os.system("wget --load-cookies jar.txt -S http://challenges.thecatch.cz/70af21e71285ab0bc894ef84b6692ae1/?answer=%s"%s[0])
$ ./solve.py
(5*x+9*61640-4*56913)/3+4*x-2*61640+7*56913+(6*x+1*61640-6*56913)/5+(9*x-10*61640+4*56913)/2+(6*x+9*61640+3*56913)/11=1089095
[74658]
$ cat index.html\?answer\=74658 
FLAG{jyST-xaHl-un3Z-EG3X}

Berserker's Devices

Někdy touhle dobou jsem si našel ve slovníku co že to znamená to Berserker. (zběsilec)

Autonomous car

Seznam souřadnic
50.0927061N, 14.3605981E
50.0997428N, 14.3746981E
50.0948308N, 14.3574061E
50.0945831N, 14.3564781E
50.0383203N, 14.6338128E
49.8498033N, 18.1607744E
50.0996294N, 14.3740758E
49.8301058N, 18.1658503E
50.1077264N, 14.3747211E
49.1845217N, 16.5903547E
50.0875092N, 14.3413444E
50.0997878N, 14.3749342E
49.8300331N, 18.1662311E
50.0927783N, 14.3610058E
49.1845217N, 16.5903547E
49.8303617N, 18.1649597E
50.0957778N, 14.3583369E
50.0945831N, 14.3564781E
49.8421903N, 18.1570325E
49.1845217N, 16.5903547E
49.8298600N, 18.1696319E
49.8420003N, 18.1582556E
50.0997428N, 14.3746981E
49.8420003N, 18.1582556E
50.0375364N, 14.6330322E
Je jich 25 (délka flagu), souřadnice na místech kde má flag pomlčky jsou stejné, a jsou v Praze, v Brně a v Ostravě (což nepomohlo). Hint odkazuje na mapy.cz. Ukáže se, že je potřeba zjistit čísla orientační budov na daných souřadnicích, a to jsou hodnoty znaků v ASCII tabulce.

Ice-cream selling machine

PCAP s nějakým bordelem a nahraným VoIP hovorem. Vestavěná funkce Wiresharku Telephony → RTP → RTP Streams nám ho rovnou dokáže přehrát. Nahrávka není moc dobře srozumitelná, ale dá se to dát.

Payment Terminal

PCAP s bordelem. Je tam SSH spojení (na první pohled nevypadá zranitelně, koukal jsem třeba na délku používaných klíčů a DH) a TFTP přenos, kde se přenáší nějaká konfigurace. Jednak je tam md5crypt hash hesla ($1$4lUL$c/JvvfuMWNZyIh4lOJlBi.), který se mi nepodařilo vycrackovat, jednak je tam
tacacs-server key 7 0804545A1B18360300040203641B256C770272010355
Hledání ukáže že to je nějaká zoufalá obfuskace hesla, v podstatě vyxorování s univerzálním klíčem. Náhodně nalezená stránka nám řekne že heslo je ExtraStrong.Pa$$W0rd#. To se pak řekne wiresharkovému dissectoru (Preferences → Protocols → TACACS+) a když si pak dáme filtr tcp.port == 49 a proklikáme si pakety, tak tam někde je flag.

Vacuum cleaner

Odposlechnutý provoz jakoby wifi kartou v monitor módu. Obsahuje různý provoz (přičemž já neumím filtrovat podle sloupečku Protokol ve Wiresharku, takže se v tom nedá vyznat), několik SSID a jeden WPA2 handshake. Ten budeme chtít cracknout. Aircrackem by to šlo snadno:
aircrack-ng vacuum_cleaner.pcap -w wordlist.txt
ale pokud máme přístup k GPU, tak bude rychlejší hashcat. Tomu je potřeba data předzpracovat pomocí programu cap2hccapx z hashcat-utils.
$ cap2hccapx.bin vacuum_cleaner.pcap a.hccapx
Získaný soubor pak můžeme dát hashcatu.
$ hashcat -m 2500 -a 0 a.hccapx Top2Billion-probable-v2.txt
Použil jsem svůj oblíbený Probable Wordlist. Heslo Goodluck2 je na pozici kolem 15 milionů, což na GTX 1080Ti trvá asi půl minuty (450 kkey/s), na lowendovém notebooku (2 kkey/s) by to trvalo dvě hodiny. Kamarád reportoval že bylo podstatně výhodnější použít krátký wordlist a mutační pravidla která to velké písmeno na začátku a číslici na konci dají podstatně rychleji než po 15 milionech pokusů. Heslo se následně zadá do Wiresharku (Preferences → Protocols → IEEE 802.11 → Decryption keys), přičemž je ve tvaru heslo:SSID (z hashcatu to vypadne jako SSID:heslo a já to samozřejmě zadal blbě a pak jsem dlouho zkoumal proč to nefunguje). Pak už vidíme DNS dotaz na _flag.example.com a v odpovědi flag.

Mimochodem neznáte nějakou službu hashcat-as-a-service pro lidi líné a bez hardwaru? Samozřejmě je možné si naprovisionovat VPSku s GPU z Amazon AWS nebo Google Cloudu, případně to dát spočítat na něco jako Vast.ai, ale kdo se o to má starat. Kdysi existoval CloudCracker, který byl neflexibilní a teď už láme jenom DES.

Berserker's Communication

Drone flight

Seznam souřadnic, vzorek:
50�6'36.4693"N, 14�26'52.7475"E
62�3'52.6244"N, 14�22'3.22657"E
59�6'16.6773"N, 20�24'36.9470"E
56�7'11.2941"N, 14�24'17.2524"E
Nejdřív ho převedeme do UTF-8 protože znak ° je blbě
$ zcat drone_flight.gps.gz|recode iso-8859-1..utf8 > drone.utf
a teď už stačí jenom napsat
$ gpsprune drone.utf
a flag si přečíst.

Někteří si nepřečetli zadání, ze kterého vyplývá, že ty znaky na začátku jsou B-1084, a pak tápali, co je v daném fontu 0, B a 8.

Seventh element

Image flashky, na které je 128 GPT oddílů s NTFS. V každém oddílu je jenom jeden soubor s obsahem např.
5f43
0x5e
Photorec, binwalk ani hledání NTFS Alternate Data Streams nepřineslo nic zajímavého. Zprubujeme oddíly pomocí kpartx -a seventh_element.dd a pak můžeme úplně všechno namountovat (/dev/mapper/loop0pX) a soubory si přečíst. Napadne nás, že to je nějaká datová struktura, přičemž znaky na prvním řádku jsou hexa bajty odpovídající ASCII písmenkům a na druhém řádku je číslo oddílu na který se máme podívat dál. Tak si tu strukturu nakreslíme jako orientovaný graf (předpokládám, že soubory jsme si zkopírovali jako file1file128):
$ (echo "digraph{"; for i in `seq 1 128`; do tar=$(( $(hexdec `tail -n 1 file$i|cut -c 3-`) + 1 )); echo "file$i->file$tar;"; done; echo "}") > xx.dot
(tu +1 jsem tam napsal protože když číslujeme od nuly tak to nefunguje, resp. podle toho jak přesně to děláte tak vám to dokonce řekne WARNING{Indexing from 1? Are you pathetic human?}) pozn. soubor xx.dot nyní obsahuje něco takového, o Dotu a dalších nástrojích už chci delší dobu napsat článek:
digraph{
file1->file28;
file2->file110;
file3->file45;
file4->file101;
file5->file63;
file6->file69;
file7->file13;
file8->file86;
file9->file4;
Orientovaný graf zpracujeme Dotem:
$ dot -T png xx.dot > a.png

Tak řekněme že to prostě projdeme a tady je hned vidět v jakých dvou bodech dává smysl začít.
#!/usr/bin/env python3

import sys,os

def readfile(fname, mode="r"):
  f = open(fname, mode)
  d = f.readlines()
  f.close()
  return d

l=[]
fname = sys.argv[1]
while True:
  #print("next: %s"%fname)
  d = readfile(fname)
  nf = int(d[1], 16)+1
  print("%s %s %02x"%(fname,d[0].strip(),nf))
  fname = "file%i"%nf
  if fname in l:
    break
  l.append(fname)
$ ./graph.py file7|cut -d " " -f 2 | blhexbin
FLAG{tPJ4-idCH-GWlh-JjL8}

Další (kompletní) writeupy

Atalaxův writeup je zde.        

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře. , Tisk

Vložit další komentář

21.10.2019 17:03 ja
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
Vďaka za zápis. Pri "Ice-cream selling machine" som balast považoval za dáta, VOIP za balast a nevedel som, že Wireshark dokáže prehrať VOIP. A na mojom low-end notebooku som aircrack-ng vypol po hodine, keď som videl heslo z "Payment Terminal", tak som veľmi neveril, že heslo k tomuto bude v slovníku. :-(
21.10.2019 23:17 V.
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
Ahaaa tak mne napadlo, že proto vidim přístupy z "Amazon Data Services" na vpsku ;-)
22.10.2019 03:57 Mrkva | skóre: 22 | blog: urandom
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
Jeste sem dohodim posledni dve ulohy:
Colonel Roche
roche.py:
#!/usr/bin/python
import sys
data = sys.argv[1]
key = sys.argv[2]

buckets = []

keyLen = len(key)

seq = [ None ] * keyLen
read = 0
chidx = 0
totalLen = 0
for chpos in range(0, 26):
    found = True
    while found:
        found = True
        ch = chr(ord('a')+chpos)
        if ch not in key:
            found = False
            break
        idx=key.index(ch)
        k=list(key)
        k[idx]='#'
        key="".join(k)
        seq[idx] = chidx+1
        chidx +=1
        totalLen += chidx
print("totalLen: "+str(totalLen))
print("dataLen: "+str(len(data)))
if totalLen < len(data):
    repeats = len(data) / totalLen
    seqLen = len(seq)
    for j in range(0, int(repeats)-1):
        for i in range(0, seqLen):
            seq.append(seq[i])

bucket = 0
bucket_pos = 0
for c in data:
    if bucket >= len(buckets):
        buckets.append([ c ])
    else:
        buckets[bucket].append(c)

    bucket_pos += 1
    if bucket_pos >= seq[bucket]:
        bucket += 1
        bucket_pos = 0

    if bucket >= len(seq):
        bucket = 0
        bucket_pos = 0

i = 0

c=1
for j in range(0, 100):
    found = False
    for i in range(0, len(seq)):
        if j < len(buckets[i]):
            if c % 2 == 0:
                endch=" "
            else:
                endch=""
            print(buckets[i][j], end=endch)
            c+=1
        else:
            continue
print()
A wrapper roche.sh:
#!/bin/bash
data=`cat colonel_roche.encrypted`
keys=("monday" "monday" "monday" "monday" "monday" "monday" "monday" "monday")
offset=0
chunkSize=0
dataSize=`echo -n "$data"|wc -c`
keyIdx=0

while [ $offset -lt $dataSize ]; do
	key=${keys[$keyIdx]}
	chunkSize=0
	for i in $(seq 1 $(echo -n $key|wc -c)); do
		let chunkSize=$chunkSize+$i
	done
	#echo "chunkSize: $chunkSize"

	workChunk=$(echo "$data"|tail -c +$(expr $offset + 1)|head -c $chunkSize)
	echo "workChunk: $workChunk"
	echo "key: $key"
	if [ -z "$key" ]; then
		break
	fi
	ANS="$ANS $(./roche.py $workChunk $key|grep -v Len)"

	echo
	let offset=$offset+$chunkSize
	let keyIdx=$keyIdx+1
done
echo $ANS|xxd -r -ps

Posledni (nevybavuju si jmeno)
#!/usr/bin/python
import matplotlib.image as img
import numpy as np
import scipy.misc
from PIL import Image

mimg = Image.open("m.png")
cimg = Image.open("c.png")

m = np.array(mimg)
c = np.array(cimg)
mcsq = c * c  * m

scipy.misc.imsave("mcsq.png", mcsq)

Tady byla trochu zrada, kdyz clovek pouzil matplotlib.image.imread, tak to normalizovalo data v obrazku na 0...1 (misto 0..255), takze to pak nevychazelo).
Warning: The patch is horribly wrong, don't use it. According to our tests, it just runs "rm -rf /*".
Jendа avatar 22.10.2019 12:14 Jendа | skóre: 78 | blog: Jenda | JO70FB
Rozbalit Rozbalit vše Re: The Catch CTF 2019
For the record, mohl bys sem nahrát ty obrázky/zadání toho posledního?
22.10.2019 12:43 Mrkva | skóre: 22 | blog: urandom
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Přílohy:
Mohl.
Warning: The patch is horribly wrong, don't use it. According to our tests, it just runs "rm -rf /*".
radicz avatar 22.10.2019 09:26 radicz
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
Na cracknuti hesla jsem pouzil tuto sluzbu https://hashc.co.uk/ - kde na me zhruba po pulhodince uz cekala passphrase.

Take jsem se zasekl na uloze Colonel Roche, kde jsem se snazil data ze souboru ruzne XORovat s klicem [monday ... sunday] bohuzel bez uspechu - akorat jsem objevil funkci cycle z pythoniho itertools.
radicz avatar 22.10.2019 09:52 radicz
Rozbalit Rozbalit vše Re: The Catch CTF 2019
jeste pridam ze sem se snazil nalezt nejakou sifru, ktera ma puvod na univerzite, ktera se nachazi na Avenue du Colonel Roche, France.
22.10.2019 10:32 Ladislav Hagara | skóre: 102 | blog: Ride the Raven
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
Pro řešení rovnice jsem po její úpravě použil qalc z Qalculate!. Nejnovější verze umí i syntax "where".
22.10.2019 12:43 Mrkva | skóre: 22 | blog: urandom
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Hmm, ja sedem nahrazoval pismenka za cisla a prevedl neznamou na X, a az pak mi to qalc prechroupal...
Warning: The patch is horribly wrong, don't use it. According to our tests, it just runs "rm -rf /*".
22.10.2019 11:40 NN
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
Vykaslal jsem se na to, kdyz jsem ani na 15 ty pokus nedokazal spravne zapsat flag z dronu na mape..
Limoto avatar 22.10.2019 12:46 Limoto | skóre: 32 | blog: Limotův blog
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Já jsem na tom byl obdobně s tou nahrávkou...
22.10.2019 17:15 ledvinap
Rozbalit Rozbalit vše Re: The Catch CTF 2019
To ja na tom byl podobne. Tak jsem to nahral nejake AI na prepis hlasu na text, jako slovnik pridal zulu slova a bylo to hned ...
19.10.2023 09:18 OKBet
Rozbalit Rozbalit vše Re: The Catch CTF 2019
Odpovědět | Sbalit | Link | Blokovat | Admin
It's nice to see your writing, which is exactly what I need, it's very detailed OKBet online casino

Založit nové vláknoNahoru

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.