नियोक्वेस्ट -२०२० के उदाहरण पर रिवर्स क्लाइंट-सर्वर एपीके पर गाइड


आज हमारे पास एक समृद्ध कार्यक्रम है (एक समय में इतने सारे साइबर स्पेस क्षेत्र होंगे!): एक एंड्रॉइड एप्लिकेशन को डिकम्पोज करने पर विचार करें, URL प्राप्त करने के लिए ट्रैफ़िक को बाधित करना, स्रोत कोड के बिना APK पुनर्निर्माण करना, क्रिप्टोकरंसी के साथ काम करना और बहुत कुछ :)

किंवदंती नियोक्स्ट -२०२० के अनुसार , नायक को पुराने रोबोट पार्ट्स मिले जिनका उपयोग कुंजी प्राप्त करने के लिए किया जाना चाहिए। चलो शुरू हो जाओ!

1. उलटा APK


इसलिए, इससे पहले कि हम थोड़ा सा है कि हम एक अर्ध-विघटित रोबोट से निकालने में कामयाब रहे - एक एपीके एप्लीकेशन जो किसी तरह हमें कुंजी प्राप्त करने में मदद करनी चाहिए। आइए सबसे स्पष्ट करें: एपीके चलाएं और इसकी कार्यक्षमता देखें। न्यूनतर अनुप्रयोग इंटरफ़ेस से अधिक कोई संदेह नहीं छोड़ता है - यह एक कस्टम फ़ाइलडायर फ़ाइल क्लाइंट है जो आपको दूरस्थ सर्वर से फ़ाइल डाउनलोड करने की अनुमति देता है। ठीक है, यह आसान लग रहा है। हम फोन को इंटरनेट से कनेक्ट करते हैं, डाउनलोड करने के लिए एक परीक्षण का प्रयास करें (तुरंत key.txt - ठीक है, अगर क्या?) - असफल, फ़ाइल सर्वर पर गायब है।



हम जटिलता के संदर्भ में अगले कार्यक्रम के लिए आगे बढ़ते हैं - हम JADX का उपयोग करते हुए अपघर्षक apkऔर आवेदन के स्रोत कोड का विश्लेषण करें, जो, सौभाग्य से, बिल्कुल भी बाधित नहीं है। हमारा वर्तमान कार्य यह समझना है कि दूरस्थ सर्वर डाउनलोड करने के लिए कौन सी फाइलें प्रदान करता है, और उनमें से कुंजी के साथ एक का चयन करें।

हम com.ctf.filedroid.ainActivity क्लास से शुरू करते हैं, जिसमें हमारे लिए सबसे दिलचस्प ऑनक्लिक () विधि है, जिसमें "डाउनलोड" बटन पर क्लिक करने की प्रक्रिया होती है। इस विधि के अंदर, ConnectionHandler वर्ग को दो बार कहा जाता है: पहला, ConnectionHandler.getToken () विधि कहा जाता है, और उसके बाद ही, ConnectionHandler.getEncryptedFile (), जो उपयोगकर्ता द्वारा अनुरोधित फ़ाइल के नाम से गुजरता है, कहा जाता है।



हाँ, यह है, पहले हमें एक टोकन की आवश्यकता है! हम इसे प्राप्त करने की प्रक्रिया के साथ थोड़ा और जांच करेंगे।
ConnectionHandler.getToken () विधि इनपुट की दो लाइनें लेती है, और फिर इन लाइनों को "crc" और "साइन" पैरामीटर के रूप में पास करते हुए, GET अनुरोध भेजता है। प्रतिक्रिया में, सर्वर JSON प्रारूप में डेटा भेजता है, जिसमें से हमारा एप्लिकेशन टोकन एक्सेस करता है और इसका उपयोग फ़ाइल डाउनलोड करने के लिए करता है। यह सब, ज़ाहिर है, अच्छा है, लेकिन "crc" और "साइन" क्या हैं?



