introduction to software security software...
TRANSCRIPT
Seong-je Cho
Spring 2019
Computer Security & Operating Systems Lab, DKU
Introduction to Software Security
Software Flaws (2)(chapter 11)
- 2 -
Sources / References
Textbook
N. Vlajic, CSE 3482: Introduction to Computer Security, Yorku
Nicholas Weaver, Computer Science 161: Computer Security, Berkeley
Myrto Arapinis, Computer Security: INFRA10067, University of Edinburgh
2011 CWE/SANS Top 25 Most Dangerous Software Errors
Lecture 12 Program Security, CS 450/650 Lecture
• Exploiting Format String Vulnerabilities, scut, 2001• http://www.madchat.fr/coding/c/c.seku/format_string/formatstring.pdf
• Textbook: R. C. Seacord, Secure Coding in C and C++, Second Ed., Addison-Wesley• http://ptgmedia.pearsoncmg.com/images/9780321822130/samplepages/0321822137.pdf
• Insecure Programming by example• http://community.coresecurity.com/~gera/InsecureProgramming/
Please do not duplicate and distribute
Computer Security & OS Lab, DKU
- 3 -
Contents
Software Security Issues
Software Bug/Flaw/Vulnerability
Buffer Overflows
Stack Buffer Overflows = Stack Smashing
Stack Protection
W⊕X : Executable Disable (XD), DEP
ASLR
Integer Overflows
Format String Vulnerabilities
Countermeasures
Computer Security & OS Lab, DKU
- 4 -
Stack Protection against Buffer Overflow
Disable stack protection on Ubuntu for buffer overflow
gcc -fstack-protector -masm=intel -S test.c
gcc –fno-stack-protector -masm=intel -S vulpro.c
● You can compile without stack canaries ( -fno-stack-protector) and with making code executable on the stack ( -z execstack)
gcc –fno-stack-protector –z execstack -o <my_pg> my_pg.c
● Making code no-executable on the stack with linker options ( -z noexecstack)
Enable an executable stack (without needing a recompile)
execstack -s /path/to/myprog
● -s --set-execstack
Mark binary or shared library as requiring executable stack.
● -c --clear-execstack
Mark binary or shared library as not requiring executable stack.
Computer Security & OS Lab, DKU
- 5 -
Address Space Layout Randomization (ASLR)
Computer Security & OS Lab, DKU
View ASLR settings
Disable ASLR
View Address Space
- 6 -
Disable/Enable ASLR
Configure ASLR using /proc/sys/kernel/randomize_va_space
● 0 : No randomization. Everything is static.
● 1 : Conservative randomization.
− Shared libraries, stack, mmap(), VDSO and heap are randomized.
− VDSO: virtual dynamically linked shared objects
● 2 : Full randomization.
− In addition to elements listed in the previous point, memory managed through brk() is also randomized.
Disable ASLR
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space (or)
echo 0 > /proc/sys/kernel/randomize_va_space
Enable ASLR
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
To temporally disable it, use sudo sysctl kernel.randomize_va_space=0
To permanently disable it, add a file /etc/sysctl.d/01-disable-aslr.conf containing: kernel.randomize_va_space = 0
Computer Security & OS Lab, DKU
Integer Overflow/Underflow
Computer Security & OS Lab, DKU
- 8 -
Bad Software is everywhere!
ARIANE 5 : Flight 501 Failure (The crash & burn of Ariane 5 Flight 501)
Europe’s newest un-manned satellite-launching rocket
On 4 June 1996, the maiden flight of the Ariane 5 launcher ended in a failure
the Internal Reference System (SRI) that measured the rocket’s spatial attitude (altitude, motion, and position) sent incorrect data to the Flight Control System instead of the actual flight data because an arithmetic overflow occurred inside its alignment function when a 64-bit floating point number for the Horizontal Basis variable (BH) could not be cast and converted to a signed 16-bit integer.
NASA’s Mars Climate Orbiter (cost $125 million)
NASA's metric confusion caused Mars orbiter loss
Error in converting units from English to metric
one engineering team used metric units while another used English units for a key spacecraft
operation
September 30, 1999
Computer Security & OS Lab, DKU
- 9 -
Integer Overflow Examples
Example 1
#include <stdio.h>
int main(void){
unsigned int num = 0xffffffff;
printf("num = %u (0x%x)\n", num, num);
printf("num + 1 = 0x%x\n", num + 1);
return 0;
}/* EOF */
The output of this program looks
like this:
num = 4294967295 (0xffffffff)
num + 1 = 0x0
Example 2
#include <stdio.h>
int main(void){
int n;
n = 0x7fffffff;
printf(“n = %d (0x%x)\n", n, n);
printf(“n + 1 = %d (0x%x)\n", n + 1 , n+1);
return 0;
}/* EOF */
The output of which is:
n = 2147483647 (0x7fffffff)
n + 1 = -2147483648 (0x80000000)
- 10 -
Integer Overflow Errors: Addition/Subtraction/Multiplication
Computer Security & OS Lab, DKU
1. unsigned int ui1, ui2 , usum ;
2.
3. /∗ Initialize ui1 and ui2 ∗/
4.
5. usum = ui1 + ui2 ;
UINT_MAX = ?
INT_MAX = ?
INT_MIN = ?
sizeof (signed int) = ?
1. signed int si1 , si2 , result;
2.
3. /∗ Initialize si1 and si2 ∗/
4.
5. result = si1 * si2 ;
1. signed int si1, si2, result;
2.
3. /* initialize si1 and si2 */
4.
5. result = si1 – si2;
- 11 -
Integer Ranges
Example integer ranges
Computer Security & OS Lab, DKU
- 12 -
Integer overflow / underflow
32-bit architecture
INT_MAX = 2,147,483,647
INT_MIN = -2,147,483,648
UINT_MAX = 4,294,967,295
(0xffffffff)
UINT_MAX =
Computer Security & OS Lab, DKU
32-bit architecture
INT_MAX + 1 =
INT_MIN - 1 =
UINT_MAX + 1 =
UINT_MIN – 1 =
- 13 -
An Unsafe Program
Computer Security & OS Lab, DKU
#include <limits.h>
int i;
unsigned int j;
i = INT_MAX; // 2,147,483,647
i++;
printf (“i = %d \n”, i);
j = UNIT_MAX; // 4,294,967,295
j++;
printf (“j = %u \n”);
i = -2,147,483,648
j = 0
/* ex4.c - various arithmetic overflows */#include <stdio.h>int main(void){
int l, x;
l = 0x40000000;printf("l = %d (0x%x)\n", l, l);
x = l + 0xc0000000;printf("l + 0xc0000000 = %d (0x%x)\n", x, x);
x = l * 0x4;printf("l * 0x4 = %d (0x%x)\n", x, x);
x = l - 0xffffffff;printf("l - 0xffffffff = %d (0x%x)\n", x, x);return 0;
}
$ ./ex4l = 1073741824 (0x40000000)l + 0xc0000000 = 0 (0x0)l * 0x4 = 0 (0x0)l - 0xffffffff = 1073741825 (0x40000001)
- 14 -
Integer Underflow
Computer Security & OS Lab, DKU
0x00000001 = +1
0xFFFFFFFE (+1의 1의보수)
0xFFFFFFFF = -1 (1을더하면, 2의보수)
- 15 -
Integer underflow
if the integer value used is less than the minimum signed or unsigned int.
This is called an underflow and will also trigger a segmentation fault.
Because the binary unsigned int -4294967295 is similar to the binary representation of the signed int -1 in memory
INT_MIN = -2147483647-1
UINT_MIN = -4294967295
Computer Security & OS Lab, DKU
- 16 -
Vulnerable program int.c
#include <stdio.h>
int main(int argc, char *argv[]) {
char buf[20];
int i = atoi(argv[1]);
memcpy (buf, argv[2], i*sizeof(int));
printf("the number is:%d=%d\n",i, i*sizeof(int));
printf("the buffer is: %s\n",buf);
}
Computer Security & OS Lab, DKU
#include <string.h>void *memcpy(void *dest, const void *src, size_t n);
# ./int 1 AAAA
the number is:1=4
the buffer is:AAAA
# ./int 111 AAAA
Segmentation fault
# ./int -1 AAAA
Segmentation fault
source: Integer overflow/underflow exploitation tutorial, by Saif El-Shereihttps://www.exploit-db.com/docs/english/28477-linux-integer-overflow-and-underflow.pdf
- 17 -
Vulnerable program int.c – Overflow
Computer Security & OS Lab, DKU
Buffer overflow
- 18 -
Vulnerable program int.c – Underflow
Computer Security & OS Lab, DKU
-1073741810 X 4 = 56
- 19 -
Widthness Overflows
/* ex1.c - loss of precision */
#include <stdio.h>
int main(void){
int l;
short s;
char c;
l = 0xdeadbeef;
s = l;
c = l;
printf("l = 0x%x (%d bits)\n", l, sizeof(l) * 8);
printf("s = 0x%x (%d bits)\n", s, sizeof(s) * 8);
printf("c = 0x%x (%d bits)\n", c, sizeof(c) * 8);
return 0;
}
Computer Security & OS Lab, DKU
$ ./ex1
l = 0xdeadbeef (32 bits)
s = 0xffffbeef (16 bits)
c = 0xffffffef (8 bits)
Secure Coding
Fun with Integers
char x, y;
x = -128;
y = -x;
if (x == y) puts("1");
if ((x - y) == 0) puts("2");
if ((x + y) == 2 * x) puts("3");
if (((char)(-x) + x) != 0) puts("4");
if (x != -y) puts("5");
20Computer security & OS lab, DKU
Secure Coding
Type Conversion
Implicit Conversions
21Computer security & OS lab, DKU
Secure Coding
Preventing Integer Overflow
Preventing integer overflow in Java code
int sum(int a, int b) {
int c = a + b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
int prod(int a, int b) {
int c = a * b;
if (a > 0 && b > 0 && c < 0)
throw new MyOverfowException(a, b)
return c;
}
22Computer security & OS lab, DKU
Preventing C integer overflow static void update_value(char op) {
if (op == '+') {
if (value + 1 > value) value ++;
else printf (“too big! \n”);
} else {
if (value - 1 < value) value --;
else printf(“too small! \n”);
}
}
int addOvf(int* result, int a, int b) {
if( a > INT_MAX - b) return -1;
else {
*result = a + b;
return 0;
}
}
Format String Vulnerabilities
Computer Security & OS Lab, DKU
See the paper, “Exploiting Format String Vulnerabilities”http://www.madchat.fr/coding/c/c.seku/format_string/formatstring.pdf
You can get more information at http://www.cis.syr.edu/~wedu/Teaching/cis643/LectureNotes_New/Format_String.pdf
Secure Coding
printf();
%[parameter][flags][width][.precision][length]type
Flags +, space, -, # or 0
e.g.) printf("%2d", 3) results in “ 3", while printf("%02d", 3) results in "03".
Length
hh: For integer types, causes printf to expect an int-sized integer argument which was promoted from a char.
h: For integer types, causes printf to expect an int-sized integer argument which was promoted from a short.
Type
%n: Print nothing, but write number of characters successfully written so far into an integer pointer parameter.
%p: void * (pointer to void) in an implementation-defined format.
24Computer security & OS lab, DKU
printf("Color %s, number1 %d, number2 %05d, hex %#x, float %5.2f, unsigned value %u.\n","red", 123456, 89, 255, 3.14159, 250);
Color red, number1 123456, number2 00089, hex 0xff, float 3.14, unsigned value 250.
Secure Coding
The stack and its role at format strings
printf ("a has value %d, b has value %d, c is at address: %08x \n", a, b, &c);
25Computer security & OS lab, DKU
printf ("a has value %d, b has value %d, c is at address: %08x \n", a, b);
int a = 10;int b = 20;int c = 30;
Secure Coding
An Example of Format string vulnerabilty
/* format_test.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (int argc, char **argv) {
char buf [100];
int x = 1;
snprintf ( buf, sizeof buf, argv [1] );
buf [ sizeof buf -1 ] = 0;
printf ( “Buffer size is (%d) \n”, strlen(buf) );
printf ( “Data input: %s \n”, buf ) ; /*→ */
}
26Computer security & OS lab, DKU
$ ./format_test “Bob”
Buffer size is (3)
Data input: Bob
$ ./format_test “Bob %x %x”
Buffer size is (14)
Data input: Bob bffff 8740
The printf argument looks like:printf ( “Data input: Bob %x %x \n”, buf ) ;
Secure Coding
Format String Problems
The %x specifier enabled you read the stack, four bytes at a time
Is the app 32- or 64-bit?
ASLR is turned off
(Address Space Layout Randomization)
27Computer security & OS lab, DKU
/* fmt_bug1.c *#include <stdio.h>
int main(int argc, char * argv[]) { if (argc > 1) printf (argv[1]);
printf(“\n”);return 0;
}
[root@redhat]# ./fmt_bug1 "%x %x"bffffb88 400309cb[root@redhat]# ./fmt_bug1 %p0xbffffb88[root@redhat]# ./fmt_bug1 %p0xbffffb88[root@redhat]# ./fmt_bug1 "%x %x %x“bffffb88 400309cb 2$ ./fmt_bug1 %p00000000006A6790
Secure Coding
Format string is not a string literal (potentially insecure)
8048407: e8 34 ff ff ff call 8048340 <_init+0x80>
804840c: 83 c4 08 add $0x8,%esp
804840f: 6a 03 push $0x3
8048411: 6a 02 push $0x2
8048413: 6a 01 push $0x1
8048415: 8d 45 e0 lea 0xffffffe0(%ebp),%eax
8048418: 50 push %eax
8048419: e8 12 ff ff ff call 8048330 <_init+0x70>
28Computer security & OS lab, DKU
/* fmt_bug2.c */
int main() {char format [32];
strcpy (format, “%08x, %08x, %08x, %08x”);printf (format, 1, 2, 3);
}
[root@redhat]# ./fmt_bug2
00000001, 00000002, 00000003, 78383025[root@redhat]#
Secure Coding
Denial of Service (= Crashing the program)
• For each %s, printf() will fetch a number from the stack, treat this number as an address, and print out the memory contents pointed by this address as a string, until a NULL character (i.e., number 0, not character 0) is encountered.
• Since, the number fetched by printf() might not be a valid address, the memory pointed by this number might not exist (i.e. no physical memory has been assigned to such an address), and the program will crash.
• It is also possible that the number happens to be a good address, but the address space is protected (e.g. it is reserved for kernel memory). In this case, the program will also crash.
29Computer security & OS lab, DKU
printf (%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s);
Secure Coding
Viewing memory at any location (1/4)
\x08\x48\x01\x10 are the four bytes of the target address.
In C language, \x10 in a string tells the compiler to put a hexadecimal value 0x10 in the current position. The value will take up just one byte.
Without using \x, if we directly put "10" in a string, the ASCII values of the characters ’1’ and ’0’ will be stored.
%x causes the stack pointer to move towards the format string.
30Computer security & OS lab, DKU
printf (“\x08\x48\01\x10 %x %x %x %x %s");
If user_input is “ \x08\x48\x01\x10 %x %x %x %x %s”, thenprintf ("\x08\x48\x01\x10 %x %x %x %x %s");
Secure Coding
Viewing memory at any location (2/4)
31Computer security & OS lab, DKU
If user_input is “ \x08\x48\x01\x10 %x %x %x %x %s”, thenprintf ("\x08\x48\x01\x10 %x %x %x %x %s");
Return address
Saved EBP
user_input
…
Addr. of the format string
Return addr
…
Return address
Saved EBP
%s...%x%x
0x10014808
…
Addr. of the format string
Return addr
…
main()stackframe
http://www.cis.syr.edu/~wedu/Teaching/cis643/LectureNotes_New/Format_String.pdf
main()stackframe
printf()stackframe
printf()stackframe
Pointer(starts here)
Secure Coding
Viewing memory at any location (3/4)
Basically, we use four %x to move the printf()’s pointer towards the address that we stored in the format string. Once we reach the destination, we will give %s to print(), causing it to print out the contents in the memory address 0x10014808.
32Computer security & OS lab, DKU
Secure Coding
Viewing memory at any location (4/4)
%x is used to advance the printf() pointer.
The key challenge in this attack is to figure out the distance between the user_input[] and the address passed to the printf() function. ● How many %x are required?
● Using trial and error, we check how many %x are needed to print out
0x10014808.
● Here we need 5 %x format specifiers, indicating 4 %x and 1 %s.
33Computer security & OS lab, DKU
Secure Coding
Change Program’s Data using %n specifier
%n specifier writes the number of characters that should have been written so far into the address of the variable you gave as the corresponding argument
34Computer security & OS lab, DKU
unsigned int bytes;
printf (“%s%n\n”, argv[1], &bytes); printf (“Your input was %d characters long\n”, bytes);
$ ./format_bug2 “Some random input”
Some random input
Your input was 17 characters long
int i;
printf ("12345%n", &i);Value of variable i is 5
Secure Coding
The use of %n format specifier in C
Lengthhh: For integer types, causes printf to expect an int-sized integer argument which was promoted from a char.
l: For integer types, causes printf to expect a long-sized integer argument.
ll: For integer types, causes printf to expect a long long-sized integer argument.
[root@redhat]# ./fmt_eg3
hello
hello
hello
hello
hello
c=, s=6, i=6, l=6, ll=6
35Computer security & OS lab, DKU
/* fmt_eg3.c */
main( ) {char c;short s;int i, j;long l;long long ll;
printf("hello %hhn\n", &c);printf("hello %hn\n", &s);printf("hello %n\n", &i);printf("hello %ln\n", &l);printf("hello %lln\n", &ll);printf("c=%c, s=%d, i=%d, l=%ld, ll=%ld\n",
c, s, i, l, ll);}
Secure Coding
The use of %n format specifier in C
%n: Print nothing, but write number of characters successfully written so far into an integer pointer parameter.
[root@redhat]# ./fmt_eg4
hello1
hello12
hello123
hello1234
hello12345
s=7, i=8, j=9, l=10, ll=11
36Computer security & OS lab, DKU
/* fmt_eg4.c */
main( ) {short s;int i, j;long l;long long ll;
printf("hello1 %hn\n", &s);printf("hello12 %n\n", &i);printf("hello123 %n\n", &j);printf("hello1234 %ln\n", &l);printf("hello12345 %lln\n", &ll);printf("s=%d, i=%d, j=%d, l=%ld, ll=%ld\n",
s, i, j, l, ll);}
Secure Coding
The use of %n format specifier
%[width][.precision][length]type
width: specifies a minimum number of characters to output, and is typically used to pad fixed-width fields in tabulated output, where the fields would otherwise be smaller, although it does not cause truncation of oversized fields. A leading zero in the width value is interpreted as the zero-padding flag mentioned above.
%u: Print decimal unsigned int.
37Computer security & OS lab, DKU
/* fmt_eg5.c */
main() {int i=0;int j=0, k;
printf("%10u%n", 1, &i);printf("%100u%n", 1, &j);printf("%12345u%n", 1, &k);printf("\n");printf("i=%d, j=%d, k=%d\n", i, j, k);
}
[root@redhat]# ./fmt_eg5
1
1
1
i=10, j=100, k=12345
Secure Coding
The use of %n format specifier
can write number of characters successfully written so far into an character pointer parameter.
[root@redhat]# ./fmt_eg6
41, 41, 41, 41,
1 1
1
1
10, 20, 40, 80,
38Computer security & OS lab, DKU
/* fmt_eg6.c */
main() {unsigned char foo[4];int i;
memset(foo, '\x41', 4);for (i=0; i<4; i++)
printf("%4x, ", foo[i]);printf("\n");
printf("%16u%n", 1, &foo[0]);printf("%32u%n", 1, &foo[1]);printf("%64u%n", 1, &foo[2]);printf("%128u%n", 1, &foo[3]);
printf("\n");for (i=0; i<4; i++)
printf("%x, ", foo[i]);printf("\n");
}
Secure Coding
The use of %n format specifier
[root@redhat FormatString]# ./fmt_eg7
foo = 4, 8
1 1
foo = 10, 31
39Computer security & OS lab, DKU
/* fmt_eg6.7 */
main(){
unsigned char foo[2];
printf("foo = %x, %x\n", foo[0], foo[1]);printf("%16u%n %32u%n", 1, &foo[0], 1, &foo[1]);printf(“\n”);printf("foo = %x, %x\n", foo[0], foo[1]);
}
Use %hn to modify the var variable two bytes at a time.
If the first %hn gets value x, and before the next %hn, t more characters are printed, the second %hn will get value x+t.
Secure Coding
The use of %n format specifier
Use %hn to modify the var variable two bytes at a time.
40Computer security & OS lab, DKU
Secure Coding
What can we achieve using format string vulnerabilities?
Attack 1 : Crash program
Attack 2 : Print out data on the stack
Attack 3 : Change the program’s data in the memory
Attack 4 : Change the program’s data to specific value
Attack 5 : Inject Malicious Code
41Computer security & OS lab, DKU
Secure Coding
What is the format string vulnerability
A correct implementation
printf (“%s”, “hello”);
printf(“%x %x”,0xffffffff, 0x00000000);
A wrong implementation
char buf[MAX_BUF];
printf(argv[1]);
printf(buf);
printf(“%x %x”);
printf (“%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s”);
42Computer security & OS lab, DKU
Secure Coding
Countermeasures: Developer
43Computer security & OS lab, DKU
Avoid using untrusted user inputs for format strings in functions like printf, sprintf, fprintf, vprintf, scanf, vfscanf.
Secure Coding
Countermeasures: Compiler
Compilers can detect potential format string vulnerabilities
44Computer security & OS lab, DKU
• Use two compilers to
compile the program: gcc and clang.
• We can see that there is
a mismatch in the
format string.
• With default settings,
both compilers gave
warning for the first printf().
• No warning was
given out for the
second one.
Secure Coding
Countermeasures: Compiler
45Computer security & OS lab, DKU
• On giving an option -wformat=2, both compilers give warnings for both printf statements
stating that the format string is not a string literal.
• These warnings just act as reminders to the developers that there is a potential problem but
nevertheless compile the programs.
Secure Coding
Countermeasures: Compiler
Many compilers can statically check format strings and produce warnings for dangerous or suspect formats.● In the GNU Compiler Collection, the relevant compiler flags are, -Wall,-
Wformat, -Wno-format-extra-args, -Wformat-security, -Wformat-nonliteral, and -Wformat=2.
<source: Options to Request or Suppress Warnings>
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Warning-Options.html#Warning-Options
● Most of these are only useful for detecting bad format strings that are known at compile-time.
● If the format string may come from the user or from a source external to the application, the application must validate the format string before using it
46Computer security & OS lab, DKU
Secure Coding
Countermeasures
Address randomization: Makes it difficult for the attackers to guess the
address of the address of the target memory ( return address, address of the
malicious code)
Non-executable Stack/Heap: This will not work. Attackers can use the return-
to-libc technique to defeat the countermeasure.
StackGuard: This will not work. Unlike buffer overflow, using format string
vulnerabilities, we can ensure that only the target memory is modified; no other
memory is affected.
47Computer security & OS lab, DKU
- 48 -
Summary, Q & A
Software bug / Flaw
Software vulnerability
Buffer overflow vulnerability
Integer overflow/underflow
Type conversion errors
Format string bugs http://null-byte.wonderhowto.com/how-to/security-oriented-c-tutorial-0x14-format-string-vulnerability-part-i-buffer-
overflows-nasty-little-brother-0167254/
How SW vulnerabilities work
Countermeasures
Computer Security & OS Lab, DKU
• What types of threat are related to this lecture?‒ Consider the STRIDE model !