Download - Shellcoding, an Introduction
Shellcoding, an introduction
Daniele Bellavista
University of Bologna, Scuola di Ingegneria ed ArchitetturaCesena Security Network and Applications
December 24, 2012
Outline
(CeSeNA) December 24, 2012 2 / 1
Warm-Up
Materiale iniziale
I La teoria di questa presentazione vale per sistemi Unix, FreeBSD eWindows.
I Il materiale e tuttavia preparato per sistemi Linux 64 bit con kernel>= 2.6 e processore > Pentium 4.
I Per chi non ha 64 bit sono disponibili anche gli esempi a 32 bit.
I Per chi non ha installato un OS Linux o non vuole sporcare il suo,sono disponibili due Virtual Machine:
32 bit: sorry non ho fatto in tempo. . .64 bit: sorry non ho fatto in tempo. . .
(CeSeNA) December 24, 2012 3 / 1
What is shellcoding?
Exploiting software vulnerabilities
I Vulnerabilities like BOFs permit the insertion and the execution of acustom payload.
I The historical function of the payload is to spawn a shell (hence thename shell-code).
I If the exploited program runs as a privileged user, the payload canassume the control of the system.
Prerequisites
Basic notion of:
I Assembly language.
I Memory structure.
I System Calls.
(CeSeNA) December 24, 2012 4 / 1
System Memory
Memory management
I Memory management is a vast topic, so let’s discuss from anhigh-level viewpoint.
I Thanks to the Virtual Memory Management, each process sees a flataddressing space of 128 TiB (4 GiB in 32 bit processors).
I Users can create sections inside the memory with read, write and/orexecute permissions.
I The basic operations for memory management are push and pop.
push Insert a 64-bit value into the top of the stack (thebottom).
pop Retrieve a 64-bit value from the top of the stack (thebottom).
(CeSeNA) December 24, 2012 5 / 1
Figure : Linux 64 bit memory management
(CeSeNA) December 24, 2012 6 / 1
Program Code
Text segment and instruction pointer
I The code is saved in a RO and executable memory called Textsegment.
I The current instruction is pointed by the Instruction Pointer.
I The instruction pointer is a value stored into the CPU.
(CeSeNA) December 24, 2012 7 / 1
Program Stack
I The stack is where function context,called frame, resides.
I The Base pointer points to the begin ofthe frame.
I The Stack pointer points to the firstavailable memory location.
1 v o i d f ( ) {2 i n t xx = 1 2 ; i n t yy = 2 3 ;3 i n t zz = 2 4 ;4 i n t sum = xx + yy + zz ;5 }
(CeSeNA) December 24, 2012 8 / 1
Assembly Language
Low, low level programming
I Assembly is the final stage of the programming process.
I Each instruction is directly converted into an number.
I Writing the number on the CPU Command BUS cause the instructionto be executed.
I You can access to a set of 64 bit registers: rax, rbx, rcx, rdx, rsi, rdi,r8, r9, r10, r11, r12, r13, r14, r15
I As instruction pointer, base pointer and stack pointer the CPU usesrespectively rip, rbp and rsp.
(CeSeNA) December 24, 2012 9 / 1
Assembly Language: function call
The call/ret instructions
call address push the RIP into the stack.
ret pop the RIP from the stack.
Creating a frame for the function
I The callee may need a stack for his own variables.
I RBP is saved (pushed) into the stack.
I The new RBP become the old RSP.
I Before doing ret, the opposite operations must be performed.
(CeSeNA) December 24, 2012 10 / 1
Assembly Language: function call and stack
(CeSeNA) December 24, 2012 11 / 1
Assembly Language: function call and parameters
Where should I put the parameters?
I If you are coding in pure ASM, you can do what you want.
I Else, you have to follow the conventions (seehttp://en.wikipedia.org/wiki/X86_calling_conventions#
List_of_x86_calling_conventions).
Linux calling convention, parameter order
First parameters:
x86-64: rdi, rsi, rdx, rcx, r8, and r9. For system calls, r10 is usedinstead of rcx.
IA-32: ecx, edx. For system calls ebx, ecx, edx, esi, edi, ebp.
Other parameters are pushed into the stack.
(CeSeNA) December 24, 2012 12 / 1
System calls
Invoking the OS
I User’s programs run in the exterior ring with PL 3, while kernel runsin the inner ring with PL 0: Kernel can access to the hardware (files,devices, . . . ), user not.
I Syscalls form the interface between user and kernel.
I E.g.: open(), read(), write(), chmod(), exec(), . . .
(CeSeNA) December 24, 2012 13 / 1
Try to use Syscalls
Using assembly
I In order to ease the programmer duty, syscalls are identified by anumber.
I In modern x86-64 processor, a syscall is invoked using the operationsyscall, putting the id in the register rax.
I In modern x86 processor, a syscall is invoked using the operationsysenter but a lot of operation must be performed before, so in thefollowing exercise we will use the old-fashion-way int 80h, which risesa software interrupt.
1 mov r d i , 02 mov rax , 603 s y s c a l l
1 mov ebx , 02 mov eax , 13 i n t 80h
(CeSeNA) December 24, 2012 14 / 1
Linux Syscalls
Linux
I Syscalls signatures: /. . . kernel-sources. . . /include/linux/syscall.h
I Syscalls numbers: /usr/include/asm/unistd 64.h
1 u n i s t d 6 4 . h2 #d e f i n e N R e x i t 603 s y s c a l l . h4 a s m l i n k a g e l o n g s y s e x i t ( i n t e r r o r c o d e ) ;
(CeSeNA) December 24, 2012 15 / 1
Writing shellcodes
The final preparation
First steps. . .
I Testing platform: http://dl.dropbox.com/u/16169203/data.zip
I Use nasm to compile your assembly code
I Feed the tester with the output.
Exercise 0
I Create a shellcode that does nothing!
I Test it!
(CeSeNA) December 24, 2012 16 / 1
Writing shellcodes
Using a syscall
Exercise 1: The exit syscall
I Use the exit syscall to terminate the program
I Change your code setting the return code to 13h
(CeSeNA) December 24, 2012 17 / 1
Writing shellcodes
Data reference I
The reference problem
I When you write a program you can use global data because, atcompile time, a static address is associated.
I But your shellcode is not compiled with the program it’s intended torun.
I You must use relative addressing, but before IA-64 it was not possible.
(CeSeNA) December 24, 2012 18 / 1
Writing shellcodes
Data reference II
Old IA-32 way
I You use a trick: jmp just before the data location, then do a call. Etvoila! On the top of the stack there is the data address.
1 jmp message2 run :3 pop ebx ; now ebx c o n t a i n s th e s t r i n g r e f e r e n c e4 ; . . . s h e l l c o d e5 message :6 c a l l run7 db ’ CeSeNA ’ ,0 x0a , 0
(CeSeNA) December 24, 2012 19 / 1
Writing shellcodes
Data reference III
New IA-64 way
I IA-64 introduces the RIP relative addressing.
1 l e a r d i , [ r e l message ] ; now ebx c o n t a i n s2 ; the s t r i n g r e f e r e n c e3 ; . . . s h e l l c o d e4
5 message db ’ CeSeNA ’ ,0 x0a , 0
(CeSeNA) December 24, 2012 20 / 1
Writing shellcodes
Data reference IV
Generic Way
I You can pop the string in hex format over the stack.
I The stack pointer is then the string reference.
1 push 0 x000a414e ; 0x00 , 0 x0a , ’AN ’2 push 0 x65536543 ; ’ eSeC ’3 mov ebx , esp ; now ebx c o n t a i n s th e s t r i n g r e f e r e n c e4 ; . . .
(CeSeNA) December 24, 2012 21 / 1
Writing shellcodes
Data reference V
Exercise 2: print on stdout
I Get the exercise skeleton.
I Understand the code
I Write your own message
(CeSeNA) December 24, 2012 22 / 1
Writing shellcodes
Execute a program
1 u n i s t d 6 4 . h2 #d e f i n e N R e x e c v e 593 s y s c a l l . h4 i n t k e r n e l e x e c v e ( c o n s t c h a r ∗ f i l e n a m e ,5 c o n s t c h a r ∗ c o n s t a r g v [ ] ,6 c o n s t c h a r ∗ c o n s t envp [ ] ) ;
Exercise 3: A real shellcode, exec a shell!
4 HaXoRs
4 g33k
4 n00bz
(CeSeNA) December 24, 2012 23 / 1
Writing shellcodes
Reverse shell I
One shellcode to rule them all
Step to execute:
1 Open a socket to the attacker server.
2 Duplicate the socket file descriptor into 0 and 1 (and optionally 2).
3 Exec a shell.
Step1: Create a socket
I The standard procedure involves socket creation and connection.
I socket() and connect() syscalls.
I The sockaddr in structure requires port in network byte order(htons()) and ip address in numeric form (inet pton()).
I The usual sockaddr in size is 16.
(CeSeNA) December 24, 2012 24 / 1
Writing shellcodes
Reverse shell II
1 l o n g s y s s o c k e t ( i n t domain ,2 i n t type ,3 i n t p r o t o c o l ) ;4 l o n g s y s c o n n e c t ( i n t fd ,5 s t r u c t s o c k a d d r u s e r ∗ ,6 i n t a d d r l e n ) ;
1 s t r u c t s o c k a d d r i n {2 s h o r t s i n f a m i l y ; // AF INET3 u n s i g n e d s h o r t s i n p o r t ; // network o r d e r ( h t o n s ( ) )4 s t r u c t i n a d d r s i n a d d r ; // As 32 b i t5 c h a r s i n z e r o [ 8 ] ;6 } ;
(CeSeNA) December 24, 2012 25 / 1
Writing shellcodes
Reverse shell III
Step2: Duplicate the file descriptor
I The return value of socket() is the file descriptor.
I The syscall dup2() copy the file descriptor and close the destination.
I dup2(fd, 0); dup2(fd, 1), dup2(fd, 2);
1 l o n g s y s d u p 2 ( u n s i g n e d i n t o l d f d ,2 u n s i g n e d i n t newfd )
(CeSeNA) December 24, 2012 26 / 1
Writing shellcodes
Reverse shell IV
Step3: Exec a shell
Already seen ;)
Exercise 4: Reverse shelling
Remember to open a server listening into a known address! E.g.: nc -l -p1234, preparing reverse shell for 127.0.0.1:1234
4 HaXoRs
4 g33k
4 n00bz
(CeSeNA) December 24, 2012 27 / 1
Writing shellcodes
Shellcode optimization
Why optimization?
I When writing a shellcode, you must consider various factors. Themost important are:
1 How the vulnerable program receives the payload.2 How long the payload can be.
I The previous exercise solutions, for instance, are not suitable in mostcases.
I The next slides will discuss about the NULL byte presence.
I About the payload length, it’s all about the exploiter expertise.
(CeSeNA) December 24, 2012 28 / 1
Writing shellcodes
String payload
zero-bytes problem
I If the payload is red as a string, C interprets a zero byte as stringterminator, cutting the shellcode.
I Zero-bytes presence is caused by data and addresses:I mov rax, 11h is equivalent to mov rax, 0000000000000011h.I lea rax, [rel message] is equivalent to lea rax, [rip + 0000. . . xxh].I execve for instance, requires a null terminated string and some null
parameters.
I Solutions are quite straightforward:I Use xor operation to zero a register.I Use when possible smaller part of registers (e.g.: rax → eax → ax →
[ah,al])I Use add operation: immediate operators are not expanded.I Place not-null marker in strings and substitute them inside the code.I When using relative addressing, place the message above: offset will be
negative [?].
(CeSeNA) December 24, 2012 29 / 1
Writing shellcodes
Zero-byte removal example
; Set r a x = 60hx o r rax , r a xmov a l , 60
; Set r d i = 12hx o r r d i , r d iadd r d i , 12h
; N e g a t i v e r e f e r e n c emessage db ’ CeSeNA ’ , ’ x ’l e a r d i , [ r e l message ]
; Set to 0 a mem a r e an u l l db ’ xxxx ’x o r rbx , r b xmov [ r e l n u l l ] , ebx
; t e r m i n a t e s t r i n g w i t h 0message db ’ CeSeNA ’ , ’ x ’x o r rbx , r b xl e a r d i , [ r e l message ]mov [ r d i +7] , b l
(CeSeNA) December 24, 2012 30 / 1
Writing shellcodes
References
(CeSeNA) December 24, 2012 31 / 1