P4 CTF 2015 - Write-upy i rozwiązania

5

P4 CTF Dobiegł końca. Serdecznie dziękujemy wszystkim za udział. Mamy nadzieję że dobrze się bawiliscie! Niedługo wrzucimy jakieś statystyki z konkursu, ale póki co możemy się pochwalić że wystartowało aż 121 osób z czego 80 poradziło sobie przynajmniej z jednym prawdziwym zadaniem. Gratulacje!

Zakładamy ten wątek jako zbiorcze miejsce gdzie możecie pochwalić sie swoimi rozwiązaniami / podyskutować na ich temat.

Liczymy na to że użytkownicy sami się pochwalą rozwiązaniami (a rozwiązane zostały wszystkie zadania!), niemniej jeśli będzie czegoś brakowało to możemy pokazać jak zakładaliśmy że rozwiążecie dane zadanie :)

i pamiętajcie o ankiecie https://docs.google.com/forms/d/15rgY4MPkvddSGT1ta89taNlNBhVn33U2ueO1r8FsnKU/viewform !

Infrastruktura póki co nadal działa i będzie dopóki @Rev nie zabije więc możecie jeszcze jakiś czas coś popróbować / porobić screenshoty do opisu rozwiązać etc :)

edit: jakby ktoś chciał poczytać jak wyglądają zadania na otwartych, międzynarodowych CTFach to zachęcam do czytania https://github.com/p4-team/ctf ;) </kryptoreklama>

edit:
Weby są dostępne tutaj: https://dl.dropboxusercontent.com/u/25622690/ctf.zip
Misce są dostępne tutaj: https://www.dropbox.com/sh/5bc5havhhabtvya/AAArenFZGsReFynCPfHZUdAJa?dl=0

6

Na wstępie dzięki wszystkim, którzy przygotowali tego CTF'a. Domyślam się, że nie było to łatwe, a i zadania były na dobrym poziomie (niektóre faktycznie poza moim zakresem).
Choć pewnie w niektórych zadaniach kręciłem się koło rozwiązania to zabrakło mi pewnie kilku kroków, a co za tym idzie umiejętności. Na dole napisze o zadania w których myślałem, że jestem blisko.
Samą organizację oceniam na 5. Szybko pojawiały się update'y tam gdzie były błedy, a dodatkowo w ciągu trwania konkursu były dokładane kolejne zadania.
Na duży minus (IMO) jest to, że sporo kont zostało założonych właśnie tylko na tego ctf'a. O ile założenie ogólne było takie że jest to dla początkujących to w praktyce wyszło inaczej. Jestem przekonany że jakieś 70% osoób z TOP 20 brało już udział w innych CTF'ach, a książkę albo mają albo im niepotrzebna :D

Moje założenia na początku były takie:

  • TOP 20 - jednak po zobaczeniu że konta które dopiero się zarejestrowały mają już kupe punktów przeszedłem do założenia 2
  • minimun 1000 punktów - udało się zrobić prawie 2 razy więcej
  • nie bawię się w skrypty, kod - lenistwo, brak umiejętności, ale jedno zadanie (pewnie inne też) aż prosiło się o kilka linijek więc jeden skrypt napisałem :D
  • z każdego działu chociaż po jednym zadaniu postaram się rozwiązać
  • sprawdzenie samego siebie, książkę już mam więc mi nie zależało na nagrodzie

Podsumowywując:

Cebula 1
Rozwiązanie - konwersja cyfr z dziesiętnego na tekst i mamy flagę

Cebula 2
Rozwiązanie - rzutem na taśmę :D base64 - decode i flaga zdobyta

Where is my password#1
Rozwiązanie - pierwsze dwa znaki 70 34 dały mi od razu pomysł HEX to TEXT i flaga zdobyta

Capture the data #1
Rozwiązanie - otwarcie pliku w wiresharku, popatrzenie co było wysyłane na serwer FTP i flaga zdobyta

English, do you speak it?
Rozwiązanie - to jest zadanie do którego napisałem skrypt w pythonie. Użyłem libki detect language, puściłem telneta ze skryptu i na zwrotce wysyłałem rozpozanany język, po 300 elementach flaga zdobyta

Easymod
Rozwiązanie - pobrałem exe, otwarłem to blees hex editorem i flaga zdobyta

SS-93 #1
Rozwiązanie - pobrałem wav, otwarłem to blees hex editorem i po zobaczeniu ile tego jest, przejechałem ze zrezygnowaniem na sam koniec. W nagrodę czekała na mnie flaga :D

Centrum NS@
Rozwiązanie - pierwsze co zrobiłem po wejściu na tą stronę popatrzyłem w ciasteczka (w zasadzie nie wiem dlaczego). Jedno ciastko o nazwie admin, podmiana wartości z 0 na 1 i flaga zdobyta. @katelx takie trudne zadania rozwiązałaś a do ciasteczka nie popatrzyłaś :D btw respect za Rémy Suárez Ascánder (pewnie piszesz/pisałaś w ocaml'u)

D0 Y0u 3v3n PHP? #1
Rozwiązanie - jak zobaczyłem dwa pola na dane to od razu w kod a tam piękna informacja o debugu w gecie :) oczywiście trochę się naszukałem bo w PHP nie piszę, ale ?debug = 1 i flaga zdobyta

D0 Y0u 3v3n PHP? #2
Rozwiązanie - tutaj musiałem zrobić większy research. strcmp był dziurawy. Podmiana na żywo w kodzie z value="password" na value="password[]" i flaga zdobyta

Koty MSMa
Rozwiązanie - jak zobaczyłem w pasku show.php?cat=Amber.jpg to od razu wpisałem show.php?cat=show.php i tutaj zadanie mogło by się prawie zakończyć, ale ja spodziwałem się pliku php pokazanego na stronie (Hackme 3.0 miał takie zadanie). Dopiero później zrobiłem zapisz jako, zobaczyłem że skrypt przyjmuje tylko JPG, ale zapisując plik do dobrego rozszerzenia pokazywał wszytko i tak cat=/home/flag.txt zapisane jako flag.txt i flaga zdobyta

42
Rozwiązanie - SQLInjection - brak podwiedzi w źródle, brak info w pasku no to jedyne co mi przyszło do głowy do SQL Injection i flaga zdobyta

Obfuscated
Rozwiązanie - skrpyt JS w kodzie strony, chwila z kartką i flaga zdobyta

Zadania przy których węszyłem, ale nie wiem czy dobrze

