Alternating Substitution Ciphers

For the entire day I had the pleasure of trying to break what I will call an Alternating Substitution Cipher. Let me explain.

Cipher Internals

Given our plaintext “example” we will encrypt it using two Simple Substitution Ciphers. One cipher will be applied to the letters in even positions (“xml”) and another cipher applied to the letters in odd positions (“eape”). When determining which cipher to use to encrypt a letter you alternate from the previous cipher used, hence Alternating Substitution Cipher.

But how do you break this cipher?

Breaking Simple Substitution

Breaking a simple substitution cipher is not too difficult, you can use letter frequencies and the dependencies between letters to reverse engineer the key and break the decryption. You can even automate this process, here is a snippet of code from lantern which does that:

simplesubstitution.crack(ciphertext, fitness.english.quadgrams)

Breaking Alternating Substitution

Automating the breaking of Alternating Substitution is difficult but not impossible. The difficulty here is that you are restricted to only letter frequencies, dependencies between letters are broken due to the alternation. Given enough ciphertext and a well tailored frequency distribution to compare against, we can break it. Here is my lantern code to do so:

cipher_a, cipher_b = split_columns(ciphertext, 2)
decryptions_a = simplesubstitution.crack(ciphertext, ChiSquared(custom_distribution_a))
decryptions_b = simplesubstitution.crack(ciphertext, ChiSquared(custom_distribution_b))
print(combine_columns([decryptions_a[0].plaintext, decryptions_b[0].plaintext]))

Yep, 4 lines. We separate the ciphertext into two columns and crack each substitution cipher separately, scored using chi-squared against a custom distribution. Once cracked just combine the plaintexts back together.

Warning!

custom_distribution can and will hurt you. Since you don’t have the luxury of letter dependencies this distribution must be incredibly accurate. Small variations can significantly affect the accuracy of decryption.

How did you find the correct distribution?

To be honest I cheated. I ended up solving the cipher by hand then using the plaintext to form the distribution in order to automate the breaking of the cipher.

Well gee, what if I can’t do that?

That’s where I’m still thinking. I could make lantern provide different distributions to use without a user needing to find and tailor their own. This may help is certain scenarios but obviously not all.

My best solution for this is to implement a two step solution. First is to have code to fiddle with the key found through automation. Since it could have matched on an inaccurate distribution, swapping around letters from the target distribution could move the decryption closer to the correct solution. Secondly, implement a manual decryption terminal session which starts off from the previous automated data. Basically giving you the best head start possible while you fiddle with the keys to crack the cipher.

Update:
I wrote an algorithm which breaks it automatically! It’s not 100% accurate though, some manual tweaking is needed at the end. Essentially it’s a 3 dimensional hill climb that scores based on the combination of the individual ciphers. This way we can use letter dependencies to get much more accurate results. I may make it into a module into lantern. We will see how it organically grows over time.

Try Yourself

Here’s the cipher in case you want to try! If you use lantern let me know how it goes!

 

Expand for the cipher

