Download presentation
Presentation is loading. Please wait.
1
Let’s look at an example
I want to write an application that reports the course scores to you. Requirements: Every student can only get his/her score Maintain all students’ scores in a file Local command-line operation
2
Score file format [root@localhost getscore]# cat score.txt
Mary Doe: :A+:… Tom Smith: :B:… User name Student SSN Score
3
Our little “getscore” program
User name and SSN for authentication Score file only readable to user root A program reads the score file and report the grade to an authenticated user ls -l total 24 -rw root root Aug 20 11:35 score.txt -rwsr-xr-x 1 root root Aug 20 11:36 getscore Setuid bit
4
Unix file system protection
Permission bits Attributes of a file course_scores]# ls -l total 20 -rwsr-xr-x 1 root root Aug getscore -rw root root Aug score.txt Owner Group directory bit owner permissions group permissions other user permissions d: directory r:read w:write x:execute (access a directory) s:set-uid bit {[d,-]} {[r,-] [w,-] [x,s,-]} {[r,-] [w,-] [x,s,-]} {[r,-] [w,-] [x, -]}
5
Unix set-uid mechanism
A user can execute a program if the program file has “x” bit set for the user Typically the program process will have the invoker’s privilege If the program file also has the set-uid bit set for the owner (“s” is shown for the owner), then the program will also have the program owner’s privilege. We call such programs “set-uid programs”.
6
Unix set-uid mechanism
Provides a path for privilege elevation There are legitimate needs for elevating a process’ privilege to perform its jobs, e.g. “passwd” command. (Simplified version) Two user id fields in a process’s PCB: real user id (ruid), and effective user id (euid) It is the euid that matters in OS protection. non-setuid programs will have both fields set to the id of the invoker when the program is started. Setuid programs have ruid set to the invoker, but euid set to the owner of the executable when started. There are programming interfaces for changing the two uid’s during the program’s execution, and rules on which changes are allowed.
7
Getting your score ./getscore "Mary Doe" Your score is A+ course_scores]$ ./getscore "Tom Smith" Your score is B Show the case when setuid bit is not present. ./getscore "Mary Doe" Invalid user name or SSN.
8
Security problems in getscore
First things first: analyze the threat Who are the adversaries? What are they after? What are the potential risks and their implications? How would you mitigate the risk?
9
There is a vulnerability in the getscore program
Let’s try this getscore]$ ./getscore "Mary Doe" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault A protection mechanism at work There is a vulnerability in the getscore program
10
Linux process memory map
.text .data heap allocated data address growth > heap < a stack frame stack ESP local variables EBP saved EBP function’s return address saved EIP function’s arguments main() local variables argc, **argv, **envp environment var’s bottom of stack
11
Calling a function .text main(){ .data : heap function(s) > } <
top of stack < > main() local vars ESP EBP argc, **argv, **envp environment var’s main(){ : function(s) } Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee.
12
Calling a function .text main(){ .data : heap function(s) > } <
top of stack < > ESP EBP argc, **argv, **envp environment var’s main(){ : function(s) } push s Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. function argument main() local vars
13
Calling a function .text main(){ .data : heap function(s) > }
function argument saved EIP ESP EBP argc, **argv, **envp environment var’s main(){ : function(s) } push return EIP function(s){ : return; } < top of stack Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. main() local vars
14
Calling a function .text main(){ .data : heap function(s) > } <
top of stack < > function argument saved EBP saved EIP main() local vars ESP EBP argc, **argv, **envp environment var’s local variables main(){ : function(s) } push EBP allocate a new frame for local variables function(s){ : return; } Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee.
15
Stack buffer overflow attack
.text .data heap top of stack < > function argument saved EBP saved EIP main() local vars ESP EBP argc, **argv, **envp environment var’s local variables main(){ : function(s) } function(s){ : return; } Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee.
16
Returning from a function
.text .data heap > function argument saved EBP saved EIP main() local vars ESP argc, **argv, **envp environment var’s local variables < main(){ : function(s) } function(s){ : return; } Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. EBP release the function’s frame and restore the saved EBP
17
Returning from a function
.text .data heap > function argument saved EBP saved EIP main() local vars ESP argc, **argv, **envp environment var’s local variables main(){ : function(s) } function(s){ : return; } A buffer overflow on stack can change this control flow Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. < EBP release control to the caller
18
Stack overflow attack .text main(){ .data : heap function(s) > }
top of stack < > function argument saved EBP saved EIP main() local vars ESP EBP argc, **argv, **envp environment var’s local variables main(){ : function(s) } push EBP allocate a new frame for local variables function(s){ : return; } AAAAAAAAAAA AAAAAAAAAAAAAAA A A A A Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. A A A A
19
Stack overflow attack .text main(){ .data : heap function(s) > }
top of stack < > function argument saved EBP saved EIP main() local vars ESP EBP argc, **argv, **envp environment var’s local variables main(){ : function(s) } function(s){ : return; } AAAAAAAAAAA AAAAAAAAAAAAAAA A A A A Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. A A A A
20
Stack overflow attack .text main(){ .data : heap function(s) > EBP
function argument saved EBP saved EIP main() local vars ESP argc, **argv, **envp environment var’s local variables < main(){ : function(s) } EBP 0x function(s){ : return; } AAAAAAAAAAA AAAAAAAAAAAAAAA A A A A Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. A A A A release the function’s frame and restore the saved EBP
21
Control Hijacked by Attacker!
Stack overflow attack .text .data heap > function argument saved EBP saved EIP main() local vars ESP argc, **argv, **envp environment var’s local variables main(){ : function(s) } EBP 0x function(s){ : return; } AAAAAAAAAAA AAAAAAAAAAAAAAA A A A A Push EBP is done by the callee before allocating a new frame for the function’s local variables. Similarly, restoring EBP is also done by the callee. A A A A < Control Hijacked by Attacker!
22
Buffer overflow vulnerability
Program fails to ensure that a write to a buffer is always within its bound. When buffer overflow happens, data structures in memory will be corrupted, potentially changing the program’s behavior. In many cases it can lead to the execution of arbitrary code by attackers A common problem for unsafe programming languages such as C and C++.
23
Setuid and buffer overflow
What is the implication of a buffer overflow in a setuid program? If the buffer overflow happens when one of the uid fields contains more privilege, it could result in a local privilege escalation vulnerability, i.e. an attacker who already obtained local access on the system can escalate his privilege. If the setuid program is owned by root, an attacker who has user account privilege may gain root privilege on the system.
24
Creating a malicious input
NOP sled Shell Code EIP The original buffer Questions: 1. How long should the input be? 2. Where should we put the EIP in the input? 3. What value of EIP should be put in?
25
Shell code to use /* Aleph1's Linux shellcode
from "Smashing the stack for fun and profit", Phrack 49, vol 7 */ char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";
26
Getting a root shell simon]$ ./exploit_gen_with_esp 0xbffff Length of shell code: 45 Using sp: 0xbffff830 Using address: 0xbffff7b8 NOP sled: 103 bytes simon]$ cd /root/course_scores/ course_scores]$ ./getscore aaa $EGG sh-2.05b# sh-2.05b# whoami root
27
Summary OS protection prevents applications from interfering with each other Protection mechanisms are limited by the possible vulnerabilities in the application and system code
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.