Capture the data #2
Wszedłem na serwer FTP dzięki danych logowania, przełączałem się na tryb bianarny (wzięte z pcap'a), ale nie pomogło. Był jeszcze plik confidential.zip ładowany do folderu upload, ale go tam nie umiałem znaleźć

Kapitan Rozdil
Po zobaczeniu że jest to obrazek przeskanowałem go pod względem ukrytego tekstu, niestety nie było go tam (lub źle to zrobiłem) i odpuściłem. Jeszcze zastanawiałem się czy przypadkiem nie ma tam drugiego obrazka w nim ale nie sprawdziłem tego.

Dzięki jeszcze raz za tego ctf'a. Czekam na wzorce i następny konkurs!

P.S Sorki za brak flag, ale nie spisywałem tego na bieżąco.

0

wystartowało aż 121 osób

Nie wiem czy wejście pod adres ctf.4programmers.net można nazwać wystartowaniem :P. Powiedziałbym że wystartowało 80 osób (bo jedno zadanie było celowo trywialne). Tak czy inaczej nieźle.

0

Jestem ciekaw czy userzy, który tak chętnie udzielają się na forum w programowaniu (i mają przy tym sporą wiedzę)
a) zapomniało
b) nie miało czasu
c) weszli popatrzyli na zadania i powiedzieli o kur**

12

Mój writeup - nie udało się zrobić wszystkiego, ale na usprawiedliwienie powiem, że dowiedziałem się o konkursie o 17:50 w sobotę (wg historii przeglądarki):

Cebula

Flaga 1:
Widzimy, że tekst z zadania to liczby do 128 - zatem pewnie ASCII. W Pythonie potwierdziło się.

s="82 49 107 122 81 48 70 79 85 108 90 70 81 84 78 69 83 48 108 67 86 48 100 90 85 85 82 78 84 107 112 66
82 49 107 121 85 48 70 79 85 108 90 70 81 84 78 69 84 85 108 67 86 48 100 90 85 85 82 78 84 108 74 66 82 
49 107 121 85 48 70 79 85 108 90 70 81 84 78 69 84 85 108 67 86 48 100 86 85 85 82 78 84 107 112 66 82 49
107 121 85 48 70 79 85 108 90 70 81 84 78 69 84 85 108 67 86 48 100 86 85 85 82 78 84 107 112 66 82 49 
107 121 85 48 70 79 85 108 100 70 81 84 78 69 84 85 108 67 86 48 100 86 85 85 82 78 84 107 112 66 82 49 
107 121 85 48 70 79 85 108 90 70 81 84 78 69 83 48 108 67 86 48 100 90 85 85 82 78 84 108 74 66 82 122 81
48 85 48 70 79 87 108 108 70 81 84 78 85 84 85 108 67 87 85 104 70 85 85 82 80 84 48 112 66 82 122 81 48
81 48 70 79 85 108 112 70 81 84 78 85 84 48 108 67 87 69 104 70 85 85 82 82 84 86 74 66 82 49 107 48 85 
48 70 85 85 48 112 74 84 86 112 86 86 86 81 121 81 48 115 49 82 86 90 74 85 48 78 86 83 107 74 66 86 107 
107 57 80 84 49 81 85 106 77 122 86 70 108 102 82 122 65 119 82 65 61 61 71 48 48 68 83 84 52 82 84"
r="".join([chr(int(x)) for x in s.split(" ")])
print r
R1kzQ0FOUlZFQTNES0lCV0dZUURNTkpBR1kyU0FOUlZFQTNETUlCV0dZUURNTlJBR1kyU0FOUlZFQTNETUlCV0dVUURNT
kpBR1kyU0FOUlZFQTNETUlCV0dVUURNTkpBR1kyU0FOUldFQTNETUlCV0dVUURNTkpBR1kyU0FOUlZFQTNES0lCV0dZUU
RNTlJBRzQ0U0FOWllFQTNUTUlCWUhFUURPT0pBRzQ0Q0FOUlpFQTNUT0lCWEhFUURRTVJBR1k0U0FUU0pJTVpVVVQyQ0s
1RVZJU0NVSkJBVkk9PT1QUjMzVFlfRzAwRA==G00DST4RT

Zatem flaga to G00DST4RT.

Flaga 2:
Poprzednia warstwa kończyła się dwoma znakami równości, a sama składała się z liter i cyfr. Prawdopodobnie to Base64:

s="R1kzQ0FOUlZFQTNES0lCV0dZUURNTkpBR1kyU0FOUlZFQTNETUlCV0dZUURNTlJBR1kyU0FOUlZFQTNETUlCV0dVUURNTkpBR1kyU0FOUlZFQT
NETUlCV0dVUURNTkpBR1kyU0FOUldFQTNETUlCV0dVUURNTkpBR1kyU0FOUlZFQTNES0lCV0dZUURNTlJBRzQ0U0FOWllFQTNUTUlCWUhFUURPT0p
BRzQ0Q0FOUlpFQTNUT0lCWEhFUURRTVJBR1k0U0FUU0pJTVpVVVQyQ0s1RVZJU0NVSkJBVkk9PT1QUjMzVFlfRzAwRA=="
import base64
base64.b64decode(s)
'GY3CANRVEA3DKIBWGYQDMNJAGY2SANRVEA3DMIBWGYQDMNRAGY2SANRVEA3DMIBWGU
QDMNJAGY2SANRVEA3DMIBWGUQDMNJAGY2SANRWEA3DMIBWGUQDMNJA
GY2SANRVEA3DKIBWGYQDMNRAG44SANZYEA3TMIBYHEQDOOJAG44CANRZEA3TOIBXHEQ
DQMRAGY4SATSJIMZUUT2CK5EVISCUJBAVI===PR33TY_G00D'

Flaga to PR33TY_G00D.

Flaga 3:
Podobnie jak poprzednio. Tym razem tekst to wielkie litery i cyfry, oraz === na końcu. Po chwili googlania, wychodzi base32:

s='GY3CANRVEA3DKIBWGYQDMNJAGY2SANRVEA3DMIBWGYQDMNRAGY2SANRVEA3DMIBWGUQ
DMNJAGY2SANRVEA3DMIBWGUQDMNJAGY2SANRWEA3DMIBWGUQDMNJAGY2SANR
VEA3DKIBWGYQDMNRAG44SANZYEA3TMIBYHEQDOOJAG44CANRZEA3TOIBXHEQDQMRAGY4S
ATSJIMZUUT2CK5EVISCUJBAVI==='
base64.b32decode(s)
'66 65 65 66 65 65 65 66 66 66 65 65 66 65 65 65 65 66 65 65 65 66 66 65 65 65 65 65 66 66 79 78 76 89 79 78 69 77 79 82 69 NIC3JOBWITHTHAT'