IXJYTJDFALHEJWSLCXSSFYSSJBTJSPBJSYJXTLQSFZDGSSCXPYIZIBCYTJSJSBFHSSJAZLKKBJSYJXHCFIZYJXSJMPZQUGMYTPASCYJKCYSPDSFZLPJXTLWJDFCYHCFEJBFHTPQAVYTPIUQEFYUGMYTPZLHYNIFWSPMGULDSIIMLDZLPFWCXPJSDMPSYVBJUZEIXHJQPMJDFHGVGEHJPSSFYCYKGEUQXSSFRJSFZFXVSFXQJDYTPXJHETJJCSSJBFQQJDLTBFHTPQSJWKSCUQWJXHCFEJHALHYTJHCCWHYHSJSJUQYTPRGIWSSCXPZIBDAVJSHJLMBCYTGDPRLALDZSSJXAJSSSSJGSSJWRLAHTPMILAJZCYHCFEJLZUIRJWSSJBMGDFALVAJFCXDJDFFYSSJXIHJLDZGIHYDGALHJHLCZHSJBFHTLMZFYAGMKIXSSJBTJSPBJSYJXASCETBFHZQCXPTEJSPHYCUZLDZSWVJDFSGRIMWDGQGEASCJPZJDFSSFYCYALHLZUXPFXSCIWCYHFIGQAEYSSJAZLKKBJSYJXTLQAJPDCCXCHTPQBCYTPFWZJJWCXSSJLUYJWDGIXFXQHIBTJZPFUCEJBFHHJSYCXPEEWZPQIRJDLKGMXJWICSSJFMPFYFWXETLCWTLZCSLZKCXPYISJWHPZCFXQSFUULHUJPRYTPBJSYJXTLQAJPDSFRCXPLPWFXQFFMJGUWIMRHAJSSSSJAFUZGUBIWHYJZFUCEJSFZLPJXSWVJDFSGAJDZEDFXQSFZLPJXMGZUCXPJSIRLDZQGAXSJZUCYTLQLZUKGXPEXQGDPFFFJDLDZSSJWJJSBFHHDMPFZIRJWSSJSJLMYTWEFFUZKDGSHFXQYFXPUJHAJSSSSJKCYSPDWEXDJDFFCSPMJSHIBDYFJZJDYTPXJQZZPISVGEBCEBPQUCYSUJYTJDFKWCPQLZJKPKLSETJDFEDSSJKCYSPDLDZPJWJDFCYFUCYSUJKCHHYIMFKJJSIDZJWHYFXQYTLSJSBFHCXQJHFMLKPMPFUZQQJDLTGEFTYSGTLWPSLEFTYVGEAJYSPMMFXDPMHVGEGEFTYQJDLTQIIBXIBVGEGEFTYHSJLQZJZZGIKCXPWJDMGFETCEUZQFYSSJGZZKLSLDZHDJLBJDFCXFHKWIHHLWGCEJLHHTPKGEUQMFXFFJLDZSSJXHSJHKWFMLUJZLLKKCXSGSSJLMMKSFJMYFKCXPYTPBJSYJXFXQYTPAGMHSPQBCYTSJWFXQAJFFXAJDZCXPIRYTPLLZUFFFJDAEYHSJZCZDYPPSGDRJWVCFHSLHHTPALHYFUBJDFFUZYTPSJXPHGXPSJXPHYIYTPBJSYJXFXQHIMJYCMJHSGTPMHJUUKCYSQHLSRJWVZJMEWJUVGDSJWBXJPRWJYJXQJDFSGALSETYTPRWIFMPHHICSSJBCXQJDFFXQXIBFXQYTPDDEYSJDFIISGDPRLALDZPPDYZQSGEETJDFSSJAFUZLHJUJSBIIZZLPPUFZSGTPZDCCCYXJPSSZIQIIBXIBASFYSGXGMWIBCHBJSYVLZJKPLPPLDQIIQSFRJFEPHHJZCCVGEZLPJXEDCXSSJBCXQGABCYTMJGDUVZCXFSALHMFKCXPQIISJQQHGVGEEIIZZDYCBFHALSETJDFSSJAIQHFJYSJDFCXHYCEBHUGMYTPLGDCCWJLDZCYALDYHDZPDYVGUHSJKKHKCYSQIXZQCYPGSHIEIUQLDZCYHXIBJZHGSSJQTLQYIUJLWPICUXJRJWXJDZBJSYVBJUZFILDZHPJYTPLGDCCWJYIMIWMGASJWJLZJKPAGEXQYAGIWSSMPJYEWDHICSSJBIWHYJZMGEXQYTPBJSYJXHXJEBNEHSYIHJPTGAJSBIIZZZGIKSSCHZPQYILHEMLXAZPCXASCETYTPLLZUMGZUJZQGAXEDIXSSJCZGIWFXQQFWQHFXQQFWQHICCYPGSIDBIIDZFFFJDZIQIIBXIBCBFHHGFXPWVKCYSQFUCEJBJXSGDLHHIGDLHYTPVBJWJEIMUGMYFAZQHPSYZPQLPLCXASJXCHFBFUZYTPXJHETJJCVGESFZLPJXQGCXPJALHRJWVXJLMUVGRPDJDFSSJBCXQGALDZRISYCXPQIIIISJDYIYTPHXIBFXQQIIQSFRJZJHJWWPQJSQIIZJSYZPXJHETJJRIIHZFWZJDFASFYTLWPVGEFIYSGHLVCIWVGEWHPZCDGAZIXSJDYJWMIRYXPHSJBJXSGDSIUQJDFEDIXJCCXPPMJXFIJDFSGSPZUVGELZUVGEWULEUSHDIXAJWIXJQIIHTEPFKJZSBCEJBTJZPQJDLTBFHALHSCXPQIIMCFEJYTJHMIWDJDFDGAQIIKLDYQPDQCYBJSYVJTPFWQQIIASFYHYTLSQIIHLVDMPSPDZCXPYTLSYTPBJSYJXALHHRPFKCXPSJWRLABJXSJDYIQIIMPVPAPZUSSFYHQIIMCFIZYUGMKJPRJDFVGEWJQJHIDJXCCVGEZHSEYSSJMSJPSSIRJSBIIZZDYTLWPTLRDJXJZDGAZIXSMFKJLDQXGMPJOKIHPHAEYZJHYJXDIXAJWSBIQIIRIZUJZHXIBQWIDFBFQLQSSJYFJZNEHSLHJTLQDEYQGAXSSJHFIKPMGUMCUBAJCIWJSJWASFYVGEBJWJYTJMHSQAPMPVGESIBQGVGEKDGAHTPALHXSYTJMHSQSGIXIBUGMXEMLPMYTWJPVGEIDBIIDZJRJWVACYICSSJBIWHYJZASCUJJALHXSUIGBJDFSSFYHYTWJPULEUSHBJSYVLDZVGERJXIYLPJXRIDJHSJZUGMLDQICSSJMVPSQIIBXIBCMHLWJDFEDFUZQIIMDEXCHTMJXSHUGMBJZDPHZFQAPJKHIRDIHJYTPVSFZHLWPQIRLZUXQRIDJHSXPDYHHTPAPDYIXSLZKCXPMIWJYISJWHPZCSSFXSSJKCYSPDBTLSBIIZZSSJQQGFYSSJPDZICFQJLMJHSIIZZLPHPDYSGRWCHIXCHEDRGHPASJXSSJZFQKLXPIWZPSMJHJPHIRDIHJPFETDEXCHTMJXSBFHSGLPPGCXPBCYTGEYFZCXDPMYTPDBTPDYTPXJHPMLLUJZFQKLXPCHTGEUQSFRJYIFIBCYTGEYUJUYVZCXDPMHFYIXKPAPZUCHTGEUQXSMCXQYTLSMEETJQCFWMLSSJWPGAJSSIISYTPXYTLDPFYSSJMQGVGESJLMYTPHXIBFFFJDHSYTPAJDZIBRLDPHKCYSQTGAXCEJLDZHGUYCYHGEXQHGIHYFHCCHGXPIXJBFHBJHHCXPYTPAJDZIBFUZGWPMGEYHJQPCBIXQPMJUYTPHXIBZGWPHYTPSWJPHLDZUJJUQHSSFYCYBJHHJHSSJMHGPPDYZQFXQYTPDJSEIRJWHYTPXIRHDIPQIIBXIBAJSSFBTJSPNICUSLDZRPMSFDHJSHFQHFIYIHZPJDQLMUCXPHSJZUSSJHEMXPMEIMJHFFFJDLDZASJXSSJQALBPEDCXSSJHEMXPMKCYSQSSJQQWJHHYTPXHJUWPHLZUCXPWJPDLDZQLDEJLLGEYASJXJRJWSSJBCXQAZGAHISSSFYHRJWVDMPSYVEMJJZFUCEJZMGRDCXPYTPLLZUICAGMHSPQYIEZLRSJWTLDZHLDZCZIHIBCHTJSBFHSWEPCMHIMPSSJBIGQHZGIKHUJPRQCXSSJLEYEMDBTPDYTPZPFRJHFWJFJYSJDFLWIBDKCYSQKLDQIIRUFQKSJHHXIBQGDYHMCUJMVZJLMJXLHKCXPJSHJWCGEHZQLPKLEHJBTPDBJBJWJDZLVJDFGIHYDGAQIIALSETPQNEHSLHJUQIIEXQPMHSGIZCYFXQBTPDJHLCZKSJEBQIIRIMWJZAPZUCYALHLDJKPKSJEBKCYSQFXQWJLZUVJXJPSSSFRJBIXCCCYTLQXSAJPDCIWSSFYDLHYVKDJPSSYTLSEFMJBCFPUCXPZIBDLXGDFXQRJJEJHBJSYVZJLMUJYHDMPSPDZFXQSJWJJAJHSCEIIZZSPZUVGESFUUYTPSSCXPHFUCEJIHPQYIHFQLPPJDXCXPBCYTSJWULWGEWCYJDTWFHJUJYHDMPSPDZHSJSFZTLQTEJSPFUIXPLMFEMJXSBCYTSJWHJHYJWIXZQSSJZFQLPUGMPFUZAJEFIHPFUCEJSFZLPPIDBCYTUJYHDMPSPDZAPMPBJDFHLDZNIJPDHFXQSJWHJHYJWASIUCKJZLPCXPRJWVPOLKYTLQLMFEPQYTLSYTPVEIIZZDYLPKLEHJYTPMPAPMPIXZQSBIGUYTPXLDZFUCEJSFZLPJXMPQIKPQLSUFHSYIHFQAPZUVGEEFXLPIXJGUYTPXYTPDLDZCUZAJLZUSSJWJHSLDZIXKPHSJSFZMPFUZQUWCFTYJXJZTPMGZZDIMHJAVHTGEYCXPHEZQPDUVJDSJWJLMXEWHPQGZPSHRWJYJXQYTLSJXLTIDFMQTQFPDLFXQQIIMPFAIXJAEYSSCHCHSLBJDFEHFBFQUWIMFUCEJHHDJPKSSGSSJKCYSPDUJYHDMPSPDZSSFYVGEWJYTPMPQTEPJXBJSYVZIQIIBXIBCYTJDKCCVGEHFYEDFXQCIUQPQQIIMLMMHQIIQUIGBPOLKYZQZJBPTPMXIBQGSWVYTPMPHLQPFWFXQLZJKPPGSYTPMPQTEPJXICUYTPSLLUJLDZHPSJSIRAJCIWJYTPBJSYJXFHFMIZJUUGMJSYIJXJSLSPTGAPWPMYTPSSCXPZCZDYHIKEJPQDMJDECDFUZQFUCEJHFJQAJEFIHPSSJKCYSPDBIIZZDYUGZZCYHLMMHDMGRPMUVHIYIDEXCHTJSHTPTPZZCYEDSGSSJUIGBJDFPUFHHYTLSJSMCFTYHPJSIBHIZKVJSBFHFXQJUQIIMPDGSFIGQZCWJESUVHTPFZQPQJZURISQIISSMGEFTJDYIUIGBJDFPUFHHSIIHPTGABIIZZVGEUCKJYTLSXIBCCVGEUZGDUVLSYJXQKCYSQFXQXIYSLZKHGXIKSCUZYJUZQIIFUZMVJQPFHFAIISUIGBJDFPUFHHSIIHPUJMHSYTPMPHYTPMGIMVGEEFXHPJYTWIIPSSSJFZLHHSSFYHNEHSYTPHLXPFHIIMZMLAJDFMGIMIXZQSSJYTJDFHFIYTPIYTPMBFQCEFXHPJLZUICCYASJXCFJYEDIXFETLCWFUZAEYSSJACYLPTJDZSSJCCWJDZLKPISCZIHIBCHTJKGEUQHJPSSFYLJSJALDYHGXIKSSGBXIBASJYTPMYTPVRJLUJMPCXSSJBCXSPMQIIDPWPMEFXSPZUVGEKDGAIDUJHHGEWUJMPHMIKJHFXQYTPDHXGBPKGXPHIRJDYTLSWIGXYIGLISYTLSMFQLPIXZQRWJYJXKPGIHYSGXLBPCYZGIKFHCCSSJQTLQLUJMPAPZUSSJXSSJAIGBHFWJHIMJYTJDFZJBPIIMAIGBHIXZQSSJBIWQHPGSSJBMGDFALVJBXIBSSFYLPKLEHJJWPTPZZEDIXJGUGEWLGIKHYIYTPPUFHHLDZSSJXSSJQTGZZEDIXJJDYTPIYTPMWIGXSIBAGEUQQIIZJBPSGZJWPCXZGIKCXPFZLHHTGEHJKCYSQCBIXQPMJUYTPVZPJWPVGEMCUBJDYTPMPRPMSFDHUIGBJDFPUFHHMCUBJHXSFIGQYIZMJDKLISGTKCYSQDGABJEIMJYIYTPRLHHFFJQIIKLDNEHSHJPFUCYSUJDJPRGUYTPRLHHFFJJDUIGBJDFPUFHHSIIHPCCVGEUJLWPSSJZIGMGUGEWQWFBCXPWIGXBCZJGRPDLDZCYHRJWVUCKJGEWRLHHFFJLHCFWFHVGEEFXHPJGDUVQIIBXIBCYXLVAJTEJSPQJUCJWJXSGDAJQIXQGTKCYSQTGAXCEJJSBIIZZLPCCAPKGEUQGDUVFJYSSMGEFTJDYIUIGBJDFPUFHHSIIHPCMHIMPCYHFIYISHIKSLPFISJUIZYTJDFHJDJSUJYHDMPSPDZSSJWJHFBFQICPPSYCXPYTWIIPSCXSGCYHGXPTGAKCYSQZPSHRWJYJXQYTPPUFHHSFHPGSLZUHGUYZJBPPLEVJHIYTLSBJEFXPPSYTWIIPSASVJSHSIMXCXPJDYILHGMYICXJHYDGAJQPKUFWJJSUZAJPFHVPDGEFTYIFJYSSMGEFTHTPALHIRGDYTPKSCMDPVDCPKPASCUJHTPHLCZSSCHSSIIPSHSJSFWQUVKDPASIBHSJSFZPGSYTPMPFXQEJWSLCXZQSSJFZLHHALHAJFCXDJDFSGXPZYFBFQGIHYZJBPFAMJPSSHCUWPMQXJHYCXFXIYTPMMIMJXSLZJKPALHYTWIIPSSSJFZLHHFXQSFZGIXDJZZJPSSUVZIBDJDYIYTPZGIKCXPFZLHHMGIMSSJRJWVCCWHYSSCXPHTPQJQBFHSGZGIKASJYTPMYTPMPALHLUJMPCXSSJCCWJDZLKPFXQHTPALHTEJSPRUJLHPQYICCXQYTLSYTPMPALHLMPFUIXJAZLYJDFFBFQFHLWCFTYZQFHSSJGDPHSJSFZZPUYLPTJDZHGCHTLZULPFHALMMTPMPFHCBFHCXSSJGZZMGIMSSIIPSSLZJKPALMMJWCXULKYLPKLEHJYTPMPZULPDGIXJSJWJYIHKGZZXPFBFQUWIMSSJCCWJGTBTLSCEXCYZULPASJXSSJQHPJMJYTWIIPSSSJFZLHHCXTPMPFXQEFXSFJYFYXPSSJXHSJAJFFXZGIKCXPLLGEYFXQXIYCEJZSSFYASFYKGEUQAJHJPDCMGXYTPIUQWIGXBFHNICYJEIMXGDLDZEXCXSPMPHYCXPAEYSSFYFUZYTPMPHYALHLHZCCUPMPDYFHRGHHCAZPUGMJDHSLDEJYTPRJKYEWJHIXSSJBFUZXJOSYTPUJMPHPJMJZSGLPFUZLZJWPFXQYTPWPMQKUIEBGDYTPKSCMDPVDCPKPVGEKDGAQIIKLDGDUVHJPSSJAFEBGUJSJDYTPZGIKCXPFZLHHTLQFIYSSJCFEJGULZJSYZPIUQMFXFXQFMJDXJZFYTPMYTPVZIXSKJPRYTJHWIGXHIYCZVLHYTPIYTPMLZJKPSSIIPSSYISJWHPZCFHHSJXIYCEJZHPWPMLZGUYTPKSJHHMJXQGAXCXSSJSJLMYTLXGDFSSJECXQPMHLISJDLDGSSJWXGXPDYAJSSFUCYSUJGTGUHEWRWCHJHTPALHZIBDGDSJWTLDZHLDZBXJPHBFYKSCXPYTPXYTPKSJHHMJXAPMPALZKCXPLLGEYSBILDZSBISJWJLMPSSJWJZBJDFFXQYTPMPQTEPJXFUCEJHFJQJDLASCHRPMCIWUPFWICUWCFTYJXCXPYTPXLDZSSJWJLMPSSJBTJSPBJDFFXQYTPASCYJTEPJXHJSYCXPGDYTPJZPPICSSJHTGWPZLDZTPMPFWJYAGKLHYZPHBFUBJDFFWXJDLMMCZIXSYTJDKSSJQKLDSJLMMJHTPAPDYIXFHHSJDEYTPMSJLQEZGHPMZIBDLDZCMDPFWZQHIMPSSJQKLDYHPJMJJUPJUHGXPTGALHJUJAPMPCXWJHJLUJSJWJHIMJYTJDFLPPLDHNIJLBJDFIXSSJYFAZPLPTJDZFUCEJLDZXLQPTPMYEWDSJWTPFZGIHYCXSJXPSGHPJGDPICSSJBTJSPRLAXHWIUZGWPMLDZLPPJDKCEBJDFHSJBFYKSJZCYAJSSPWJLSEEWCGHJSQSGHPJBTLSBIIZZTLRDJXDPOYCYCHSSJRIJKPICXQKSCUQYTPASCYJTEPJXKWCPQGEYFHHSJWEHTPQDFHSYTPBJDFHGWJIUJXSUVYTLSHTPBXIEBPQSCMIRJWFMIXPYTPKJDZJWHMVDMPKJIIHUCUVMVJXDJWCLZKCYSPDLDZHSJAJFFXHEMLXAZJDFAJZZZQEDSSJHCZJGUYTPUPDZJWCMRPMJFUUJQZZPHYCEBHFJQYTPBJDFMILACXPSCHDGHPASCETSFZLPJXTIMYLQSSJCFUZSJSFZFWCFTYSGLPFUCYSUJLDXIQJZAJSSSSJTEPJXUGMSJBFHKGWPMPQBCYTLHSJHUWIMTPFZSGUGIYFUCEJBFHWPMQFXOJIIHYIAJGUIHPFXQLHYTPRGIWZJSYZPZJZQALHXJLMUVHKWJLXJDFTPMHJUUJDYILUJSHTPTLHYCUVDCEBPQIRYTPNIJPDLDZHPSSJWIXSSJYFAZPLQSSJHCZJGUSJWDGCHVUCYSUJZFIPSSPMYTPNIJPDFFHRPQLDZHLSZIBDYTPMLRJQNIIMXJQSSMGEFTYTPFJMSFZNICYJYFKJXFBFQTPMAMPFYTLDZUGMLXJDISPIWSBIHTPKGEUQZIXIYTJDFLISSEFSSJUCYSUJUCUVJDHCUJXKPFHHGIXFHHSJSFZMPKGWPMPQSJWLWJLSSFUCYSUJHTPKLZUJZIISYIYTPASCYJKCXPBTGALHHCYSJDFHIZKCUVLXGDFSSJLHSJHXJDZSSJRIUKLDGASFYWGZEFXIHFJQYTPBJDFZGIKCXPIRLDOCGEHZQCXSGSSJCCWJLHJUSJYTGEFTYSSFYALHYTPXGHYZJBPZQRUFEJYICCXQGDPLUJBXPEDRLDYJZSSJTEPJXASIBFHHYCUZLZJSYZPIISGUAMPFYTMCXQQIIKGXPEDSSJWJFEUFWALVZIXSFJYLUIBDIRLZJKPALSETPQYTPASCYJKCXPLHSJHZGAUVHSWEFPUJZEDUWIMLLMYIAFWSJZUFYZLHYHSJHFJQBTQVGEUZAJSIIMHFXQSIIMHPPSYCXPYIYTPSLLUJLSYTLSWFYJJQCFWLPSYJWTPZDVGESFZDYCAEYSSJKCXPYIGBXIXIYCEJGUYTPNIJHSJIXCYALHTEJSPKUJLMYTLSSJEIIZZDPCYTPMSJLMSJWDGMHJPTPMHILZJKPRJKKJZTJXIRRJWVFJXSUVLDZZJUYJZTJXLKWIHHMIWJHZGAUVYTLDHTPTLQUCCSPQYTPNIJPDYTLSHTPXJPSSXSYFKJSCHLWJLSSFBFQLISAJCIWJHTPRISSCMIXSSJYFAZPHSJYTGEFTYHSJMCFTYFHAPZUQIHYTJXLZJSYZPTPALHHIEIRJWJZAJSSFHTPHHTPHLCZFCSPMBFWQHSSFYHSJSFZDPWPMHJPDJDLZUTPMUCCJHEETLULKPFHSSJKCXPMFZJBTPDSJCIIDZTJXHJUUSJUQJDYTPFJMAVLDJDRCHCAZPTLDZFXQAJJDFQIHYJZTPALHCFWSGIMEETLHYIXCHTPQYIEMQIISAEYTJHPVPHLDZTJHMIISSAPDYIXPPSYCXPUFWPPMLDZZLMFJWFXQWIIDZJWFXQWIIDZJWSJZUTPMSFXQHTGIKHGAJSSZLEFTJDFSSFYHSJXJLMUVUJYTJXZMGRIRGDYTPUUIGMGTDZPFHJZIXSMFKJHEETCFEJHXQQPFWHSJEMJJZIISTEJSPUGMFJYSJDFSSFYSSJKCXPEIIZZDYTPFWTPMQIIXLBPXPZLEFTHIYTLSJKLDSFWQUVSIUQQIIFXQZIXSKJPRQIIMMIISSHGAJQPIDJXFUZYTPFHTPHBCUZFJYCXSGCYSSJWJXIBCYTJDKVGEWJYCZVPDGEFTHTPFZQPQLHHTPHMIGSSJZTJHSFJMLDZHPSSCMEDIXSSJYFAZPDPFWSSJTEPJXSSJKCXPJXMJZCLSPZQUPZUUUFYIXTJHAFEBLDZZLVDJWUPKYZQHYCUZLDZFUCEJBFHFUCYSUJLZLMMJZFYASFYHSJSFZQGDPFXQBJXSWIIDZSSJWIGXYIHJPCCHSJEIIZZUJDZFXVBFYJWSGSSMGAGWPMSCMTGAPWPMHTPKGEUQCCXQXIYTJDFLISLLGSYZPICCXBLDZASJXHSJFIYLLKKAJSSCYHSJCIIDZTPTLQWJEIRJWJZFXQSJLDZSSJTEPJXAPMPSLZKCXPYIFJYTPMJDLUWCFTYJXJZASCHRPMHIUIBSSFYFUCEJEIIZZTLMZZQTPFWASFYSSJQHLCZSSJKCXPBFHHLVJDFCLHHEWJQIIXQQPFWCYEWDPQEIUQYIYTPWPMQJXQHICXQASCHBPMHSGASCETYTPNIJPDWJDZJJZVGESFRJXSFIYFXVBTJHKJWHYTPTGMWIWICSSFYXGXPDYSSJKCXPBJXSGDJHSFUZXJRJWDPWPMCIWPPSQIIAJZUSSIIPSSSJTEPJXHLCZCCVGEZIXSMFKJLXPXGMLDZEMICCYFUCEJUIGBPQGDBCYTFMPFYCXSPMPHYFHSSJKCXPYIGBLDPDGMMIIHMJMIWFXQIXAIGBGEYICTJHDIEBPSLDZLPPLDBMJSJDFFHEZQPDYTGEFTYHYMIKKTPMLDZHSJYIGBSIUQGUYTPJXQGUYTPRPDECUASCETEFMJHIMJBFQIRJWTJHHTGEUQPMLDZLPPLDBMJSJDFUGMSCMSSJDIGMKCXPUIGBPQDEVYUJZFXQIDSFDRQFXQHSWEFPUJZAJSSSSJDJXKJZCIWHGXPSJXPAJSSIISHFQCXPLDQSSCXPAEYFUCEJBFHSGIHSWIXPCIWTJXLDZFYZLHYTPRLDYJZIISMVZJLMJMPFUZQXIHYPPSLSSCXDPMDJXKJZJKLDYXLDLPPSSCHIXJLLJSJSBMJSPHLZUXLDXJWICSSCXPHSSFYCZIXSJDYJXQBTLSMFXDPMGUYTJDFHHFJQYTPNIJPDUIGBJDFIRJWSSJAIGBJDBTJKSFUCEJSFZRISYTPASCYJKDJPSSJHHZJQJDFQGAXSSJDIKJWTPLLZLDEJHWPMQLLQUVYTLSHDGSLXPXGMLDZEMICVGEWUPJUCXPHSSJWJBFHFAIGBUVJDFDPFWFUCEJGDYTPSLLUJLDZASCUJHTPHLSBFYKSCXPYTPASCYJKCXPCIWHSJBFHHYCUZLZJSYZPFXOJIIHLLGEYTJXLDZTLQYTPCXBLZUMPFZVYIYTWIBIRJWTJXJDEFHJSJCFJDYJZFFFJDHTPSIMXJZIRJWSSJUJLWPHYICCXQHIMJDFWSYTLSHTPKGEUQWJLQCIWCYHLZUCXHGXPZLDFELPPCZIXSKDGAHTPHLCZSGTPMHJUUJSBFHZJBPSSCHVKKGAWJALLGHJRIYVSSJZHJSSZDLPJZUCWLHFBSPLLAPTYDJJULMCFQXFPMQPZCZHPWGPGMGLPTYJWJBVHXJXUZLJAFWPYEGHSSLMPXGXPTYQXFHTPRIYVZPQGWPMYTJHCIWHGXPSJXPLISLSUFHSLLWCFTYSSIIPSSHSWEEBSJWASVJSHFUIGBJDFPUFHHAIGBGUEIIMHJLDZCCCSIUQJSIRYILPUFHHYTPAGMZHBCUZLZUPGSSJWCFTYALVLPLCXSSCHALHYTPRGJMSSFYFUCEJWJLQNFALPMBIEBQSBFHLWCUZJPLDZSSJHZJSSVYIRJHQJQFVWJLDZPJXAZPCXSSJBFAJLZUXJXHVBJWJYTPLGMGPGWPHLDZSSJMIMJWFYTHIISFMLLPLPALMPSSJNFALPMBIEBMVHIXSSJNFBHYTLSACYJYTPKUFBHYTLSEFYKSLPALMPSSJNEAGILACWQLDZHSEXSSJCMIXJIIHAFXQPMHDLSETSJYIGBSCHWGMDFUHBIWQJDSFXQUIXPYCMJYTPXLDOIMJCIPTPHGEFTYHGMPHYJZTPLQSSJYEMSIXYMPJLDZHYIGQLASCUJJDYTGEFTYFXQLHJDIUCCHTYTGEFTYTPHYIGQYTPGLLAJWAGKKAJSSJQJHICUUFMJEFMJBTJUCZJDFSSMGEFTYTPSIZFJQAGIZFXQAEWLUJZFHCYKLXPIXJYAGIXJYAGFXQYTWIIPSFXQYTWIIPSSSJRIWRLZAZLQPAPDYHXCEBPMHDLKKTPZPUYCYQPFZFXQBCYTJSHTPFZTPAPDYPLZIXDTJDFLLKKFXQSFHSYTGEHZLCXSSJNFALPMBIEBEIMJYIMVLMMHMVAJLXJHSLGVGUWFAGGEHQLVEFUZGISKLZUFQTPKSIWSUJZCXTJHNIQSBFHLWCUZJPLDZSSJHZJSSVYIRJHQJQFVWJLDZPJXAZPCXSSJBFAJLZUXJXHVBJWJYTPLGMGPGWPHLDZSSJMIMJWFYTHIISFMLLPCYHPJMHRJWVDMPSYVHTPHLCZASJXHSJSFZUJDJHSJZCYLISJSHMLSSJWTLMZSGEXQPMHSLDZVGEHJPHSJZCZDYZJBPSGKGDCJHHPWPDYISJWHPZCSSFYHSJEIIZZDYXLBPCYIISLSLZUHGXPTGAJSHJPXHSGUJZUXQTPFZAJSSCZJLHGDUVJQGDYJOFESUVKDGABTLSYTPVLMPTGAPWPMHIMJAIZVKCUZPQHIMJYTJDFSSFYHEZPFWFYFXVWFYJAEYISSSIIPSSLZJKPHIQZJXZQGIXDCXPIRJUJQGDYXLBPTLHYJJHSFUZSFRJYIFIAFEBYTWIIPSSSJUIGBJDFPUFHHAJCIWJJWPHPJXASFYSSJWJHSGUYTPTGEHJJHUCKJUJYHSFRJLZGIKFYSSJFFWQPDCCWHYHSJBFHIISGUYTPMGIMCXFMIMJXSLDZMLDZIBDHSLCWHGMLSUJLHYCYALHXSPOLKYZQMIDXCXPAEYFXJBCXWPDYCGDGUSJWHCIWPPSYCXPZIBDHSLCWHTEJKKZQFXQPFHCUVLHLZJKPHLCZSGTPMHJUUHTPGIHYBPRYSSJYCDHGUSJWUJDFJWHGDYTPTLDZMLCUFXQCZGFYJZPPDYZQQGAXAJSSIISPWPDYIIKSCXPYTPHYFJMHAJSSTPMCJPSYTPDHTPUUILSPQGDYTWIIPSSSJSFUZLDZAGEUQSFRJFIXJHSWFJPSSGEYFYSSJZIGMJDYTPHLXPALVJUHTPTLQXSEFIPSSSIUQGUYTPQGIWRGHYHSJBFHPPSYCXPLZJSYZPPJQZVBCYTHIMEETCZGFYCXPJDYTPFJMLDZALHWFYTPMFZLQYICCXQSJWHPZCALZKCXPLPLCXCXSSJXFYEWFUALVEFDCYFUUGOYMGSUCMFLZDTLPGZCIDJXLWFEJEFDCYFUKSFWZJJLZDTLJETGHJJWMLFURSFWIMJGKLRJSLZLZDTLCXQJFXIRJMLPMYFXPGKLRJSLZFIUUGHEFWSLDFIEFDCYFUDGWPXAJWIHKLMYFXPGTGSPZJDZCLDGWPXAJWPGZCKLRJSLZGHEFWDGWPXAJWKLRJSLZMCKJPKSIHCOJJPSSGDPKUIHJAMLKP

 

