Dawn Song
Vulnerability Analysis (IV): Program Verifjcation
Computer Security Course. Dawn Song Computer Security Course. Dawn Song
Slide credit: Vijay D’Silva
Vulnerability Analysis (IV): Program Verifjcation Slide credit: - - PowerPoint PPT Presentation
Computer Security Course. Dawn Computer Security Course. Dawn Song Song Vulnerability Analysis (IV): Program Verifjcation Slide credit: Vijay Dawn Song DSilva Program Verifjcation Dawn Song Program Verifjcation How to prove a
Dawn Song
Computer Security Course. Dawn Song Computer Security Course. Dawn Song
Slide credit: Vijay D’Silva
Dawn Song
Dawn Song
Dawn Song
Precondition: φ(x) Postcondition: ψ
Dawn Song
– fp points to a valid location in memory – fp points to a fjle – the fjle that fp points to contains at least 4 characters – …
1:int parse(FILE *fp) { 2: char cmd[256], *url, buf[5]; 3: fread(cmd, 1, 256, fp); 4: int i, header_ok = 0; 5: if (cmd[0] == ‘G’) 6: if (cmd[1] == ‘E’) 7: if (cmd[2] == ‘T’) 8: if (cmd[3] == ‘ ’) 9: header_ok = 1; 10: if (!header_ok) return -1; 11: url = cmd + 4; 12: i=0; 13: while (i<5 && url[i]!=‘\0’ && url[i]! =‘\n’) { 14: buf[i] = tolower(url[i]); 15: i++; 16: } 17: buf[i] = ‘\0’; 18: printf(“Location is %s\n”, buf); 19: return 0; } f( x) f( x)
φ(x ) ψ
Dawn Song
Precondition: φ(x) Postcondition: ψ
Dawn Song
1:int parse(FILE *fp) { 2: char cmd[256], *url, buf[5]; 3: fread(cmd, 1, 256, fp); 4: int i, header_ok = 0; 5: if (cmd[0] == ‘G’) 6: if (cmd[1] == ‘E’) 7: if (cmd[2] == ‘T’) 8: if (cmd[3] == ‘ ’) 9: header_ok = 1; 10: if (!header_ok) return -1; 11: url = cmd + 4; 12: i=0; 13: while (i<5 && url[i]!=‘\0’ && url[i]! =‘n’) { 14: buf[i] = tolower(url[i]); 15: i++; 16: } 17: buf[i] = ‘\0’; 18: printf(“Location is %s\n”, buf); 18: return 0; }
– buf contains no uppercase letters – (return 0) ⇒(cmd[0..3] == “GET “)
f( x) f( x)
φ(x ) ψ
Dawn Song
– Specifying what obligations caller has and what caller is entitled to rely upon
– if precondition is met at function’s entrance, – then postcondition is guaranteed to hold upon function’s return
Precondition: φ(x) Postcondition: ψ
Dawn Song
– Write down a precondition and postcondition for every line
– Use logical reasoning
– Each statement’s postcondition must match (imply) precondition of any following statement – At every point between two statements, write down invariant that must be true at that point
precondition for next one
f( x) f( x)
φ(x ) ψ
⇒
Dawn Song
We’ll take our example, fjx the bug, and show that we can successfully prove that the bug no longer exists.
1:int parse(FILE *fp) { 2: char cmd[256], *url, buf[5]; 3: fread(cmd, 1, 256, fp); 4: int i, header_ok = 0; 5: if (cmd[0] == ‘G’) 6: if (cmd[1] == ‘E’) 7: if (cmd[2] == ‘T’) 8: if (cmd[3] == ‘ ’) 9: header_ok = 1; 10: if (!header_ok) return -1; 11: url = cmd + 4; 12: i=0; 13: while (i<5 && url[i]!=‘\0’ && url[i]!=‘n’) { 14: buf[i] = tolower(url[i]); 15: i++; 16: } 17: assert(i>=0 && i <5); 18: buf[i] = ‘\0’; 19: printf(“Location is %s\n”, buf); 20: return 0; } f( x) f( x)
φ(x ) ψ F F T T T T F F
i = 0; i = 0; buf[i] = ‘\0’; buf[i] = ‘\0’; CRASH! CRASH! assert(i>=0 && i<5); assert(i>=0 && i<5); i++; i++; is(i<5 && url[i]!=‘\0’ && url[i]! =‘\n’)? is(i<5 && url[i]!=‘\0’ && url[i]! =‘\n’)?
Dawn Song
We’ll take our example, fjx the bug, and show that we can successfully prove that the bug no longer exists.
1:int parse(FILE *fp) { 2: char cmd[256], *url, buf[5]; 3: fread(cmd, 1, 256, fp); 4: int i, header_ok = 0; 5: if (cmd[0] == ‘G’) 6: if (cmd[1] == ‘E’) 7: if (cmd[2] == ‘T’) 8: if (cmd[3] == ‘ ’) 9: header_ok = 1; 10: if (!header_ok) return -1; 11: url = cmd + 4; 12: i=0; 13: while (i<5 && url[i]!=‘\0’ && url[i]!=‘n’) { 14: buf[i] = tolower(url[i]); 15: i++; 16: } 17: assert(i>=0 && i <5); 18: buf[i] = ‘\0’; 19: printf(“Location is %s\n”, buf); 20: return 0; } f( x) f( x)
φ(x ) ψ
1:int parse(FILE *fp) { 2: char cmd[256], *url, buf[5]; 3: fread(cmd, 1, 256, fp); 4: int i, header_ok = 0; 5: if (cmd[0] == ‘G’) 6: if (cmd[1] == ‘E’) 7: if (cmd[2] == ‘T’) 8: if (cmd[3] == ‘ ’) 9: header_ok = 1; 10: if (!header_ok) return -1; 11: url = cmd + 4; 12: i=0; 13: while (i<4 && url[i]!=‘\0’ && url[i]!=‘n’) { 14: buf[i] = tolower(url[i]); 15: i++; 16: } 17: assert(i>=0 && i <5); 18: buf[i] = ‘\0’; 19: printf(“Location is %s\n”, buf); 20: return 0; }
F F T T T T F F
i = 0; i = 0; buf[i] = ‘\0’; buf[i] = ‘\0’; CRASH! CRASH! assert(i>=0 && i<5); assert(i>=0 && i<5); i++; i++; is(i<5 && url[i]!=‘\0’ && url[i]! =‘\n’)? is(i<5 && url[i]!=‘\0’ && url[i]! =‘\n’)?
F F T T T T F F
i = 0; i = 0; buf[i] = ‘\0’; buf[i] = ‘\0’; CRASH! CRASH! assert(i>=0 && i<5); assert(i>=0 && i<5); i++; i++; is(i<4 && url[i]!=‘\0’ && url[i]! =‘\n’)? is(i<4 && url[i]!=‘\0’ && url[i]! =‘\n’)?
Bug Fixed!
Dawn Song
We’ll take our example, fjx the bug, and show that we can successfully prove that the bug no longer exists…
f( x) f( x)
φ(x ) ψ
1:int parse(FILE *fp) { 2: char cmd[256], *url, buf[5]; 3: fread(cmd, 1, 256, fp); 4: int i, header_ok = 0; 5: if (cmd[0] == ‘G’) 6: if (cmd[1] == ‘E’) 7: if (cmd[2] == ‘T’) 8: if (cmd[3] == ‘ ’) 9: header_ok = 1; 10: if (!header_ok) return -1; 11: url = cmd + 4; 12: i=0; 13: while (i<4 && url[i]!=‘\0’ && url[i]!=‘n’) { 14: buf[i] = tolower(url[i]); 15: i++; 16: } 17: buf[i] = ‘\0’; 18: printf(“Location is %s\n”, buf); 18: return 0; }
…So assuming fp points to a fjle that begins with “GET “, we want to show that parse never goes down the false assertion path. ut fjrst, we will need the concept of loop invariant. F F T T T T F F
buf[i] = ‘\0’; buf[i] = ‘\0’; CRASH! CRASH! assert(i>=0 && i<5); assert(i>=0 && i<5); i++; i++; is(i<4 && url[i]!=‘\0’ && url[i]! =‘\n’)? is(i<4 && url[i]!=‘\0’ && url[i]! =‘\n’)? i = 0; i = 0;
Dawn Song
– Must be true before every loop iteration
F F T T
i = 0; i = 0; buf[i] = tolower(url[i]); i++; buf[i] = tolower(url[i]); i++; is(i<5 && url[i]!=‘\0’ && url[i]! =‘\n’)? is(i<5 && url[i]!=‘\0’ && url[i]! =‘\n’)? A A C C B B
φ(i ) φ(i+1 ) φ(i) φ(i+1 )
Dawn Song
– Base Case: Prove true for fjrst iteration: φ(0) – Inductive step: Assume φ(i) at the beginning of the loop. Prove φ(i+1) at the start of the next iteration. φ(i) φ(i+1 )
Dawn Song
Try with our familiar example, proving that (0≤i<5) after the loop terminates: LOOP INVARIANT: LOOP INVARIANT:
/* φ(i) = (0≤i<5) */
φ(i) φ(i+1 )
/* φ(0) = (0≤0<5) */
Base Case: Inductive Step:
/* ⇒ (0≤i+1<5) at the end of the loop */ /* assume(0≤i<5)at the beginning of the loop */ /* for (0≤i<4), clearly (0≤i+1<5) */ /* (i=5) is not a possible case since that would fail the looping predicate */
F F T T T T F F
i = 0; i = 0; buf[i] = ‘\0’; buf[i] = ‘\0’; CRASH! CRASH! assert(i>=0 && i<5); assert(i>=0 && i<5); i++; i++; is(i<4 && url[i]!=‘\0’ && url[i]! =‘\n’)? is(i<4 && url[i]!=‘\0’ && url[i]! =‘\n’)?
/* ⇒ parse never fails the assertion */
Dawn Song
– Then we can conclude its postcondition holds and use this fact in our reasoning
– Can verify function f() by looking at only its code and the annotations on every function f() calls
transitively
– Makes reasoning about f() an almost purely local activity
Dawn Song
Dawn Song
– T
post-conditions – she doesn’t need to look at or understand his code
– Each module assigned to one programmer, and pre-/post- conditions are a contract between caller and callee – Alice and Bob can negotiate the interface (and responsibilities) between their code at design time
Dawn Song
– Must not make out-of-bounds memory accesses, deference null pointers, etc.
– Ex: when a pointer is dereferenced, there is an implicit precondition that pointer is non-null and in-bounds
Dawn Song
Dawn Song
Computer Security Course. Dawn Song Computer Security Course. Dawn Song
Dawn Song
Dawn Song
Dawn Song
Dawn Song
File 1 File 2 File 3 … File n User 1 read write
User 2 write write write
read … User m read write read write read Subjects Objects
Dawn Song
– Store column of matrix with the resource
– User holds a “ticket” for each resource – T wo variations
File 1 File 2 … User 1 read write
write write
… User m Read write write
Access control lists are widely used, often with groups Some aspects of capability concept are used in many systems
Dawn Song
– Associate list with each object – Check user/group against list – Relies on authentication: need to know user
– Capability is unforgeable ticket
– Reference monitor checks ticket
Dawn Song
Process P
Process Q User U Process R User U Process P Capabilty c,d,e Process Q Process R Capabilty c Capabilty c,e
Dawn Song
– Cap: Process can pass capability at run time – ACL: T ry to get owner to add permission to list?
– ACL: Remove user or group from list – Cap: T ry to get capability back from process?
– OS knows which data is capability – If capability is used for multiple resources, have to revoke all or none …
– If C → P → R, then revoke capability C by setting P=0
Dawn Song
– Administrator, PowerUser, User, Guest – Assign permissions to roles; each user gets permission
– Partial order of roles – Each role gets permissions of roles below – List only new permissions given to each role
Administrator Guest PowerUser User
Dawn Song
Individuals Roles Resources engineering marketing human res Server 1 Server 3 Server 2
Dawn Song
Subject Subject Reference Monitor Reference Monitor Object Object
Dawn Song
Dawn Song
Dawn Song
procedure withdrawal(w) // contact central server to get balance
// contact server to set balance
Dawn Song
Non-Language-Specifjc Vulnerabilities
// Part of a setuid program if (access("file", W_OK) != 0) { exit(1); } fd = open("file", O_WRONLY); write(fd, buffer, sizeof(buffer));
access(“fjle”, W_OK) Returns 0 if the user invoking the program has write access to “fjle” (it checks the real uid, the actual id of the user, as opposed to the efgective uid, the id associated with the process)
Y) Returns a handle to “fjle” to be used for writing only write(fd, bufger …) Writes the contents of bufger to “fjle”
Dawn Song
// Part of a setuid program if (access("file", W_OK) != 0) { exit(1); }
access(“fjle”, W_OK) Returns 0 if the user invoking the program has write access to “fjle” (it checks the real uid, the actual id of the user, as opposed to the efgective uid, the id associated with the process)
Y) Returns a handle to “fjle” to be used for writing only write(fd, bufger …) Writes the contents of bufger to “fjle” symlink(“/etc/passwd”, “fjle”) Creates a symlink from “fjle” to “/etc/passwd”. A symbolic link is a reference to another fjle, so in this case the attacker causes “fjle” (which they have privileges for) to point to “/etc/passwd”. The program then opens “/etc/passwd” instead of “fjle”.
// After the access check symlink("/etc/passwd", "file"); // Before the open, "file" points to the password database
fd = open("file", O_WRONLY); write(fd, buffer, sizeof(buffer));
Dawn Song
– Eg. symlink(“/etc/passwd”, “file”) – Bypasses the check in the code! – Although the user does not have write privileges for /etc/passwd, the program does (and the attacker has privileges for file, so they are allowed to create the symbolic link) – Time-Of-Check T
– Meaning of file changed from time it is checked (access()) and time it is used (open())
Dawn Song
Dawn Song
Dawn Song
Reference Monitor and Confjnement for Running Untrusted Code
We often need to run buggy/untrusted code:
– programs from untrusted Internet sites:
– old or insecure applications: ghostview, outlook – legacy daemons: sendmail, bind – Honeypots
– Can be implemented at many difgerent levels
Dawn Song
Sandbox Sandbox Sandbox Sandbox
Reference monitor Reference monitor
Dawn Song
Dawn Song
– Ability to access or modify a resource
– A system module should only have the minimal privileges needed for intended purposes
– Separate the system into independent modules – Each module follows the principle of least privilege – Limit interaction between modules
Dawn Song
– Grants permission to user ids – Owner, group, other
– Inherit from creating process – Process can change id
– Special “root” id
File 1 File 2 … User 1 read write
write write
… User m Read write write
Dawn Song
– Read, write, execute – Owner, group, other – Represented by vector of four octal values
– This privilege cannot be delegated or shared
grp
setid
Dawn Song
– Root can do anything
– Even though they only need to perform a small number of priviledged operations
– Privileged programs are juicy targets for attackers – By fjnding a bug in parts of the program that do not need privilege, attacker can gain root
Dawn Song
– Solution? – Drop privilege right after binding the port
– Even if attacker fjnds a bug in later part of the code, can’t gain privilege any more
– Setuid programming in UNIX
Dawn Song
– Read, write, execute – Owner, group, other – Represented by vector of four octal values
– This privilege cannot be delegated or shared
setid
Dawn Song
– Real user ID (RUID)
– Efgective user ID (EUID)
– fjle access and port binding
– Saved user ID (SUID)
Dawn Song
– ID=0 for superuser root; can access any fjle
– Inherit three IDs, except exec of fjle with setuid bit
– seteuid(newid) can set EUID to
– Several difgerent calls: setuid, seteuid, setreuid
Dawn Song
– Setuid – set EUID of process to ID of fjle owner – Setgid – set EGID of process to GID of fjle – Sticky
remove fjles, even if not owner
remove fjle in the directory
setid
Dawn Song
…; …; exec( ); RUID 25 SetUID program
…; …; i=getruid() setuid(i); …; …;
RUID 25 EUID 18 RUID 25 EUID 25
fjle
fjle Owner 18 Owner 25
read/write read/write
Owner 18
Dawn Song
Dawn Song
Dawn Song
Dawn Song
Dawn Song
Dawn Song
Dawn Song