Flaga to: NIC3JOBWITHTHAT.

Flaga 4:
Powtórka z flagi 1:

s='66 65 65 66 65 65 65 66 66 66 65 65 66 65 65 65 65 66 65 65 65 66 66 65 65 65 65 65 66 66 79 78 76 89 79 78 69 77 79 82 69'
"".join([chr(int(x)) for x in s.split(" ")])
'BAABAAABBBAABAAAABAAABBAAAAABBONLYONEMORE'

Flaga: ONLYONEMORE.

Flaga 5:
Tekst to ciąg liter A i B. Sugeruje to użycie kodu Bacona (http://rumkin.com/tools/cipher/baconian.php). Po wklejeniu tam
naszego ciągu (i wybraniu opcji i=J and U=V), dostajemy flagę THEEND.

Where is my password?! #1

Flaga wg treści pochodzi z klucza. Klucz to:
klucz='7034xx6265747465725f6b6565705f69745f72616e646f6d5f647564653b29xx'
gdzie x to niewiadoma. Zauważamy, że klucz jest heksadecymalny, a poszczególne bajty nie przekraczają 0x7f, co sugeruje ascii.
Po zdekodowaniu dostajemy:
p4?better_keep_it_random_dude;)?
Zatem flaga to:
p4{better_keep_it_random_dude;)}

Hasło Shaloma
Otwieramy plik w Wiresharku, patrz screenshot http://imgur.com/ryZfAXx. Nie licząc czasu, tylko dwa bajty się
zmieniały pomiędzy pakietami, z czego pierwszy tylko pomiędzy dwoma wartościami: 0x00 i 0x20. Przypuściłem, że to zapewne
Shift albo coś w tym stylu, natomiast drugi bajt koduje klawisz. Problem w tym, że nie było to ani ascii, ani nic podobnego.
Po poszperaniu w internecie, znalazłem jednak stronę z kodami klawiaturowymi:
https://www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html
Po przeliterowaniu (ręcznie) po wszystkich naciśnięciach, dostajemy flagę:
p4{i--74k--u2yvv4m--m45ki}

Capture The Data #1