Craptolocker 3

The 3rd step is to create a decryption program by reversing the encryption routines in the source code. I have attached one of the encrypted files for you to test your decryption.
The flag is contained in the decrypted file.

Here is the entire encryption program from PasteBin.

import string
import random
# written by dr0ppyb3@r_h@ck3r
# v0.3 - The release version will be much better
# Updated flag: flag{h1d3_0n_p@steb1n}

def xor_c(a):
return bytearray([b^0xA8 for b in bytearray(a)])

alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ., 1234567890-!{}"
tmp_alphabet = list(alphabet)
random.shuffle(tmp_alphabet, lambda: 0.97444187175646646) # Shuffle the list into random order (but the same order every time)
shuffled_alphabet = ''.join(tmp_alphabet)

shuffleit = string.maketrans(alphabet,shuffled_alphabet)

handler = open("original_file",'rb')
handler2 = open("encrypted_file",'wb')
contents = handler.read()
handler2.write(xor_c(string.translate(contents,shuffleit)))

The main focus points are the XOR and the alphabet shuffle. Essentially to encrypt a file, use a substitution cipher and then an XOR. What makes this task simple is that the random number used for the shuffle is not random, its hard coded as 0.97444187175646646, therefore the shuffle is the same every time you encrypt a file.

To decrypt this we need to write a program which reverses the XOR first, then reverses the shuffling.

