52a05998498f50902482cb19122468cd.ppt
- Количество слайдов: 41
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Software Attacks Buffer Overflow
Software attacks Lorenzo Dematte’ (dematte@ieee. org) Outline of the seminaries • 8 hours, 4 lessons + 2 -3 hours seminars by YOU =) • Buffer overflow, introduction: – Stack smashing, concepts, practical example (Blaster) – Mitigations • Buffer overflow: new techniques – Heap smashing, concepts, the heap in Win 32 – Countermeasures: Win. XP SP 2 • Integer overflow and DLL injection – A Win 32 process memory layout – An example: IAT patching, memory walking • Countermeasures: managed languages (Java, . NET) – An example: . NET Code Access Security
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, Bug. Traq.
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Microsoft Security Bulletin MS 03 -26 (buffer overflow vulnerability exploited by Blaster) Author Technique Notes Last Stage of Delirium Unknown Original report Never published Xfocus Stack smashing Apparently same as Blaster www. xfocus. org/ D. Litchfield Pointer subterfuge Cigital Pointer subterfuge K-oitic Arc injection Pincus, Baker Arc injection + Pointer subterfuge
Lorenzo Dematte’ (dematte@ieee. org) Software attacks 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
Software attacks Lorenzo Dematte’ (dematte@ieee. org) Buffer overflow: some basic (2) Buffers are commonly used, especially in network programming. char recvbuf[32]; bytes. Recv = recv(Connect. Socket, recvbuf, 32, 0); A buffer overflow is a condition created by a defect in a program. void print. Func(char* str) { char buffer[20]; strcpy(buffer, str); . . . } What if str is more than 20 characters?
Lorenzo Dematte’ (dematte@ieee. org) Software attacks 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…
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 (Do. S) (If used well) Can lead to privilege escalation / Malicious Code execution.
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 (x 86, but is valid for every architecture)
Software attacks Lorenzo Dematte’ (dematte@ieee. org) Memory layout • The attack is architecture dependent • We take as an example Win 32 on an x 86 CPU • Each process has its own Virtual Address Space, which is divided into several areas: text, bss, stack, heap, etc… 0 x 0000 0 x 00030000 0 x 00130000 stack 0 x 00140000 heap 0 x 00400000 Exe image 0 x 7 FFFFFFF • We’ll see the heap in more detail in another lesson
Lorenzo Dematte’ (dematte@ieee. org) Software attacks The Stack • Why the stack? Function calls! • Pop, push, EBP, ESP • Stack grow from 0 x 00130000 to 0 x 0003000 (from high to low) <- this is due to x 86 stack instructions 0 x 00030000 … Page guard 0 x 00130000 2 pages committed
Lorenzo Dematte’ (dematte@ieee. org) Software attacks 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; ; ; ; 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; } int main() { f(2, 3); return 0; mov eax, DWORD PTR mov DWORD PTR [ebp add eax, DWORD PTR mov DWORD PTR [ebp mov esp, ebp pop ebp ret 0 [ebp + 8 h] ; a - 8], eax ; j EBP - 8 [ebp + 0 Ch] ; b - 4], eax ; i EBP - 4 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 } Do it by yourself! /Fas (VC) –save_temps (gcc)
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack configuration (2) And now let’s see how a function call is made ESP 0 x 0012 FE 84 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 Return address a b
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack configuration (2) PUSH EBP ESP 0 x 0012 FE 80 0012 FE 90 EBP saved 0 x 0012 FE 84 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 Return address a b
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack configuration (2) MOV EBP, ESP 0012 FE 90 EBP saved 0 x 0012 FE 84 EBP 0 x 0012 FE 80 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 Return address a b
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack configuration (2) ESP Unitiliazed buffer SUB ESP, 28 unitiliazed 0 x 0012 FE 80 0 x 0012 FE 84 EBP 0012 FE 90 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 i j EBP saved Return address a b NB! EBP let us know where local variables and parameter are located! EBP – offset -> locals EBP + 8 + offset -> params
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack configuration (3) Do you remember? ; ; ; 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; 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; mov eax, DWORD PTR mov DWORD PTR [ebp add eax, DWORD PTR mov DWORD PTR [ebp mov esp, ebp pop ebp ret 0 [ebp + 8 h] ; a - 8], eax ; j [ebp + 0 Ch] ; b - 4], eax ; i i = a + b; strcpy(buffer, str); } Where str = “averylongstring”
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack smashing Unitiliazed ESP buffer unitiliazed 0 x 0012 FE 80 0 x 0012 FE 84 EBP 0012 FE 90 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 i j EBP saved Return address a b ESP Before strcpy… …and after! buffer gstr ing i j 0 x 0012 FE 80 0012 FE 90 EBP saved 0 x 0012 FE 84 EBP aver ylon 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 Return address a b
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!
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Overwriting return address //00401090 static char message[] = "AAAAAAAAAAAAx 90x 10x 40x 00"; Fill buffer owr sfp owr ret void handle. Request() { char buffer[20]; strcpy(buffer, message); printf("Request: %sn", buffer); } void do. Nasty. Things() { printf("He he!!n"); } int main() { while(1) { handle. Request(); } return 0; } AA AA AA AA DD DD DD DD AA sfp Old. AA AA AA 90 20 10 40 00
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
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Shellcode injection • The shellcode has to be small, and it must not contain terminators for the function overflowing the buffer (ex: n, x 00, r, …) • We “send” it in the buffer before the return address, and then point the return address back in the buffer 0 x 0012 FF 20 SSSSSSSSSSPPPPP 20 FF 1200 S = shellcode; P = padding
Lorenzo Dematte’ (dematte@ieee. org) Software attacks NOP Problem: At what address our code will be? What do we (over)write as ret? int f() { } int g() { f(); } f stack frame int main() { f(); g(); f stack frame 0 x 00130000 g stack frame main stack frame ? } Answer: (1) Estimate (stack start always at the same address (0 x 00130000 on Win 32)) (2) Use nop(s) to have a margin (otherwise) Trampolining (more on this later)
Lorenzo Dematte’ (dematte@ieee. org) Software attacks NOP (2) 0 x 0012 FF 20 NNNNNSSSSSSSSSS 40 FF 1200 S = shellcode; N = NOP Our estimate is not precise, but it works nonetheless [How to write a shellcode? ]
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 Win 32 dll (ex: Win. Exec in kernel 32. dll) (but the params? – hardcoded addresses change) • Find a trampoline (jmp reg, call reg) at an absolute address (same as before)
Lorenzo Dematte’ (dematte@ieee. org) Software attacks A simple example (Demo? )
Software attacks Lorenzo Dematte’ (dematte@ieee. org) A real world example: Blaster
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: Direct. X, 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
Lorenzo Dematte’ (dematte@ieee. org) Software attacks The COM model IUnknown Co. Create. Instance IClass. Factory return IUnknown* to client IClass. Factory: : Create. Instance IUnknown Co. Get. Instance. From. File IPersist. File return IUnknown* to client IPersist. File: : Load
Software attacks Lorenzo Dematte’ (dematte@ieee. org) The RPC-DCOM interface vulnerability (1) HRESULT Co. Get. Instance. From. File( COSERVERINFO * p. Server. Info, CLSID * pclsid, IUnknown * punk. Outer, DWORD dw. Cls. Ctx, DWORD grf. Mode, OLECHAR * sz. Name, ULONG cmq, MULTI_QI * rgmq. Results ); 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 “\servernamefilename”
Lorenzo Dematte’ (dematte@ieee. org) Software attacks The RPC-DCOM interface vulnerability (2) At server side Get. Path. For. Server Get. Machine. Name Here the only check done is ‘’ (cmp ax, 5 Ch)! Here buffer is 32 only! (max length of a NETBIOS name) String is assembled by system, BUT we can assemble a malicious request building an ad-hoc packet!
Lorenzo Dematte’ (dematte@ieee. org) Software attacks The RPC-DCOM interface vulnerability (3) Get. Path. For. Server; . text: 761543 DA . text: 761543 DB . text: 761543 DD . text: 761543 E 0 . text: 761543 E 3 . text: 761543 E 4 . text: 761543 E 5 . text: 761543 E 8 . text: 761543 E 9 . text: 761543 EB . text: 761543 EC . text: 761543 EE . text: 761543 F 1 . text: 761543 F 3 . text: 761543 F 9 . text: 761543 FD . text: 76154403 . text: 76154406 . text: 76154408 . text: 76154409 . text: 7615440 A Get. Machine. Name: . text: 7614 DB 6 F . text: 7614 DB 72 . text: 7614 DB 75 . text: 7614 DB 78 . text: 7614 DB 7 C over push ebp mov ebp, esp sub esp, 20 h <-----the length is only 0 x 20 mov eax, [ebp+arg_4] push ebx push esi mov esi, [ebp+h. Mem] push edi push 5 Ch pop ebx mov [eax], esi cmp [esi], bx mov edi, esi jnz loc_761544 BF cmp [esi+2], bx jnz loc_761544 BF lea eax, [ebp+String 1] <----addr to place servername, only 0 X 20 push eax push esi <------here is the parameter of filename call Get. Machine. Name mov lea mov cmp eax, [ebp+arg_0] ecx, [ebp+arg_4] edx, [eax+4] ax, 5 Ch <------check if it is 0 X 5 C, if yes, the servername is
Lorenzo Dematte’ (dematte@ieee. org) Software attacks The exploit One of the published exploits is by Xfocus. org (many others, remember? ) It uses a trampoline (jmp esp) On XP SP 1, there is one at 0 x 77 d 737 db More details, plus the documentation and the complete exploit, on their website
Lorenzo Dematte’ (dematte@ieee. org) Software attacks 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! strncpy vulnerabilities Remember Blaster void Concat. String(char *buf 1, char *buf 2, size_t len 1, size_t len 2) { char buf[256]; if((len 1 + len 2) > 256) return -1; memcpy(buf, buf 1, len 1); memcpy(buf + len 1, buf 2, len 2); }
Lorenzo Dematte’ (dematte@ieee. org) Software attacks 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 Do. S effect, but arbitrary code excecution is MUCH worse!
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Stack. Guard • The first to introduce canaries Canaries is checked before the asm ret instruction unitiliazed i j locals Stack. Canary Stack grows 0 x 0012 FE 80 0012 FE 90 EBP saved 0 x 0012 FE 84 004119 A 2 0 x 0012 FE 88 00000003 0 x 0012 FE 8 C 00000002 Return address a b params The Stack. Guard idea: terminator canary Is a word “x 00nrx. FF” memory grows
Software attacks Lorenzo Dematte’ (dematte@ieee. org) VC 7. X stack canary (Windows XP SP 2 & Windows 2003 Server) • Recently introduced in Visual C++ • Canary is a random word, so it works better then Stack. Guard • 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-w 2 k 3 -stack-protection. pdf
Software attacks Lorenzo Dematte’ (dematte@ieee. org) They can be defeated • • Heap overflow Trampolines over canary (Stack. Guard) terminators (Blaster) Arc injection, function pointer overwrites, new buffer overflow techniques (next lessons)
Lorenzo Dematte’ (dematte@ieee. org) Software attacks 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 x 86 -32 (but available on x 86 -64)
Lorenzo Dematte’ (dematte@ieee. org) Software attacks Conclusions (some advices by G. Mc. Graw) • The network is populated with untrustworthy people – All input should not be trusted until proven otherwise • Do not trust input that comes from nonvalidated 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
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!