strings -n 10 forensics2.pcapng | grep p4{

6PASS p4{FTP_Free_To_Pwn}

Capture The Data #2
Otwierając w Wiresharku plik, okazuje się że poprzednia flaga była w przekazie FTP. Przekazany był jeden plik - po wyciągnięciu
go, okazuje się, że był to zip zawierający 1000 plików o nazwach 1, 2, ..., 1000. Na szczęście były one niewielkie, zatem je
po prostu wypisałem:

cat *

Po szybkim przejrzeniu okazuje się, że tylko jeden zawierał coś dłuższego niż kilka znaków:
70347b616c6c5f6f665f796f75725f7a6970735f6172655f62656c6f6e675f746f5f75737d
Flaga to więc, po zmianie hex->ascii:
p4{all_of_your_zips_are_belong_to_us}

English, do you speak it? / Do they speak English in "what"?
Zadanie polegało na napisaniu bota, który po otrzymaniu akapitu w jednym z kilku języków odpowie, jaki to był język.
Najprościej znaleźć w internecie listę 1000 najpopularniejszych słów w danym języku i dla każdego z nich zliczać, ile jest
trafień, by wypisać najlepszy strzał. To działało dla pierwszej części - w drugiej niestety nie byłem w stanie znaleźć
dobrego słownika dla np. języka arapaho, plemienia indiańskiego. Na szczęście mogłem wykorzystać sam serwer jako dawcę próbek

  • po prostu odpowiadałem zawsze arp (skrót od arapaho) i jeśli nie było błędu, oznaczało to, iż mam próbkę tego języka.

piet
Szybko można znaleźć stronę http://www.bertnase.de/npiet/ zawierającą npiet - interpreter języka, oraz npiet-foogol, który jest
kompilatorem z języka foogol do języka piet. foogola również nie znałem (obviously...), ale po HelloWorld w nim to:

begin
  prints ("Hello World!\n")
end

Ten można natomiast łatwo zmodyfikować, aby wypisał potrzebny tekst.

Kapitan Rozdil
Po znalezieniu oryginału obrazka w internecie i porównaniu z naszym za pomocą narzędzia compare, dostajemy taki widok:
http://imgur.com/oa97kVF

SS-93 #1

strings -n 10 stegano2.wav | grep p4{

p4{zawsze_ostatni_:(}

SS-93 #2
Po otworzeniu pliku w Audacity i wybraniu analizy spektralnej, dostajemy:
http://imgur.com/d094rMw

C3ntrum N$A
Wystarczy zmienić flagę w ciasteczku.

D0 Y0u 3v3n PHP? #1
Patrząc w źródło strony, widzimy komentarz dotyczący parametru debug=1. Flaga jest na linku:
http://web.ctf.4programmers.net/web1/?debug=1

D0 Y0u 3v3n PHP? #2
Na tej samej stronie dostajemy kod php. Flaga jest porównywana z polem "password" za pomocą funkcji strcmp.
W dokumentacji PHP czytamy w komentarzach, że strcmp zwraca zero (oprócz gdy stringi są równe) także przy błędzie,
np. gdy jeden z argumentów jest tablicą. Zmieniamy więc w requeście pole password na password[] i otrzymujemy flagę.

Koty MSMa
Znamy miejsce ukrycia flagi i wiemy że zdjęcia kotów są wywoływane jako |url|?cat=Amber.jpg
Flagę otrzymujemy poprzez:
curl http://web2.ctf.4programmers.net/web2/show.php?cat=/home/flag.txt
p4{path_traversal_cats}

42
Po wpisaniu admin, dostajemy hasło admina: ICANSQL. Próbujemy więc sql injection:
' or '1'='1' or '1'='
Po czym dostajemy flagę.

Obfuscated
Jak sama nazwa wskazuje, należy znaleźć sens w udziwnionym kodzie JavaScriptu. Nie będę dokładnie się rozpisywał - wystarczy
dokładnie przejść instrukcja po instrukcji i w końcu odgadnie się hasła.

Księżniczka Lea
Musimy znaleźć takie $data i $signature, dla którego nie wykona się $signature !== hash('sha256', $key . $data), a
ponadto $signature zawiera w sobie stringa: "&user=admin". W treści jest wspomniane o HMAC, które po chwili googlania prowadzi do:
https://en.wikipedia.org/wiki/Length_extension_attack
Okazuje się, że istnieje już gotowy tool do podobnych rzeczy:
https://github.com/iagox86/hash_extender
Wpisujemy weń:

./hash_extender --data blah=qwerty --secret 20 --append \&user=admin --signature 
c700e9638661184e03a2c372b0639f4efd05f3814b08c83ba8461ef25addcdbd --format sha256

Otrzymujemy rozwiązanie ($signature i $data).

easymode

strings -n 10 re0.exe | grep p4{

p4{najprostsze_re_na_swiecie}

xorme
Korzystając z IDA'y, deasemblujemy plik. Po analizie, dostajemy coś, co można sprowadzić do kodu w C (pomijam wypisywanie błędów):

char xorred[]="\x7f;tw`}Pf{PnccPnakP{gjaPb`}jr"; // zawarte w pliku
int main(int argc, char** argv){
	int len=strlen(argv[1]);
	for(int i=0;i<len;i++){
		if(xorred[i]^0x0f^argv[1][i]){
			puts("Wrong");
			exit(0);
		}
	}
	puts("Ok");
}

Ponieważ xorred jest dostępny, a operacja ^ (xor) jest odwracalna, uzyskamy rozwiązanie poprzez xorred[] xor 0x0F:

s="\x7f;tw`}Pf{PnccPnakP{gjaPb`}jr"
print "".join([chr(ord(c)^0x0F) for c in s])

p4{xor_it_all_and_then_more}

Zadania z Captchami:
Użycie Tesseracta i naklepanie skryptu w Pythonie do automatycznego odpowiadania na zapytania pozwoliło na rozwiązanie dwóch pierwszych tasków.

Niezrobione zadania:
Remy Suarez Ascander
Analiza kodu w bodajże F#, a później coś z RSA. Jakoś nie bardzo mi się chciało zagłębiać w tę dziwna składnię (ale może to dlatego, że byłem wówczas już na szczycie rankingu ;) )

Where is my password #2
Myślałem, że to trudniejsze - ale nigdy nie byłem dobry w kryptografii. Jak mnie koledzy z IRCa później uświadomili, dało się to rozwiązać w dwóch linijkach, bo znamy plaintext, ciphertext i key, a potrzebujemy tylko IV: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
Bodajże: IV=P1 xor Decrypt(key, C1), gdzie P1 i C1 to odpowiednio pierwsze bloki plain- i cipher-textu.

Impossibru captcha
Captcha z kreskami - co prawda je jakoś usuwałem, ale jednak tesseract nie dawał rady ze zniekształconymi nieco literami.

Jeśli ktoś czyta ten tekst i się czuje głupio, że sam na to nie wpadł, to niech pamięta, że opisuję tutaj jedynie udane próby. Spędziłem sporo czasu brnąc w ślepe uliczki i próbując rozwiązywać zadania w zły sposób - nie zniechęcajcie się więc zbyt szybko, bo tylko ten, który nie próbuje, nigdy się nie myli.
Podsumowując, CTF zaliczam zdecydowanie do udanych :)

1

będą jeszcze trochę zostawione zadanka na serwerze żeby można było sobie rozwiązać teraz jak się ma podpowiedzi?
(chodzi o to żeby się czegoś nauczyć)

2

Hm, na cebuli poszedłem złym tropem, stwierdziłem, że skoro warstwy to pewnie flaga z części 1szej będzie przydatna w drugiej jako passphrase a tu zonk...
Oba RE banalne, objechałem to szybko skryptami do gdb. Jakby była wersja linuxowa to nie wiem czy ltrace'm nie opędziłbym tego jeszcze szybciej...
Język: część pierwsza banalna, pythonowskie langid+expect do zautomatyzowania tego i jazda...

Kpt. Rozdil... to ja tu bity odwracam, szukam sekwencji, cuda robię... a na to nie wpadłem. Wstyd... ;)

A serio... potwierdziło się, że jestem dobry w gdb i skryptach, webu nie znam wcale a w szyfrowaniu brak mi doświadczenia. Btw - czekam aż ktoś poda rozwiązanie zadania z rozpoznawaniem języków w wersji trudnej. Pierwszy mój trop to podobieństwo pewnych rzadkich języków do innych i odpowiednie przetworzenie pomyłki, ale czasu mi już brakło...

edit: skoro @Proxima się skryptami chwali, to i ja mogę ;) do zadania nr 2 oczywiście

set verbose off
set silent
file ./re1.exe
b *main+132
commands 1
	set $al=$dl
	print (char)($dl^0xf)
	continue
end
r aaaaasssssdddddfffffgggggjjj
1

Miałem podobnie jak @alagner troche ;p
Z xorme poradziłem sobie szybko na VM.

xor_str="w`}Pf{PnccPnakP{gjaPb`}jr"
out=""
c=0
for c in xor_str:
    for i in range(ord(' '), 127):
        if c == chr(i ^ 0xf):
            out = out + chr(i)        
print("p4{" + out)

Pierwsza część języków - w pare minut za pomocą libki cld
A reszta co mi się udało to pierdoły typu otwórz plik hexedytorem. Webu nie tykałem prawie w ogóle nawet bo nie trawie webdevu. Kiepsko mi poszło ;p
Jakbyście planowali następny, dajcie więcej RE i Misc(serwerki) : D

2

Obrazki z pieta

@Marszal

4bb86856c632818dc9df407384711ad9Marszal.png

@karol.pysklo

8198e588fb9ecf7771733dc62d2a9d0bkarol.pysklo.png

@Hummin

b943ac1750edeae353113aa9d69bd368Hummin.png

@WhiteLightning

fb7e607b08a9fc23ebef130e6023761aWhiteLightning.png

W nagrodę za to, że daliście radę się podpisać i wstawiliście obrazek, który najprawdopodobniej sami narysowaliście, wszyscy dostajecie 300pkt.

4

Język cz. 1 i 2 (Perl), niezoptymalizowałem PL i HU :)