We can reuse much of the original code, and just reverse the order of execution.

import string
import random
import sys

def xor_c(a):
return bytearray([b^0xA8 for b in bytearray(a)])

alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ., 1234567890-!{}"
tmp_alphabet = list(alphabet)
random.shuffle(tmp_alphabet, lambda: 0.97444187175646646) # Shuffle the list into random order (but the same order every time)

reverse_map = {key: value for (key, value) in zip(tmp_alphabet, alphabet)}

with open(sys.argv[1]) as file:
encrypted = file.read()

reversed_xor = xor_c(encrypted)
print(reversed_xor)
plaintext = ''.join(map(lambda x: reverse_map[chr(x)] if chr(x) in reverse_map else chr(x), reversed_xor))
print(plaintext)

Using this program on the encrypted file gives us our flag.

$ python crapto.py encrypted_file
Congrats-,Xou,found,itZ,flag!d2cr@pt92d_n9_b-tc9-n_3_y2ws{

Congrats! You found it. flag{d3cr@pt03d_n0_b!tc0!n_4_y3ws}

Craptolocker 2

The 2nd step is to find the source code of Craptolocker.
The source code contains the flag. (Look on the Internet)

We can search for Cr@pT0l0cK3r but this didn’t give any meaningful results. Instead, lets search for the hackers handle dr0ppyb3@r_h@ck3r.

Lo and behold, the code is on pastebin.

http://103.1.172.112/archieves/index.php?q=aHR0cDovL3Bhc3RlYmluLmNvbS9aZHU0aWJnZQ%3D%3D

# written by dr0ppyb3@r_h@ck3r
# v0.3 - The release version will be much better
# Updated flag: flag{h1d3_0n_p@steb1n}

Craptolocker 1

The following web page was left by a hacker, who is using ransomware to hold my web site hostage. I am a poor student and can't affort to pay the ransom. Can you help?

http://ctf.crikeycon.com:1234
The 1st step of this challenge is to identify the hacker.
Submit the flag as: flag{hacker_handle}

Oh no! Its been craptolocked!

Screenshot from 2017-03-07 16-02-06.png

The hackers name doesn’t appear on the front end of this website, however I’m going to use an old trick that I learnt from my hacker friend who goes by the name “Alex”.

CpPFpd3VMAA7Hx0

And we find the hackers name written in an HTML comment.

<!-- Page made by dr0ppyb3@r_h@ck3r ->

Pragyan – Steganography

ctf.pragyan.org

Lost Friends – 300

Moana and her friends were out on a sea voyage, spending their summer joyously.
Unfortnately, they came across Charybdis, the sea monster. Charybdis, furious over having unknown visitors, wreaked havoc on their ship. The ship was lost.
 
Luckily, Moana survived, and she was swept to a nearby island. But, since then, she has not seen her friends. Moana has come to you for help. She believes that her friends are still alive, and that you are the only one who can help her find them.
lost_friends
Nothing here O_O

The image looks empty. But, play around on GIMP (using our decompose trick we learnt earlier) we see that the RGB channels are pictures of Alvin and the Chipmunks!

The story in the challenge describes a shipwreck, so I’m assuming Alvin and the Chipmunks were in a shipwreck. Coincidentally there is a move about that, called Alvin and the Chipmunks: Chipwrecked.

lost_friends-RGBA.png

We still need some more information to go on, after looking at hex dump of the image we can see the following hidden message.

 Psssst, Director, maybe ??

So the flag is the Director’s name of the move Alvin and the Chipmunks: Chipwrecked?

Yep. -_-

Pragyan – Forensics

ctf.pragyan.org

Look Harder – 50

There are rumours that in the Great Sahara Desert, a great treasure has been buried deep inside the ground, but the map for the exact location of the treasure over the years, has not been preserved properly.
You have got hold of the map, but it looks nothing more than a plain white sheet of paper. Can you make sense out of it ??

The image appears to be all white, except when titling the screen there is a faint contrast between two similar colours giving the outline of what seems to be a QR code.

Can you see it?

Opening the image up in GIMP we see the image is in indexed mode so lets change the main colour from faint yellow to black. Windows -> Dockable Dialogs -> Colourmap.This makes our QR code visible enough to scan and get the flag.

treasure_map_bold
Gimp is the best.

Interstellar – 150

Dr. Cooper, on another one of his endless journeys encounter a mysterious planet. However when he tried to land on it, the ship gave way and he was left stranded on the planet. Desperate for help, he relays a message to the mothership containing the details of the people with him. Their HyperPhotonic transmission is 10 times the speed of light, so there is no delay in the message. However, a few photons and magnetic particles interefered with the transmission, causing it to become as shown in the picture. Can you help the scientists on the mothership get back the original image.

The image appears to be corrupted in some what – modified heavily from the original. It almost looks like there is destructive interference or value inversion, because I can see a tree and what looks like the moon, but a tree is definitely not purple and white.

transmission
When the moon hits your eye…

After playing around with many different tools, I came across Colors -> Components -> Decompose. This separates an image into its channel components, in this case we want RGBA. On the red channel we can clearly see our flag hiding in plain sight.

transmission2-rgba
Seriously, just mess around on Gimp.

The Karaboudjan – 150

Captain Haddock is on one of his ship sailing journeys when he gets stranded off the coast of North Korea. He finds shelter off a used nuke and decides to use the seashells to engrave a message on a piece of paper. Decrypt the message and save Captain Haddock.
 
->-.>-.---.-->-.>.>+.-->--..++++.
.+++.
.->-.->-.++++++++++.+>+++.++.-[->+++<]>+.+++++.++++++++++..++++[->+++<]>.--.->--.>.

The following symbols are Brainfuck code, which when executed output the following data, shown here as a hex string.

ffff fcff 0001 fefe 0202 0505 ffff 0903
050d 121c 1c60 5efe 00

I did not work out how to massage this data into a key for the zip file. Instead, I used a tool called fcrackzip to enumerate through a dictionary of words to try and crack the zip file. Luckily, the password for the zip was an English word.

fcrackzip clue.zip -D -p english.txt -u

The pcap file inside the zip just has a simple packet which has the flag hidden in the frame.

Virtual Box 5 (Virtual Series) – 75

Description

I accidentally closed out this odd message I found. Can you get it back?

Solution

 

After searching around we open internet explorer and see the history open, a page was opened 10 days ago.

http://i.imgur.com/FQJ4JtO.png

Looks like some windings font, let’s convert it into english using this table

http://speakingppt.com/wp-content/uploads/2011/10/webdings-wingdings-character-map-speakingppt.png

ABCTF{ITS_C00L_L00KING_BACK}

Old RSA (Cryptography) – 70

Description

I’m sure you can retrieve the flag from this file.

Solution

We can lookup the factorization of N as it isn’t a very big number (comparatively)

http://www.factordb.com/index.php?query=70736025239265239976315088690174594021646654881626421461009089480870633400973

N =
70736025239265239976315088690174594021646654881626421461009089480870633400973

p =  238324208831434331628131715304428889871
q = 296805874594538235115008173244022912163

We can calulate Z from the formula

z = (p -1) * (q -1)

z = 70736025239265239976315088690174594021111524798200448894265949592322181598940
e = 3

We can calculate d from the formula

ed -1 = 0 (mod z)

d = 47157350159510159984210059126783062680741016532133632596177299728214787732627

And our message is C

c = 29846947519214575162497413725060412546119233216851184246267357770082463030225

The easiest way is to use the pycrypto library for python which will calculate all this very fast for us.

#!/usr/bin/python3

from Crypto.PublicKey import RSA

p = 238324208831434331628131715304428889871
q = 296805874594538235115008173244022912163

n = p * q
z = (p-1)*(q-1)

e = long(3)
d = 47157350159510159984210059126783062680741016532133632596177299728214787732627
c = 29846947519214575162497413725060412546119233216851184246267357770082463030225

key = RSA.construct((n, e, d, p, q))
decrypted = key.decrypt(c)
decrypted = hex(decrypted)
decrypted = decrypted.lstrip('0x')
decrypted = decrypted[:-1]
ascii_bytes = bytearray.fromhex(str(decrypted))
print(ascii_bytes)

ABCTF{th1s_was_h4rd_in_1980}

WordPress.com.

Up ↑