Download presentation
Presentation is loading. Please wait.
Published byAriel Stevens Modified over 9 years ago
1
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Software Attacks Buffer Overflow
2
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Outline of the seminaries 8 hours, 4 lessons Buffer overflow, introduction: –Stack smashing, concepts, practical example (Blaster) –Mitigations Buffer overflow: new techniques –Heap smashing, concepts, the heap in Win32 –Countermeasures: WinXP SP2 Integer overflow and DLL injection –A Win32 process memory layout –An example: IAT patching, memory walking Countermeasures: managed languages (Java,.NET) –An example:.NET Code Access Security + 2-3 hours seminars by YOU =)
3
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Software attacks A VULNERABILITY is a security flaw caused by a software defect. An EXPLOIT is a technique that take advantage of a vulnerability. A malicious hacker uses them to ATTACK a system. For each vulnerability, many EXPLOIT may exist Buffer overflow is the most frequent vulnerability (ca 50% of security problems) See for example, MS bulletins, CERT, BugTraq.
4
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Software attacks Microsoft Security Bulletin MS03-26 (buffer overflow vulnerability exploited by Blaster) Last Stage of DeliriumUnknownOriginal report Never published XfocusStack smashingApparently same as Blaster www.xfocus.org / / D. LitchfieldPointer subterfuge CigitalPointer subterfuge K-oiticArc injection Pincus, BakerArc injection + Pointer subterfuge AuthorTechniqueNotes
5
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Buffer overflow: some basic A buffer is a contiguous block of memory, that holds multiple instances of the same data type To a C programmer, a buffer is usually char buffer[200]; [Or char* buffer = (char*)malloc(200); ] –In the latter case, we have a dynamically allocated buffer -> we’ll consider this case later –In fact, it is possible to overflow (and exploit) various types of buffers. The first one we’ll see, is the stack buffer overflow
6
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Buffer overflow: some basic (2) Buffers are commonly used, especially in network programming. char recvbuf[32]; bytesRecv = recv(ConnectSocket, recvbuf, 32, 0); What if str is more than 20 characters? void printFunc(char* str) { char buffer[20]; strcpy(buffer, str);... } A buffer overflow is a condition created by a defect in a program.
7
Software attacks Lorenzo Dematte’ (dematte@ieee.org) What is a Buffer Overflow? In most cases, if it’s a programming error, a buffer overflow results in a Segmentation Fault / Memory Access error void func() { char buffer[20]; char* current = buffer; for (int i = 0; i < 256; ++i) { *current = 'A'; ++current; } } What about this address? We’ll see in a moment…
8
Software attacks Lorenzo Dematte’ (dematte@ieee.org) How can this lead to a software attack? You can use it to inject code/data in a program and then Change the program control flow. (If used bad) you can crash a system process (DoS) (If used well) Can lead to privilege escalation / Malicious Code execution.
9
Software attacks Lorenzo Dematte’ (dematte@ieee.org) How can this lead to a software attack?(2) In the stack smashing exploit, a buffer allocated on the stack is overflowed to overwrite a particular area of the stack. This approach is very architecture dependent: So, let’s see how is the stack configuration of a process (x86, but is valid for every architecture)
10
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Memory layout The attack is architecture dependent We take as an example Win32 on an x86 CPU Each process has its own Virtual Address Space, which is divided into several areas: text, bss, stack, heap, etc… Exe image stack heap 0x00000000 0x00400000 0x00130000 0x00140000 We’ll see the heap in more detail in another lesson 0x7FFFFFFF 0x00030000
11
Software attacks Lorenzo Dematte’ (dematte@ieee.org) The Stack Why the stack? Function calls! Pop, push, EBP, ESP Stack grow from 0x00130000 to 0x0003000 (from high to low) <- this is due to x86 stack instructions Page guard … 2 pages committed 0x00130000 0x00030000
12
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack configuration (1) Let’s see what asm code the following (simple) program generates: void f(int a, int b) { char buffer[20]; int i; int j; j = a; i = a + b; } int main() { f(2, 3); return 0; } Do it by yourself! /Fas (VC) –save_temps (gcc) push ebp mov ebp, esp sub esp, 0 ; 13 : f(2, 3); push 3 push 2 call _f ; 14 : return 0; xor eax, eax mov esp, ebp pop ebp ret 0 push ebp mov ebp, esp sub esp, 28 ; 4 : char buffer[20]; ; 5 : int i; ; 6 : int j; ; 7 : j = a; ; 8 : i = a + b; mov eax, DWORD PTR [ebp + 8h] ; a mov DWORD PTR [ebp - 8], eax ; j EBP - 8 add eax, DWORD PTR [ebp + 0Ch] ; b mov DWORD PTR [ebp - 4], eax ; i EBP - 4 mov esp, ebp pop ebp ret 0
13
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack configuration (2) 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 ESP Return address a b And now let’s see how a function call is made
14
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack configuration (2) 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 ESP Return address a b 0012FE90 0x0012FE80 EBP saved PUSH EBP
15
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack configuration (2) 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 ESP Return address a b 0012FE90 0x0012FE80 EBP saved MOV EBP, ESP EBP
16
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack configuration (2) 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 ESP Return address a b 0012FE90 0x0012FE80 EBP saved SUB ESP, 28 EBP unitiliazed Unitiliazed j i buffer NB! EBP let us know where local variables and parameter are located! EBP – offset -> locals EBP + 8 + offset -> params
17
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack configuration (3) push ebp mov ebp, esp sub esp, 28 ; 4 : char buffer[20]; ; 5 : int i; ; 6 : int j; ; 7 : j = a; ; 8 : i = a + b; mov eax, DWORD PTR [ebp + 8h] ; a mov DWORD PTR [ebp - 8], eax ; j add eax, DWORD PTR [ebp + 0Ch] ; b mov DWORD PTR [ebp - 4], eax ; i mov esp, ebp pop ebp ret 0 Do you remember?Let’s see a slightly more complex example void f(int a, int b, char* str) { char buffer[12]; int i; int j; j = a; i = a + b; strcpy(buffer, str); } Where str = “averyverylongstring”
18
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Stack smashing 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 ESP Return address a b 0012FE90 0x0012FE80 EBP saved EBP j i buffer Before strcpy… Return address a b EBP saved j i buffer 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 ESP 0012FE90 0x0012FE80 EBP ing\0 gstr aver yver ylon …and after! unitiliazed Unitiliazed
19
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Overwriting return address If we go further, we have the saved frame pointer, plus the return address Go overwrite it, placing an address of our choice! The buffer could be filled with code of our own choice!
20
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Overwriting return address //00401090 static char message[] = "AAAAAAAAAAAAAAAAAAAAAAAA\x90\x10\x40\x00"; void handleRequest() { char buffer[20]; strcpy(buffer, message); printf("Request: %s\n", buffer); } void doNastyThings() { printf("He he!!\n"); } int main() { while(1) { handleRequest(); } return 0; } DD DD Old sfp 20 10 40 00 Fill buffer AA AA Old sfp 20 10 40 00 owr sfp AA AA 20 10 40 00 owr ret AA AA 90 10 40 00
21
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Shellcode writing We have only injected an arc, modifying the control flow of a program, but we can inject code as well This requires us to write some shellcode A shellcode is a small portion of machine code we write by hand, and then insert in the buffer
22
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Shellcode injection The shellcode has to be small, and it must not contain terminators for the function overflowing the buffer (ex: \n, \x00, \r,…) We “send” it in the buffer before the return address, and then point the return address back in the buffer SSSSSSSSSSSSSSSSSSSPPPPP20FF1200 0x0012FF20 S = shellcode; P = padding
23
Software attacks Lorenzo Dematte’ (dematte@ieee.org) NOP Problem: At what address our code will be? What do we (over)write as ret? Answer: (1)Estimate (stack start always at the same address (0x00130000 on Win32)) (2)Use nop(s) to have a margin (otherwise) Trampolining (more on this later) int f() { } int g() { f(); } int main() { f(); g(); } main stack frame f stack frame main stack frame g stack frame f stack frame 0x00130000 ?
24
Software attacks Lorenzo Dematte’ (dematte@ieee.org) NOP (2) NNNNNSSSSSSSSSSSSSSSSSSS 4 0FF1200 0x0012FF20 S = shellcode; N = NOP Our estimate is not precise, but it works nonetheless [How to write a shellcode?]
25
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Exploits possible Overwrite ret with an address pointing back to the buffer, use NOPs to increment probabilities (stack protection) Overwrite ret with an absolute address, taken by a Win32 dll (ex: WinExec in kernel32.dll) (but the params? – hardcoded addresses change) Find a trampoline (jmp reg, call reg) at an absolute address (same as before)
26
Software attacks Lorenzo Dematte’ (dematte@ieee.org) A simple example (Demo?)
27
Software attacks Lorenzo Dematte’ (dematte@ieee.org) A real world example: Blaster
28
Software attacks Lorenzo Dematte’ (dematte@ieee.org) (Brief COM introduction) What is COM? Component Object Model: object are in DLLs and can be used locally or invoked remotely (ex: DirectX, Active Directory, ADO, etc.) Component implement some interfaces The COM runtime provides function to load/locate/create components These functions MUST work for both locally avalable AND server-side components
29
Software attacks Lorenzo Dematte’ (dematte@ieee.org) The COM model CoCreateInstance IClassFactory IUnknown IClassFactory::CreateInstance return IUnknown* to client CoGetInstanceFromFile IPersistFile IUnknown IPersistFile::Load return IUnknown* to client
30
Software attacks Lorenzo Dematte’ (dematte@ieee.org) The RPC-DCOM interface vulnerability (1) HRESULT CoGetInstanceFromFile( COSERVERINFO * pServerInfo, CLSID * pclsid, IUnknown * punkOuter, DWORD dwClsCtx, DWORD grfMode, OLECHAR * szName, ULONG cmq, MULTI_QI * rgmqResults ); Includes name of server Name of file containing persistant object Message is packed for RPC request, and the string passed to server is assembled in this way “\\servername\filename”
31
Software attacks Lorenzo Dematte’ (dematte@ieee.org) The RPC-DCOM interface vulnerability (2) GetPathForServer GetMachineName At server side String is assembled by system, BUT we can assemble a malicious request building an ad-hoc packet! Here buffer is 32 only! (max length of a NETBIOS name) Here the only check done is ‘\’ (cmp ax, 5Ch)!
32
Software attacks Lorenzo Dematte’ (dematte@ieee.org) The RPC-DCOM interface vulnerability (3) GetPathForServer;.text:761543DA push ebp.text:761543DB mov ebp, esp.text:761543DD sub esp, 20h <-----the length is only 0x20.text:761543E0 mov eax, [ebp+arg_4].text:761543E3 push ebx.text:761543E4 push esi.text:761543E5 mov esi, [ebp+hMem].text:761543E8 push edi.text:761543E9 push 5Ch.text:761543EB pop ebx.text:761543EC mov [eax], esi.text:761543EE cmp [esi], bx.text:761543F1 mov edi, esi.text:761543F3 jnz loc_761544BF.text:761543F9 cmp [esi+2], bx.text:761543FD jnz loc_761544BF.text:76154403 lea eax, [ebp+String1] <----addr to place servername, only 0X20.text:76154406 push 0.text:76154408 push eax.text:76154409 push esi <------------here is the parameter of filename.text:7615440A call GetMachineName GetMachineName:.text:7614DB6F mov eax, [ebp+arg_0].text:7614DB72 mov ecx, [ebp+arg_4].text:7614DB75 lea edx, [eax+4].text:7614DB78 mov ax, [eax+4].text:7614DB7C cmp ax, 5Ch <-----------check if it is 0X5C,if yes,the servername is over
33
Software attacks Lorenzo Dematte’ (dematte@ieee.org) The exploit One of the published exploits is by Xfocus.org (many others, remember?) It uses a trampoline (jmp esp) On XP SP1, there is one at 0x77d737db More details, plus the documentation and the complete exploit, on their website
34
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Workarounds So, how can we avoid such situations? Some over-simplistic recommendations: –Move-to-heap -> heap smashing! –Use “safe” functions: avoid using C library functions (like strcpy) -> is not a panacea! Remember Blaster strncpy vulnerabilities void ConcatString(char *buf1, char *buf2, size_t len1, size_t len2) { char buf[256]; if((len1 + len2) > 256) return -1; memcpy(buf, buf1, len1); memcpy(buf + len1, buf2, len2); }
35
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Mitigations What is a mitigation? Instead of letting malicious hackers obtain control over a machine, kill process If the program/OS is aware that there is a buffer overflow, terminate program It can have a DoS effect, but arbitrary code excecution is MUCH worse!
36
Software attacks Lorenzo Dematte’ (dematte@ieee.org) StackGuard The first to introduce canaries 004119A2 0x0012FE84 0x0012FE88 0x0012FE8C 00000003 00000002 Return address a b 0012FE90 0x0012FE80 EBP saved unitiliazed j i StackCanary Stack grows memory grows locals params Canaries is checked before the asm ret instruction The StackGuard idea: terminator canary Is a word “\x00\n\r\xFF”
37
Software attacks Lorenzo Dematte’ (dematte@ieee.org) VC 7.X stack canary (Windows XP SP2 & Windows 2003 Server) Recently introduced in Visual C++ Canary is a random word, so it works better then StackGuard However, stack protection has still several vulnerabilities –Double Cookie Overwrite –Security Handler Overwrite –Replacing the Windows System Directory –Ldr* function pointer overwrites See http://www.nextgenss.com/papers/defeating-w2k3-stack-protection.pdf
38
Software attacks Lorenzo Dematte’ (dematte@ieee.org) They can be defeated Heap overflow Trampolines over canary (StackGuard) terminators (Blaster) Arc injection, function pointer overwrites, new buffer overflow techniques (next lessons)
39
Software attacks Lorenzo Dematte’ (dematte@ieee.org) NX bit http://en.wikipedia.org/wiki/NX NX bit may prevent the stack and heap memory areas from being executable, and may prevent executable memory from being writable Not available on x86-32 (but available on x86-64)
40
Software attacks Lorenzo Dematte’ (dematte@ieee.org) Conclusions The network is populated with untrustworthy people –All input should not be trusted until proven otherwise Do not trust input that comes from non- validated sources –If user/caller does not authenticate, do not extend trust Use a "white list" instead of a "black list" –Determine what is legal and reject the rest –Test carefully with illegal values (fault injection) Limit maximum characters length (some advices by G. McGraw)
41
Software attacks Lorenzo Dematte’ (dematte@ieee.org) [Overwriting function pointers] Attack known as pointer subterfuge void func(void* arg, size_t len) { char buffer[100]; void (*f)() =...; memcpy(buff, arg, len); //buffer overflow f();... } It may seems not so common.. But it has no mitigations and in other forms is very widely used… …but we’ll see it in another lesson!
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.