if(($line =~ m/thn/) || ($line =~ m/oxt/)) {
  $lang = 'arp';
} else {
if(($line =~ m/ the /)) {
  $lang = 'en';
} else {
if(($line =~ m/ zu /) || ($line =~ m/ das /)) {
  $lang = 'de';
} else {
if(($line =~ m/vous/) || ($line =~ m/eux/) || ($line =~ m/ois /)) {
  $lang = 'fr';
} else {
if(($line =~ m/wek /) || ($line =~ m/szcz/) || ($line =~ m/iego /) || ($line =~ m/szci/) || ($line =~ m/anie /) || ($line =~ m/dzie/) || ($line =~ m/ w /)) {
  $lang = 'pl';
} else {
if(($line =~ m/sszo/) || ($line =~ m/ettm/) || ($line =~ m/ssze/) || ($line =~ m/szth/) || ($line =~ m/szola/) || ($line =~ m/gysz/) || ($line =~ m/ itt /) || ($line =~ m/ ki /) || ($line =~ m/tsz/) || ($line =~ m/egy/)) {
  $lang = 'hu';
} else {
if(($line =~ m/ y /) || ($line =~ m/eres /) || ($line =~ m/esas /)) {
  $lang = 'rmr'; # hisz
} else {
if(($line =~ m/aadh/) || ($line =~ m/aama/) || ($line =~ m/aana/)) {
  $lang = 'sa'; # sanskrit
}
2

Mój pierwszy CTF w życiu. Fajnie było sie zabawić.
Połowę z rozwiązanych zrobiłem w telefonie (przeglądarka i hexeditor).
Pozostałe python, wireshark na komputerze. Sposoby podobne jak @akrasuski1
Ad. xorme
xorsearch re1.exe p4{
Ad. Wykrywanie języka
Bot w pythonie. Wystarczyły pięciowyrazowe "słowniki" i zliczanie wystąpień
Ad. CAPTCHA
Python + tesseract
Ad. Kolorowa CAPTCHA
jw + zamiana tła na białe, a liter na czarne
Ad. Kreskowana CAPTCHA
a. Zliczenie wystąpień pikseli o danym kolorze.
b. Najczęstszy kolor to tło, na drugim miejscu tekst.
c. Pozostałe to linie
d. Zamiana tła na białe, a liter i linii na czarne
e. Potem jeszcze cv2.MORPH_CLOSE
f. tesseract i tak miał czasem problem z rozróżnieniem liter H,W,M. Tam gdzie wykrył H poddawałem ręcznej weryfikacji.

1

Świetny CTF. Mój pierwszy, choć chyba nie poszło mi tak źle. Zdecydowanie potrzebujemy takich więcej :D

Właściwie już znamy wszystkie rozwiązania, ale dorzucę coś do zadania z captchą, a mianowicie pliczek z wyszkolonymi danymi do Tesseract'u. Standardowe dane miały problemy z rozpoznawaniem litery Q, więc musiałem coś z tym zrobić. Trenowanie tego OCRa przysporzyło mi trochę problemów, więc dlatego się nim podzielę.
http://szymekk.me/files/ctf.traineddata
Pierwsze dwa zadania przechodzi idealnie (biorąc pod uwagę to, że captche z drugiego zadania zostały odpowienio spreparowane).

0

Szczerze mówiąc bałem się trochę że Captche będą za łatwe ze względu na to co wisi na naszym githubie, tzn:
https://github.com/p4-team/ctf/tree/master/2015-09-26-trendmicro/captcha
oraz
https://github.com/p4-team/ctf/tree/master/2015-10-02-dctf/misc_400_captcha
gdzie generalnie są kompletne solvery, jeden z tesseractem a drugi bez i każdy z nich po niewielkiej modyfikacji by to rozwiązał ;)

1

Czy ktoś mógłby powiedzieć jak zrobić zadanie Remi Suarez?
Ja próbowałem tak:

W google znalazłem że język użyty w zadaniu to OCaml (http://try.ocamlpro.com/)
Widać z funkcja szyfrująca oprócz flagi potrzebuje dwóch innych parametrów:
e = 65537
m = 13513545201780754751363061730973412461964840798555163524204230289623875027547891
(można je uzyskać bezpośrednio z interpretera)
Zostają dwie funkcje:

let rec p x y = match string_of_big_int y with | "0" -> big_int_of_int 1 | _ -> mult_big_int x (p x (sub_big_int y (big_int_of_int 1)));; 

let k x y = match x with | z when (compare_big_int x y) == -1 -> z | _ -> sub_big_int x (mult_big_int y (div_big_int x y));;

Pierwsza to rekurencyjne zapisana silnia, druga to modulo.
Szyfrowanie wiadomości to: Flaga ^ e mod m
Wygląda to na RSA, moim pomysłem był rozkład na czynnik pierwsze m żeby wyliczyć liczbę d potrzebną do rozszyfrowania ale na tym poległem - stąd pytanie, jak to zrobić?

0

Serio tutaj poległeś? ale przecież tutaj już nie ma nic trudnego. Na naszym githubie często jest opis do RSA bo zwykle jest zadanie. Rozkład m to minuta w programie yafu a wyliczenie d to modinv albo użycie algorytmu euklidesa. Nawet wikipedia opisuje jak z tego miejsca rozwiązać zadanie :) próbowałeś poszukać? ;)

https://github.com/p4-team/ctf/tree/master/2015-09-26-trendmicro/rsa
https://github.com/p4-team/ctf/tree/master/2015-10-18-hitcon/crypto_314_rsabin
https://github.com/p4-team/ctf/tree/master/2015-12-05-seccon/paillier_crypto_200

1

Jedna rzecz IMHO do zmiany w przyszlosci: nie dodawanie zadan w trakcie. Ja mialem tylko troche czasu na CTFa w piatek, wiec nie mialem nawet szansy by sie z nimi zapoznac a moze by wiecej punktow wpadlo.
Moja najwieksza wtopa to szyfr - tka myslalem ze to ASCII ale z lenistwa nie chcialo mi sie dekodera pisac (srodek nocy, po ciezkim dniu w pracy) i wrzucilem do jakiegos onlinowego, on sobie nie poradzil to zostawilem. A szkoda bo Base 64 i nastpeny bym poznal. Druga to koty - ze ja nie wpadlem zeby to curlem rozwijac, a robilem przez pasek adresowy:)
Ogolnie inicjatywa bardzo fajna, mozna poczuc jak inny tryb myslenia jest potrzebny niz przy pracy nad produktem. Mam nadzieje ze bedzie wiecej takich. To akurat bylo dla mnie w fatalnym czasie - weekend przedswiateczny, i mialem tylko jakies 4h w piatek w nocy na zabawe.
Kolejna rzecz na wielki, wielki plus - to pierwsze najlatwiejsze zadanie, gdyby nie to nie zabralbym sie nawet za inne zadania, a tak to zadzialal mechanizm jeszcze jednej tury:)

A mam jeszcze pytanie o zadanie z FTP - plik sie tam fizycznie znajdowal, czy trzeba bylo sobie samemu z pcapa poskladac?

1
WhiteLightning napisał(a):

Druga to koty - ze ja nie wpadlem zeby to curlem rozwijac, a robilem przez pasek adresowy:)

Nie musiałeś używać cURL'a, ja sobie wywołałem przez pasek adresowy i po prostu zapisałem i otworzyłem notatnikiem.

Where is my password#1 - stwierdziłem, że klucz po zwykłym hexdecode, to będzie za proste i nawet nie spróbowałem dekodować :(

0

Jedna rzecz IMHO do zmiany w przyszlosci: nie dodawanie zadan w trakcie.

Nasz największy problem przed rozpoczęciem CTFa polegał na tym, że nie mieliśmy zielonego pojęcia: ile osób weźmie udział, jaki poziom będą reprezentować, jakie poziomy zadań mamy przygotować, etc. Baliśmy się, że np. połowa zadań może pozostać nierozwiązana więc po tym jak zaskoczyliście nas frekwencją oraz poziomem postanowiliśmy dodać przynajmniej kilka trochę trudniejszych zadań :). A samo dodawanie zadań w trakcie jest bardzo częste na normalnych CTFach.

2

Kurcze - wczoraj cały dzień byłem offline i nie ma 1 miejsca :( Ogólnie CTF na propsie - zadania fajne, wszystko działało i czuję tylko niedosyt, że nie miałem niedzieli. Ale cóż, wyszły dużo ważniejsze życiowe sprawy.

No i muszę kupić książkę do IDY

Wszystkie rozwiązania są spisane, ale dodam, że w księżnicce Lei można było zakodować znak równości na %3D i otrzymać flagę.

PS. Jakby ktoś chciał stworzyć team CTF w celu dalszej nauki to jestem otwarty na propozycję :P

1

@Shalom - wiem ze konwersja z ASCII jest prosta, ale ja juz naprawde bylem w stanie gdzie myslenie boli, a ze w google wyskoczyla mi gotowa stronka to skorzystalem (co oazalo sie bledem). Swoja droga jakos nie moge sie za Pythona zabrac, bo w miare dobrze znam Perla i przewaznie skrypty do przetwarzania pisze tam, wiec szczerze to nie widze co bym zyskal, wiec jesli ktos potrafi tutaj jakies korzysci podac, to bede wdzieczny.
Na nastepnego CTFa bede tez lepiej przygotwany, mam juz wirtualke z Linuxem. Zainstalowanego Cygwina, Perla, Pythona, Ide (legalna), Wiresharka pod Windowsem, przetwarzarke do PNG (czasem tak mozna prawie za darmo flage wyciagnac). Teraz jeszcze pare skryptow sobie zrobie i bedzie lepiej... Najwazniejsze ze udalo sie pierwszy krok w strone CTF zrobic, bo do tej pory tylko czytalem write-upy i myslalem ze moze kiedys..

5

musze przyznac ze dalo mi to niespodziewanie duzo radosci (glownie przez to ze udalo mi sie pare rzeczy rozwiazac, choc przewidywalam ze to beda kompletnie nie moje klimaty)

zadania byly ciekawe, imo bardzo dobrze dostosowany poziom trudnosci, organizacja pierwsza klasa, szacun dla autorow :)

troche mi przykro ze nie mialam wiecej czasu zeby rozkminic wszystkie, nastepnym razem (bo beda nastepne?) musze wymyslic jakas rozrywke dla rodzinki, bo tak z doskoku rozwiazywalam. albo dostosujcie czas pod matki polki, 2 tygodnie zamiast 2 dni? ;)

zadania rozwiazalam przy wsparciu dev tools z chrome, notepad++ i f# repl.
podjelam sie, ale nie zrobilam:

  • C3ntrum N$A - bo glupia kombinowalam jak tu swoj ip przeklamac w headerze
  • Do you even captcha? - w sobotni wieczor wpadlam na genialny pomysl, czemu by nie zaimplementowac solvera do captchy (zamiast uzyc jakiegos istniejacego, jak sugeruje logika). ok 4 rano w niedziele okazalo sie ze debugowanie mojego programu nie przybliza mnie do udanego submita 200x pod rzad :(

jeszcze raz, wielki uklon w strone organizatorow.

1

Podpiąłem w 1 poście linki do Webów oraz do Misców jakby ktoś je chciał uruchomić sobie lokalnie albo przeanalizować jak działały (ale serio, szału tam nie ma :D).

Poza tym pamiętajcie o ankiecie bo póki co jest tylko 35 głosów! No i zapomniałem w ankiecie najważniejszego pytania: jak sie podobała piosenka?
;)

2

Po pierwsze, dzięki za zorganizowanie tego eventu. Super sprawa :)