इसे समझने के लिए, हम चेक क्लास की ओर आगे बढ़ते हैं, कृपया खराब हैश () और बैडसाइन () तरीके प्रदान करते हैं। पहले वर्ग से चेकसम की गणना करता है। xx और resource.arsc, इन दो मूल्यों को समेटता है और इसे बेस 64 में लपेटता है (ध्वज 10 पर ध्यान दें = NO_WRAP | URL_SAFE, यह काम में आएगा)। और दूसरी विधि के बारे में क्या? और वह आवेदन हस्ताक्षर के SHA-256 फिंगरप्रिंट के साथ भी ऐसा ही करता है। एह, ऐसा लगता है कि FileDroid वास्तव में फिर से बनने के लिए उत्सुक नहीं है :(



ठीक है, हम कहते हैं कि हमें टोकन मिला है। आगे क्या होगा? हम इसे ConnectionHandler.getEncryptedFile () पद्धति के इनपुट पर पास करते हैं, जो टोकन के लिए अनुरोधित फ़ाइल का नाम जोड़ता है और एक और GET अनुरोध उत्पन्न करता है, इस बार "टोकन" और "फ़ाइल" पैरामीटर के साथ। प्रतिक्रिया में सर्वर (विधि के नाम को देखते हुए) एक एन्क्रिप्टेड फ़ाइल भेजता है, जिसे / sdcard / पर संग्रहीत किया जाता है।

इसलिए, थोड़ा उप-संक्षेप प्रस्तुत करने के लिए: हमारे पास दो खबरें हैं, और ... दोनों खराब हैं। सबसे पहले, FileDroid वास्तव में एपीके (चेकसम और सिग्नेचर चेक किए गए) को संशोधित करने के लिए हमारे उत्साह का समर्थन नहीं करता है, और दूसरी बात, सर्वर से प्राप्त फ़ाइल एन्क्रिप्टेड होने का वादा करती है।

ठीक है, हम उपलब्ध होते ही समस्याओं को हल कर देंगे, और अब हमारी मुख्य समस्या यह है कि हमें अभी भी यह नहीं पता है कि हमें कौन सी फाइल डाउनलोड करनी है। हालाँकि, ConnectionHandler वर्ग का अध्ययन करते समय, हम मदद नहीं कर सकते, लेकिन ध्यान दें कि getToken () और getEncryptedFile () विधियों के बीच में, FileDroid डेवलपर्स ने एक और बहुत ही आकर्षक तरीके को भुला दिया जिसे getListing () नाम कहा जाता है। तो, सर्वर ऐसी कार्यक्षमता का समर्थन करता है ... ऐसा लगता है कि यह वही है जो आपको चाहिए!



लिस्टिंग प्राप्त करने के लिए, हमें प्रसिद्ध "crc" और "साइन" की आवश्यकता होगी - कोई समस्या नहीं है, हम पहले से ही जानते हैं कि वे कहाँ से आते हैं। हम मान पढ़ते हैं, एक GET अनुरोध भेजते हैं और ... तो, रुकें। हम GET अनुरोध भेजने के लिए कहां जा रहे हैं? पहले रिमोट सर्वर URL प्राप्त करना अच्छा होगा। एह, हम MainActivity.onClick () पर लौटते हैं और देखते हैं कि नेटपैथ तर्क गेटटेकन () और getEncryptedFile () विधियों को कॉल करने के लिए कैसे उत्पन्न होते हैं:

Method getSecureMethod = 
wat.class.getDeclaredMethod("getSecure", new Class[]{String.class});

// . . .

// netPath --> ConnectionHandler.getToken()
(String) getSecureMethod.invoke((Object) null, new Object[]{"fnks"})

// netPath --> ConnectionHandler. getEncryptedFile()
(String) getSecureMethod.invoke((Object) null, new Object[]{"qdkm"})

अजीब पत्र संयोजन "fnks" और "qdmk" हमें wat.getSecure () विधि के विघटन के परिणाम की ओर मुड़ने के लिए मजबूर करते हैं। स्पोइलर: JADX का यह परिणाम ऐसा है।



करीब से निरीक्षण करने पर, यह स्पष्ट हो जाता है कि इस विधि के सभी बहुत ही सुखद सामग्री को इस तरह के सामान्य स्विच-केस से नहीं बदला जा सकता है:

// . . .
switch(CODE)
{
    case «qdkm»: 
        r.2 = com.ctf.filedroid.x37AtsW8g.rlieh786d(2);
        break;
    case «tkog»: 
        r2 = com.ctf.filedroid.x37AtsW8g.rlieh786d(1);
        break;
    case «fnks»: 
        String r2 = com.ctf.filedroid.x37AtsW8g.rlieh786d(0);
	break;
}
java.lang.StringBuilder r1 = new java.lang.StringBuilder 
r1.<init>(r2) 
java.lang.String r0 = r1.toString() 
java.lang.String r1 = radon(r0)
return r1 

चूंकि "fnks" और "qdmk" का उपयोग पहले से ही एक टोकन प्राप्त करने और एक फ़ाइल डाउनलोड करने के लिए किया जाता है, "tkog" को सर्वर पर उपलब्ध फ़ाइलों की सूची का अनुरोध करने के लिए आवश्यक URL देना चाहिए। ऐसा लगता है कि सस्ते में आवश्यक पथ प्राप्त करने की उम्मीद है ... सबसे पहले, आइए देखें कि एप्लिकेशन में URL कैसे संग्रहीत किए जाते हैं। हम com.ctf.filedroid.x37AtsW8g.rlieh786d () फ़ंक्शन को खोलते हैं और देखते हैं कि प्रत्येक URL को एन्कोडेड बाइट सरणी के रूप में सहेजा गया है, और फ़ंक्शन स्वयं इन बाइट्स से एक स्ट्रिंग बनाता है और इसे वापस करता है।



अच्छा। लेकिन फिर लाइन को com.ctf.filedroid.wat.radon () फ़ंक्शन से पारित किया जाता है, जिसके कार्यान्वयन को देशी पुस्तकालय libae3d8oe1.so को प्रस्तुत किया जाता है। बाजूबंद ६४? अच्छी कोशिश, FileDroid, लेकिन एक और समय पर आते हैं?

2. सर्वर यूआरएल प्राप्त करें


आइए दूसरी ओर से संपर्क करने का प्रयास करें: ट्रैफ़िक को बाधित करने के लिए, स्पष्ट पाठ में URL प्राप्त करें (और बोनस के रूप में, चेक और हस्ताक्षर मान भी!), उन्हें com.ctf.filedroid.x37Atsc8g.rlieh786d () से बाइट सरणियों से मिलाएं - यह कर सकते हैं क्या एन्क्रिप्शन सामान्य सीज़र या XOR सिफर है? .. तो तीसरे URL को पुनर्स्थापित करना और लिस्टिंग करना मुश्किल नहीं होगा।

रीडायरेक्ट यातायात के लिए, आप (किसी भी सुविधाजनक प्रॉक्सी का उपयोग कर सकते हैं चार्ल्स , Fiddler , BURPआदि।)। हम एक मोबाइल डिवाइस पर अग्रेषण कॉन्फ़िगर करते हैं, उचित प्रमाण पत्र स्थापित करते हैं, सत्यापित करते हैं कि अवरोधन सफल है, और फ़ाइलफ़ायर लॉन्च करें। हम एक मनमानी फ़ाइल डाउनलोड करने की कोशिश कर रहे हैं और ... "NetworkError" देखें। यह त्रुटि प्रमाणपत्र-पिनिंग की उपस्थिति के कारण हुई थी (देखें com.ctf.filedroid.ConnectionHandler.sendRequest विधि): फ़ाइल क्लाइंट सत्यापित करता है कि अनुप्रयोग में "वायर्ड" प्रमाणपत्र उस सर्वर से मेल खाता है जिसके साथ वह इंटरैक्ट करता है। अब यह स्पष्ट है कि अनुप्रयोग संसाधनों की अखंडता क्यों नियंत्रित है!



हालाँकि, इंटरसेप्ट किए गए ट्रैफ़िक में, हम फ़ाइल क्लाइंट द्वारा एक्सेस किए गए सर्वर का कम से कम डोमेन नाम देख सकते हैं, जिसका अर्थ है कि URL को डिक्रिप्ट करने की उम्मीद बनी हुई है!



आइए com.ctf.filedroid.x37AtsW8g.rlieh786d () फ़ंक्शन पर लौटते हैं और ध्यान दें कि पहले कुछ दसियों बाइट्स सभी सरणियों में मेल खाते हैं:

cArr[0] = new char[]{'K', 'S', 'Y', '5', 'E', 'R', 'Q', 'J', 'S', '0', 't', 'W', 'B', '2', 'w', 'k', 'N', 'j', '8', 'O', 'D', 'l', 'd', 'K', 'C', 'l', 'U', 'B', 'c', 'T', 'Q', '3', 'P', 'h', 'V', 'J', 'Q', 'R', 'F', 'L', 'U', 'R', '5', 'p', 'b', 'i', . . .};

cArr[1] = new char[]{'K', 'S', 'Y', '5', 'E', 'R', 'Q', 'J', 'S', '0', 't', 'W', 'B', '2', 'w', 'k', 'N', 'j', '8', 'O', 'D', 'l', 'd', 'K', 'C', 'l', 'U', 'B', 'c', 'T', 'Q', '3', 'P', 'h', 'V', 'J', 'Q', 'R', 'F', 'L', 'U', 'R', '5', 'p', 'b', 'j', . . .};

cArr[2] = new char[]{'K', 'S', 'Y', '5', 'E', 'R', 'Q', 'J', 'S', '0', 't', 'W', 'B', '2', 'w', 'k', 'N', 'j', '8', 'O', 'D', 'l', 'd', 'K', 'C', 'l', 'U', 'B', 'c', 'T', 'Q', '3', 'P', 'h', 'V', 'J', 'Q', 'R', 'F', 'L', 'U', 'R', '5', 'p', 'b', 'j', . . ., '='};

इसके अलावा, तीसरी सरणी का अंतिम बाइट संकेत देता है कि यह आधार 6 के बिना नहीं था। आइए URL के ज्ञात भाग के परिणामस्वरूप परिणामी बाइट्स को डीकोड और पोक करने का प्रयास करें:



ऐसा लगता है कि ARMag3dd0n के साथ कोई भी कभी इतना खुश नहीं हुआ है! बात छोटी है: क्रमिक रूप से डिकोड किए गए कुंजी के साथ बेस 64 यूआरएल और ज़ोरिम को डीकोड करें। लेकिन ... और अगर यह XOR नहीं था, लेकिन एक स्व-निर्मित क्रमपरिवर्तन सिफर, जिसे आप सौ प्रयासों के साथ भी नहीं उठा सकते हैं?

3. फ्रिडा के साथ APK का पुनर्निर्माण करें


इस राइट-अप के भाग के रूप में, हम फ्रिडा फ्रेमवर्क का उपयोग करते हुए अधिक दर्द रहित (और, हमारी राय में, अधिक सुंदर) समाधान पद्धति पर विचार करेंगे, जो हमें रन-टाइम में आवश्यक तर्कों के साथ मनमाने ढंग से एपीके एप्लीकेशन विधियों को निष्पादित करने की अनुमति देगा। ऐसा करने के लिए, आपको रूट अधिकारों या एक एमुलेटर वाला फोन चाहिए। हम निम्नलिखित कार्य योजना मानते हैं:

  1. एक पीसी और एक परीक्षण फोन पर फ्रिडा घटकों को स्थापित करना।
  2. टोकन या सूची अनुरोधों से मेल खाते URL पुनर्प्राप्त करें और फ़ाइल (फ़्रिडा का उपयोग करके) डाउनलोड करें।
  3. मूल एप्लिकेशन के चेकसम और हस्ताक्षर मानों को पुनः प्राप्त करना।
  4. सर्वर पर संग्रहीत फ़ाइलों की एक सूची प्राप्त करना, और वांछित फ़ाइल की पहचान करना।
  5. फ़ाइल को डाउनलोड और डिक्रिप्ट करें।

सबसे पहले, हम रूट किए गए फोन और एपीके के बीच संबंध स्पष्ट करेंगे। हम एप्लिकेशन इंस्टॉल करते हैं, इसे चलाते हैं, लेकिन फ़ाइल क्लाइंट पूरी तरह से बूट नहीं करना चाहता है, यह केवल ब्लिंक करता है और बंद हो जाता है। हम लॉगकैट के माध्यम से संदेशों की जांच करते हैं - हां, यह है, फाइलड्रॉइड पहले से ही महसूस करता है कि कुछ एमिस है और जैसा वह कर सकता है वैसा ही प्रतिरोध करता है।



हम फिर से MainActivity class की ओर मुड़ते हैं और पाते हैं कि doChecks () विधि को onCreate () में कहा जाता है, और यह लॉग में निम्नलिखित त्रुटियां प्रदर्शित करता है:



इसके अलावा, onResume () यह देखने के लिए भी जांचता है कि क्या Frida का पोर्ट खुला है:



हमारी फाइल क्लाइंट थोड़ी असहिष्णु है डिबगिंग, रूट और फ्रिडा के लिए ही। इस तरह का विरोध हमारी योजनाओं में बिल्कुल शामिल नहीं है, इसलिए हमें एपीकेटी यूटिलिटी का उपयोग करके एप्लिकेशन का स्माली-कोड प्राप्त होता है, किसी भी टेक्स्ट एडिटर में MainActivity.smali फ़ाइल खोलें, ऑनक्रीट () विधि ढूंढें और doChecks () कॉल को हानिरहित टिप्पणी में बदल दें:



तब हम आत्महत्या से वंचित कर देते हैं () आवेदन को वास्तव में नीचे करने का अवसर का तरीका:



अगला, आइए, APKtool और साइन का उपयोग करके फिर से हमारे थोड़े बेहतर अनुप्रयोग का निर्माण करें। निम्नलिखित आदेशों को निष्पादित करके उसे (आपको प्रशासक अधिकारों की आवश्यकता हो सकती है):

cd "C:\Program Files\Java\jdk-14\bin"
.\keytool -genkey -v -keystore filedroid.keystore -alias filedroid_alias -keyalg RSA -keysize 2048 -validity 10000
.\jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore  filedroid.keystore filedroid_patched.apk filedroid_alias
.\jarsigner -verify -verbose -certs filedroid_patched.apk

हम फोन पर एप्लिकेशन को फिर से इंस्टॉल करते हैं, इसे चलाते हैं - हुर्रे, डाउनलोड बिना घटना के हो जाता है, लॉग साफ है!



हम एक पीसी और मोबाइल डिवाइस पर फ्रिडा फ्रेमवर्क स्थापित करने के लिए आगे बढ़ते हैं:

$ sudo pip3 install frida-tools
$ wget https://github.com/frida/frida/releases/download/$(frida --version)/frida-server-$(frida --version)-android-arm.xz
$ unxz frida-server-$(frida --version)-android-arm.xz
$ adb push frida-server-$(frida --version)-android-arm /data/local/tmp/frida-server

मोबाइल डिवाइस पर फ्रिडा फ्रेमवर्क सर्वर लॉन्च करें:

$ adb shell su - "chmod 755 /data/local/tmp/frida-server"
$ adb shell su - "/data/local/tmp/frida-server &"  

हम एक सरल get-urls.js स्क्रिप्ट तैयार कर रहे हैं, जो सभी समर्थित अनुरोध सर्वरों के लिए wat.getSecure () कॉल करेगी:

Java.perform(function () 
{
     const wat = Java.use('com.ctf.filedroid.wat');
	console.log(wat.getSecure("fnks"));
	console.log(wat.getSecure("qdmk"));
	console.log(wat.getSecure("tkog"));
});

हम फाइलड्रॉइड को मोबाइल डिवाइस पर लॉन्च करते हैं और इसी प्रक्रिया के लिए हमारी स्क्रिप्ट के साथ "क्लिंग" करते हैं:



4. सर्वर पर फाइलों की लिस्टिंग प्राप्त करें


अंत में, रिमोट सर्वर हमारे थोड़ा करीब हो गया है! अब हम जानते हैं कि सर्वर निम्नलिखित तरीकों से अनुरोधों का समर्थन करता है:

  1. दर्ज किया गया ।neoquest.ru/api/verifyme? crc= {crc} & sign = {साइन करें}
  2. दर्ज किया गया ।neoquest.ru/api/list_post_apocalyptic_collection? crc= {crc} & sign = {sign}
  3. दर्ज किया गया ।neoquest.ru/api/ file?file= {फ़ाइल} और टोकन = {टोकन}

उपलब्ध फ़ाइलों की सूची प्राप्त करने के लिए, यह मूल एप्लिकेशन के चेकसम और हस्ताक्षर मानों की गणना करने के लिए रहता है, और फिर उन्हें बेस 64 में एनकोड करता है।

Python3 में इस तरह की स्क्रिप्ट आपको ऐसा करने की अनुमति देगी:

स्पॉइलर
import hashlib
import binascii
import base64
from asn1crypto import cms, x509
from zipfile import ZipFile


def get_info(apk):
    with ZipFile(apk, 'r') as zipObj:
        classes = zipObj.read("classes.dex")
        resources = zipObj.read("resources.arsc")
        cert = zipObj.read("META-INF/CERT.RSA")
        crc = "%s%s" % (get_crc(classes), get_crc(resources))
        return get_full_crc(classes, resources).decode("utf-8"), get_sign(cert).decode("utf-8")


def get_crc(file):
    crc = binascii.crc32(file) & 0xffffffff
    return crc


def get_full_crc(classes, resources):
    crc = "%s%s" % (get_crc(classes), get_crc(resources))
    return base64.urlsafe_b64encode(bytes(crc, "utf-8"))


def get_sign(file):
    pkcs7 = cms.ContentInfo.load(file)
    data = pkcs7['content']['certificates'][0].chosen.dump()
    sha256 = hashlib.sha256()
    sha256.update(data)
    return base64.urlsafe_b64encode(sha256.digest())  

get_info('filedroid.apk')


आप मैन्युअल रूप से भी कर सकते हैं। हम classes.dex और resources.arsc से CRC32 पर विचार किसी भी सुविधाजनक उपकरण होने के लिए (उदाहरण के लिए, लिनक्स के लिए - मानक CRC32 उपयोगिता), हम क्रमशः मूल्यों +१२७६९४५८१३ और +२८१४१६६५८३ मिलता है, उन्हें श्रेणीबद्ध उदाहरण के लिए बेस 64 में (12769458132814166583 बाहर आ जाएगा) और एनकोड,, यहाँ :



JADX विंडो में, एप्लिकेशन पर हस्ताक्षर करने के लिए एक समान प्रक्रिया करने के लिए, "एपीके सिग्नेचर" अनुभाग पर जाएं, "SHA-256 फिंगरप्रिंट" मान को कॉपी करें और इसे एक बाइट सरणी के रूप में base64 में एनकोड करें:



महत्वपूर्ण:मूल एपीके में, base64 एन्कोडिंग URL_SAFE ध्वज के साथ किया जाता है, अर्थात वर्णों के बजाय "+" और "/", "-" और "_" क्रमशः उपयोग किए जाते हैं। यह सुनिश्चित करना आवश्यक है कि यह स्व-कोडिंग के साथ भी देखा जाएगा। ऐसा करने के लिए, जब ऑनलाइन कोडिंग की जाती है, तो आप "ABCDEFGHIJKLMNOPQRSTUVWXYZabcde fghijklmnopqrstuvwxyz012346789 +" के साथ "ABCDEFGHIJKLMNNQQNSTQWSTZZZZZZZZZZZZZZZZZZZYZ" स्क्रिप्ट के साथ प्रयोग किया जा सकता है।

अंत में, हमारे पास सफलतापूर्वक सूचीबद्ध फ़ाइलों के लिए सभी सामग्री हैं:

  1. दर्ज किया गया ।neoquest.ru/api/list_post_apocalyptic_collection? crc= {crc} & sign = {sign}
  2. crc: MTI3Njk0NTgxMzI4MTQxNjY1ODM =
  3. संकेत: HeiTSPWdCuhpbmVxqLxW-uhrozfG_QWpTv9ygn45eHY =

हम GET अनुरोध को निष्पादित करते हैं - और चियर्स, हमारी लिस्टिंग! इसके अलावा, फ़ाइलों में से एक का नाम खुद के लिए बोलता है - "खुले-अगर-आप-चाहते-से-भागने" - ऐसा लगता है कि हमें इसकी आवश्यकता है।



अगला, हम एक बार एक्सेस टोकन के लिए अनुरोध करते हैं और फ़ाइल डाउनलोड करते हैं:

import requests

response = requests.get('https://filedroid.neoquest.ru/api/verifyme', 
    		params={    'crc': 'MTI3Njk0NTgxMzI4MTQxNjY1ODM=', 
'sign': HeiTSPWdCuhpbmVxqLxW-uhrozfG_QWpTv9ygn45eHY=},
verify=False)
    
token = response.json()['token']
print(token)
response = requests.get('https://filedroid.neoquest.ru/api/file', 
params={'token': token, 'file': '0p3n1fuw4nt2esk4p3.jpg'}, verify=False)

with open("0p3n1fuw4nt2esk4p3.jpg", 'wb') as fd:
        fd.write(response.content)

हम डाउनलोड की गई फ़ाइल को खोलते हैं और एक छोटी परिस्थिति को याद करते हैं जिसे हमने बाद में छोड़ा था:



5. क्रिप्टोग्राफी की एक चुटकी जोड़ें ...


एह, बहुत जल्दी हम फ़ाइलडायर को बंद कर देते हैं। चलो JADX पर वापस जाएं और देखें कि फ़ाइल क्लाइंट डेवलपर्स ने हमारे लिए कुछ उपयोगी छोड़ा है या नहीं। हां, यह मामला है जब कोड सफाई स्पष्ट रूप से लोकप्रिय नहीं है: अप्रयुक्त डिक्रिप्टाइल () विधि चुपचाप कनेक्शनहैंडलर वर्ग में हमारे ध्यान की प्रतीक्षा कर रही है। हमारे पास क्या है?

एन्क्रिप्शन एईएस मोड CBC , sinhroposylka पहले 16 बाइट्स पर कब्जा कर लेता है ... आलस्य - प्रगति का इंजन, यह बेहतर है फ्रिडा का उपयोग करें और हमारे 0p3n1fuw4nt2esk4p3.jpg को सरलता से समझें। लेकिन अभी एन्क्रिप्शन कुंजी के रूप में पास? कई विकल्प नहीं हैं, लेकिन एक और "भूल" savePlainFile (स्ट्रिंग फ़ाइल, स्ट्रिंग टोकन) विधि की उपस्थिति को देखते हुए, विकल्प स्पष्ट है।

निम्नलिखित decrypt.js स्क्रिप्ट तैयार करें ( टोकन के रूप में वास्तविक मूल्य को इंगित करें, उदाहरण के लिए, 'HoHknc572mVpZESSQN1Xa7S9zOidxX1PMbykdoM1EXI ='):

Java.perform(function () {
    const JavaString = Java.use('java.lang.String');
    const file_name = JavaString.$new('0p3n1fuw4nt2esk4p3.jpg');
    const ConnectionHandler = Java.use('com.ctf.filedroid.ConnectionHandler');
    const result = ConnectionHandler.savePlainFile(file_name, <token>);
    console.log(result);
});

हम एन्क्रिप्टेड फ़ाइल 0p3n1fuw4nt2esk4p3.jpg / sdcard / पर डालते हैं, फाइलड्रॉइड चलाते हैं और फ्रिडा का उपयोग करके डिक्रिप्ट.जेएस स्क्रिप्ट को इंजेक्ट करते हैं। स्क्रिप्ट के चलने के बाद, plainfile.jpg फ़ाइल / sdcard / पर दिखाई देगी। हम इसे खोलते हैं और ... बस हल!



इस कठिन कार्य के लिए प्रतिभागियों को एक साथ सूचना सुरक्षा के कई क्षेत्रों में ज्ञान और कौशल की आवश्यकता होती है, और हमें खुशी है कि अधिकांश प्रतियोगियों ने सफलतापूर्वक इसका सामना किया!

हम आशा करते हैं कि जिनके पास कुंजी प्राप्त करने से पहले पर्याप्त समय या ज्ञान नहीं था वे अब किसी भी CTF में समान कार्य सफलतापूर्वक पारित करेंगे :)

All Articles