Presentation is loading. Please wait.

Presentation is loading. Please wait.

Reflections on Trusting Trust by Ken Thomson

Similar presentations


Presentation on theme: "Reflections on Trusting Trust by Ken Thomson"— Presentation transcript:

1 Reflections on Trusting Trust by Ken Thomson
Vangelis Markatos

2 What is the problem? Ken Thomson described a hack
That allows attackers to enter a system The hack can not be found Even after source code inspection The hack just vanishes from the source code.

3 Assume we want to change the “login” daemon
So that when we log in it will ask for no password i.e. original login damenon: login = read_login( ); pass = read_password() If (matches(pass, pass_for_login(login)) return (TRUE); return (FALSE);

4 Assume we want to change the “login” daemon
Allow the hacker to log in without a password: login = read_login( ); pass = read_password(); If (login == “hacker1234”) return (TRUE); If (matches(pass, pass_for_login(login)) return (FALSE);

5 BUT This change would attract attention
Someone would read the source code sooner or later And notice the special case for login “hacker1234” Is it possible to do this hack Without leaving any traces in the source code of the “login” deamon Without any traces in the source code of any UNIX program? Without any traces in the source code of the UNIX kernel? If this is possible It will be something like a “super trojan” Non detectable by users Non detectable by the software company

6 Let us take a step back Can we teach a compiler new tricks?
c = next( ); If (c != ‘\\’) return(c); /* else it is “\” */ If (c == ‘\\’) /* \\ */ return(‘\\’); If (c == ‘n’) /* \n */ return(‘\n’); Can we teach a compiler new tricks? Can we hide these new tricks? Example: We will teach a compiler to recognize a new character in C: the “\v” character Check out the code that parses a string to print it Such as printf(“Hello World\n”) Or printf(“This is one backslash: \\”)

7 Teach the compiler to recognize a new character: `\v`
Let us add a new character: `\v` The vertical space printf(“add vertical space \v”); c = next( ); If (c != ‘\\’) return(c); /* else it is “\” */ If (c == ‘\\’) /* \\ */ return(‘\\’); If (c == ‘n’) /* \n */ return(‘\n’); If (c == ‘v’) /* \v */ return (‘\v’);

8 BUT The c compiler does not know the character ‘\v’
Thus we can not use it But ASCII character 11 is the vertical tab so `11` is the character we are looking for. c = next( ); If (c != ‘\\’) return(c); /* else it is “\” */ If (c == ‘\\’) /* \\ */ return(‘\\’); If (c == ‘n’) /* \n */ return(‘\n’); If (c == ‘v’) /* \v */ return (11);

9 Summary We started with a compiler (say A) which did not understand `\v` We added a new char: ‘\v’ We updated the compiler (say we created version B) To print `11` when it reads `\v` Now, let us compile compiler B with compiler A to get compiler C Which can compile programs that have the `\v` character So A does not understand `\v` B (and C) understand `\v` and print (11)

10 What if? What if we compile B with C and get compiler D?
c = next( ); If (c != ‘\\’) return(c); /* else it is “\” */ If (c == ‘\\’) /* \\ */ return(‘\\’); If (c == ‘n’) /* \n */ return(‘\n’); If (c == ‘v’) /* \v */ return (‘\v’); What if we compile B with C and get compiler D? B understands ‘\v’ will print 11 C understands ‘\v’ will print 11 D will understand ‘\v’ will print ‘\v’ Consider the piece of code to the right Does B compile it? Does C compile it? Does D compile it?

11 What? D compiles it! But Where is the `11`?
c = next( ); If (c != ‘\\’) return(c); /* else it is “\” */ If (c == ‘\\’) /* \\ */ return(‘\\’); If (c == ‘n’) /* \n */ return(‘\n’); If (c == ‘v’) /* \v */ return (‘\v’); D compiles it! But Where is the `11`? Gone! What if we need to change it? What if it were wrong? What can I do about it? Nothing! It is gone!

12 And now the interesting part starts!
Can we use this “disappearing” code to add backdoors? Backdoors that disappear from the source code? But which are always there? Can we?

13 Assume a compiler compile(s) char *s; {  }
compile(s) char *s; { if(match(s, “this is the login daemon program”)) { compile (“if(l == “hacker1234”)return”); return; } 

14 What can this compiler do?
“Bug” the code of login daemon Can you see the “bug” in the code of login daemon? No! BUT Careful inspection of the compiler code can expose this “bug” Can we “disappear” the code from the compiler code?

15 Let us “bug” the compiler itself
Let us say that the original trusted compiler of the system is “A” Let us make the following changes and get compiler “B” compile(s) char *s; { if(match(s, “this is the login daemon program”)) { compile (“if(l == “hacker1234”)return”); return; } if(match(s, “this is the C compiler running”)) { compile (<add the above if statement and this if statement in the compiler stream>); Let us compile “B” with “A” and get compiler “C”.

16 Now remove the “bugs” from the code
Let us go to the original source code of trusted compiler A No “bugs” – no hacks – no nothing Let us now compile “A” with “C” and call the result compiler “D” Is compiler “D” “bugged”? Is the source “A” bugged? (no) Is “C” bugged? (yes) Is “D” bugged? ………. (yes) So, the source code (“A”) is clean but the object code (“D”) is bugged!!! How can this be possible?

17 Summary We described a method which bugs a program without a trace in the source code So? KT suggests that these bugs are very difficult to find you need to trust the people who write the code


Download ppt "Reflections on Trusting Trust by Ken Thomson"

Similar presentations


Ads by Google