Szkoda, że nagrody tylko dla użytkowników forum; gdy doczytałem o tym w sobotni wieczór, to motywacja mi na tyle spadła, że nie ruszałem już tych nietrywialnych zadanek :/

Tesseract- u mnie z kolei miał problem z rozróżnieniem Q i O. Dodałem proste sprawdzenie koloru piksela w miejscu, gdzie powinien być ogonek :)

Forensics 2- tyle przegrać! Skompletowałem Wiresharkiem sobie tego zipa, posortowałem po rozmiarze zawartość w windowsowym explorerze, a że wszystkie pliki miały pokazywany rozmiar 1KB, to uznałem, że to nie to...

Czy tylko ja miałem problem z xorme pod OllyDbg? Po samym załadowaniu pliku pokazywał, że:

debugged application has modified the debugging registers. Maybe it called ZwContinue() or SetDebugContext(). The
modifications are saved to the log
Po krótkim researchu w google'u udało mi się zlikwidować jeden powód takiego zachowania, patchując funkcję IsDebuggerPresent żeby zwracała zawsze 0, ale ciągle coś nie pozwalało przejść do "normalnego" debugowania. Niestety znam tylko podstawy RE, więc po krótkiej dodatkowej zabawie z IDĄ uznałem, że "a, namieszali tam z cygwinem" i zostawiłem to zadanie.
2

Ten CTF był super, czekam na następny!
A od siebie dodam kody programów do dwóch zadań:

  1. To z botem do rozpoznawania języków:
    ogólnie algorytm jest taki, że dla każdego języka mamy mini "bazę", no dobra, listę z bardzo popularnymi wyrazami (można w necie znaleźć)
    teraz dla każdego języka zliczamy wystąpienia tych słów kluczowych i jako odpowiedź wysyłamy język który ma najwięcej wystąpień tych słów kluczowych. Np gdybyśmy mieli 2 języki: polski i angielski i listaPL = " tak ", " nie ", " jest ", " co ", a listaEn = " this "," the "," yes "," no "
    I serwer przysyła tekst:
    Tak mi dobrze, tak mojo, aż rechoce się serce.
    Same nogi mnie niosą gdzieś — i po co mi, gdzie?
    Idę młody, genialny, niosę BUT W BUTONIERCE,
    Tym co za mną nie zdążą echopowiem: — Adieu! —

to współczynnikPl = 5, a współczynnikEn = 0, wobec tego wysyłamy odpowiedź "pl"
To działa lepiej dla dużo dłuższych tekstów i lepszej listy słów kluczowych
Drugą wersję tego zadania rozwiązywało się podobnie, przyczym pomocna była obserwacja że w języku "arp" bardzo często występują znaki "e" i "h"

Kod w javie

package MainPackage;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.Arrays;
import java.util.List;

public class Main {

	private static final int __PORT = 37330;  
    private static final String __HOST = "5.135.165.156";  
    
    static List<String> listPl = Arrays.asList(" tak ", " nie ", " jest ", " co ");
    static List<String> listEn = Arrays.asList(" yes ", " no ", " and ", " or ", " the ", " this ", " that ");
    static List<String> listDe = Arrays.asList(" ich ", " ist ", " der ", " die ", " das ", " ein", " gern ");
    static List<String> listFr = Arrays.asList(" voyez ", " monde ", " au ", " l ", " il ", " pas ", " le ", " que ", " vous ");
    static List<String> listHu = Arrays.asList(" ha ", " jok ", " addig ", " hogy ", " nagy ", " igy ", " en ", " nem ", " egy ", " meg ", " es ");
    
    public static boolean isGoodChoice(int a, int b, int c, int d, int e){
    	return a>=b && a >= c && a >= d && a >= e;
    }
    
    public static String translateRespFromServer(String str){
    	int ctrPl=0;
    	int ctrDe=0;
    	int ctrFr=0;
    	int ctrHu=0;
    	int ctrEn=0;
    	for(String s : listPl){if(str.contains(s))ctrPl++;}
    	for(String s : listDe){if(str.contains(s))ctrDe++;}
    	for(String s : listFr){if(str.contains(s))ctrFr++;}
    	for(String s : listHu){if(str.contains(s))ctrHu++;}
    	for(String s : listEn){if(str.contains(s))ctrEn++;}
    	if(isGoodChoice(ctrPl, ctrDe, ctrFr, ctrHu, ctrEn)){return "pl";}
    	if(isGoodChoice(ctrDe, ctrPl, ctrFr, ctrHu, ctrEn)){return "de";}
    	if(isGoodChoice(ctrFr, ctrDe, ctrPl, ctrHu, ctrEn)){return "fr";}
    	if(isGoodChoice(ctrHu, ctrDe, ctrFr, ctrPl, ctrEn)){return "hu";}
    	if(isGoodChoice(ctrEn, ctrDe, ctrFr, ctrHu, ctrPl)){return "en";}
    	return "en";
    }
    
    public static void main(String argv[]) throws Exception
    {
     String sentence;
     String fromServer;
     BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
     Socket clientSocket = new Socket(__HOST, __PORT);
     DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
     BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
     int ctr=0;
     fromServer = inFromServer.readLine(); //CHoose: fr,en,de...
     while(ctr < 303){
    	 ctr++;
    	 //sentence = inFromUser.readLine();
    	 //if(sentence.equals("BREAK"))break;
         //outToServer.writeBytes(sentence + '\n');
         fromServer = inFromServer.readLine();
         System.out.println("FROM SERVER: " + fromServer);
         fromServer = translateRespFromServer(fromServer);
         System.out.println("sending: " + fromServer);
         outToServer.writeBytes(fromServer + '\n');
         fromServer = inFromServer.readLine();
         System.out.println("RESULT: " + fromServer);
     }
     clientSocket.close();
    }

}
  1. Hasło Shaloma
    Jak zrobic to zadanie napisał już ktoś wcześniej, nie podał jednak kodu przydatnego do rozwiązania:
keys = ['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', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '\n', 'esc', 
'backspace', '\t', ' ', '-', '=', '{', '}', '\\', 'number', ';', 
'\'', '~', ',', '.', '/', 'caps']
 
infile = open('keyboard2.txt', 'r')
outfile = open('keys.txt', 'w')
 
str = infile.readline()
len = len(keys)
output="";
while str != "":
    svalue = str.split(":")[2] # we are interesting in a third byte
    value = int(svalue, 16) - 4 # first symbol have code 0x04
    if value >= 0 and value < len:
            #outfile.write(keys[value])
            #print(keys[value])
        output += keys[value] 
    str = infile.readline()
print(output)

plik z wejściem wyglądał następująco:

00:00:13:00:00:00:00:00
00:00:21:00:00:00:00:00
00:00:39:00:00:00:00:00
00:00:39:00:00:00:00:00
20:00:00:00:00:00:00:00
20:00:2f:00:00:00:00:00
20:00:00:00:00:00:00:00
00:00:0c:00:00:00:00:00
20:00:00:00:00:00:00:00
20:00:2d:00:00:00:00:00
00:00:2d:00:00:00:00:00
00:00:24:00:00:00:00:00
00:00:21:00:00:00:00:00
00:00:0e:00:00:00:00:00
20:00:00:00:00:00:00:00
20:00:2d:00:00:00:00:00
00:00:2d:00:00:00:00:00
00:00:18:00:00:00:00:00
00:00:1f:00:00:00:00:00
00:00:1c:00:00:00:00:00
00:00:19:00:00:00:00:00
00:00:19:00:00:00:00:00
00:00:21:00:00:00:00:00
00:00:10:00:00:00:00:00
20:00:00:00:00:00:00:00
20:00:2d:00:00:00:00:00
00:00:2d:00:00:00:00:00
00:00:10:00:00:00:00:00
00:00:21:00:00:00:00:00
00:00:22:00:00:00:00:00
00:00:0e:00:00:00:00:00
00:00:0c:00:00:00:00:00
20:00:00:00:00:00:00:00
20:00:30:00:00:00:00:00
00:00:30:00:00:00:00:00
00:00:39:00:00:00:00:00

Dodam że program do 2) dało się znaleźć w necie

Gdyby ktoś miał jakieś pytania odnośnie programów to proszę pisać śmiało
Pozdrawiam

4

To mój pierwszy post na forum, więc witam serdecznie :). Zaglądam tutaj od ponad roku, ale nigdy nie czułem potrzeby aby się rejestrować i dopiero chęć uczestnictwa w CTF-ie mnie zmotywowała do założenia konta (chociaż @panryz uzna to pewnie za duży minus :P ). Nie jestem programistą, chociaż czasem coś zakodzę, bawiłem się też reverse-engineeringiem kilkanaście lat temu, dłubałem w różnych unixach, sieciach itd. więc coś tam wiem. Ponieważ jednak nigdy wcześniej nie brałem udziału w żadnym CTF-ie, obawiałem się czy uda mi się zrobić chociaż jedno zadanie. Okazało się, że udało się zrobić 11 (nie licząc intro). Nie będę opisywał moich rozwiązań, bo są identyczne, lub bardzo podobne do wcześniej opublikowanych. Opiszę tylko moją fatalną przygodę z Kapitanem Rozdilem, bo przez głupi błąd straciłem wiele godzin i nie zrobiłem tego zadania. Gdy tylko przyjżałem się obrazkowi i dostrzegłem że da się zauważyć jakieś znaki, zacząłem kombinować z filtrami w gimpie (zmiana kontrastu, wykrywanie krawędzi), ale ponieważ efekty były słabe, to następnym pomysłem było, że może gdzieś w sieci jest ten obrazek bez naniesionego napisu, wtedy wystarczy odjąć od siebie obrazki na warstwach. Obrazek szybko znalazłem, odjąłem, coś się pojawiło na czarnym tle... jeszcze tylko autolevels, żeby lepiej było widać i dostałem takie coś http://s11.postimg.org/rx99tsgtf/rozdil.png. W tym momencie pomyślałem że zadanie ma jakieś drugie dno i brakujące w środku znaki trzeba jakoś wyliczyć. Ponieważ ciąg znaków wyglądał jak hash md5, to zacząłem sprawdzać md5 popularnych słów i słów mogących mieć związek z zadaniem (nazwa pliku, rozdil, cat, kapitan itd.). Straciłem mnóstwo czasu na bezproduktywne kombinowanie, a nie przyszło mi do głowy, żeby zamiast robić autolevels, pobawić się krzywymi, wtedy można uzyskać cały tekst.

Mam dwie uwagi do organizatorów. Po pierwsze fajnie byłoby, aby w każdej kategorii była podobna ilość zadań (więcej re, więcej re ! :) ), po drugie 200 punktów za zadanie easymode, gdzie wystarczyło tylko zajrzeć do pliku aby znaleźć flagę, to za dużo. Za takie coś powinno być 50, góra 100 punktów.

Poza tym dzięki za zorganizowanie tak fantastycznego konkursu i czekam na następny :).

1

Obrazek szybko znalazłem, odjąłem, coś się pojawiło na czarnym tle... jeszcze tylko autolevels, żeby lepiej było widać i dostałem takie coś http://s11.postimg.org/rx99tsgtf/rozdil.png. W tym momencie pomyślałem że zadanie ma jakieś drugie dno i brakujące w środku cyfry trzeba jakoś wyliczyć

W tym momencie to faktycznie słabo, brakowało Ci jednej cyfry właściwie. Na upartego mogłeś spróbować wszystkich 16 możliwych flag nawet.

Po pierwsze fajnie byłoby, aby w każdej kategorii była podobna ilość zadań (więcej re, więcej re ! :) ), po drugie 200 punktów za zadanie easymode, gdzie wystarczyło tylko zajrzeć do pliku aby znaleźć flagę, to za dużo. Za takie coś powinno być 50, góra 100 punktów.

Ok, przyjeliśmy do wiadomości że za mało RE. Na następnym CTF będzie 10 zadań RE (i ciekawszych, bo oba zadania były w końcu prawie najprostsze możliwe) :P. Easymode celowo było takie trywialne, chociaż faktycznie 200 punktów to za dużo.

Ale zrobliśmy sobie przed CTFem google doca gdzie każdy kto rozwiązał zadanie oceniał ile punktów jest warte, i tak jakoś wyszło.

(i dzięki za opinie).

(dłuższy post, może z jakimiś statystykami etc, później wieczorem)

0

Ja chciałem wziąć udział, ale niestety zdążyłem zrobić tylko pierwsze zadanie :P. Weekend przed świętami miałem bardzo zajęty.

1
akrasuski1 napisał(a):

Flaga 4:
Powtórka z flagi 1:

s='66 65 65 66 65 65 65 66 66 66 65 65 66 65 65 65 65 66 65 65 65 66 66 65 65 65 65 65 66 66 79 78 76 89 79 78 69 77 79 82 69'
"".join([chr(int(x)) for x in s.split(" ")])
'BAABAAABBBAABAAAABAAABBAAAAABBONLYONEMORE'

Flaga: ONLYONEMORE.

Flaga 5:
Tekst to ciąg liter A i B. Sugeruje to użycie kodu Bacona (http://rumkin.com/tools/cipher/baconian.php). Po wklejeniu tam
naszego ciągu (i wybraniu opcji i=J and U=V), dostajemy flagę THEEND.

Co za bezsens z tym "kodem" Bacona i podstawianiem I=J, U=V. To ma być jakieś security by obscurity? Ja zdekodowane liczby potraktowałem wprost jako indeksy w alfabecie łacińskim i wyszło mi SHEEMD. I na tym koniec. <foch>

0
akrasuski1 napisał(a):

Where is my password #2
Myślałem, że to trudniejsze - ale nigdy nie byłem dobry w kryptografii. Jak mnie koledzy z IRCa później uświadomili, dało się to rozwiązać w dwóch linijkach, bo znamy plaintext, ciphertext i key, a potrzebujemy tylko IV: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
Bodajże: IV=P1 xor Decrypt(key, C1), gdzie P1 i C1 to odpowiednio pierwsze bloki plain- i cipher-textu.

Próbuję wyliczyć IV dokładnie w ten sposób, ale dostaję śmietnik:

  1. Biorę pierwsze 16 bajtów ciphertextu (128 bit, 1 blok AES) i dekoduję kluczem z części 1
  2. Robię XORa bajt po bajcie z pierwszym blokiem plaintextu

Zastanawiam się, czy gdzieś nie robię błedu?

1
aes = AES.new(key, AES.MODE_CBC, '\x00' * 16)
print ''.join([chr(ord(a) ^ ord(b)) for a, b in zip(aes.decrypt(ciphertext[:16]), plaintext[:16])])

1 użytkowników online, w tym zalogowanych: 0, gości: 1