hw1 (1)

Upload: rmwarora

Post on 18-Jan-2016

9 views

Category:

Documents


0 download

DESCRIPTION

hw1

TRANSCRIPT

  • Ruchika Gupta cs161-cb

    Spring 2013 Paul Pearce

    Dis W 10-11 CS 161 - HOMEWORK 1 Problem 1 Line 26-

    Flaw: The scanf procedure call allows for buffer overflow if the user enters data longer than expected input. Fix: Put bound checks to prevent input that is too long. So, for example we can do:

    scanf("%32s: %256s -> %32s", publisher.name, content, to);

    Line 12-

    Flaw: It is possible that malloc can return null. In this case, using buf can cause a null pointer exception. Fix: Check to make sure that buf is not null prior to using it. Line 14-

    Flaw: Once again, the size of the input is not being checked. If it is too large it can cause a buffer overflow. Buffer overflow can generate other security vulnerabilities. Fix: Put in bounds checks.

    Flaw: We do not check that sender.name and msg contain expected input. If they dont, they can possibly invoke dangerous functions. Fix: We should do a regex check to ensure that sender.name and msg contain expected content. For instance, we could check that they are strings with alphanumeric characters.

    Flaw: dst can contain just about anything including certain flags such as l and any address. Fix: Once again, we can do a regex check to ensure that the dst is as expected and doesnt contain other flags, commands etc. Line 16-

    Flaw: This line is subject to format string vulnerabilities. If there is things like %n in buf, the attacker can get control over the system. Fix: Make sure that both arguments do not contain %.Also, instead of using fprintf we can use a safer print such as sprintf. Line 1-

    Flaw: debug has not been initialized Fix: Initialize debug to be 0. Problem 2

    (a) I will use the fourth, first, and second gadgets: xorl %ecx, %ecx //register %ecx now contains 0 addl $42, %ecx //register %ecx now contains 42 movl %ecx, %eax //register %eax now contains 42

  • Ruchika Gupta

    (b) B:0x1eg4cafe

    C:0x1eg4face D: 0x1eg4f00d Initially, %ebp points to A. Now we execute leave so %esp points to A. We pop off %ebp so %ebp points to the sfp value and %esp points to B. Then we pop off address at rip and put it in %eip making it the next instruction to be executed, so in this the first gadget will execute. Since we popped off content at B, %esp points to C. Now within the gadget there is a return. So the instruction at C is popped off, moving %esp to D, and C is put into %eip. Thus now second gadget will execute. The third gadget will execute in similar fashion.

    (c) B: 0x1ffa4b28 C: 0x1ffa4b28 D:0xbfdecae0 E: 0xbfdecaf0 Notes: leave => mov1 %ebp %esp

    pop1 %ebp ret => pop1 %eip

    Initially, ebp points to A. Now we execute leave so esp points to A. We pop off ebp so ebp points to the sfp value and esp points to B. Then we pop off address at rip and put it in %eip making it the next instruction to be executed, so in this case system will execute. Due to previous pop, esp points to C. We enter systems prologue. Ebp is pushed onto stack and then both esp and eb p point to B. We access the argument at an offset of 8 from ebp so we access D. Thus at D we should put the argument we want system to use. Now in leave we pop ebp off the stack so esp points to C. Now we pop off address at C, in this case system, and put it in eip so system is the next to execute. Now %esp points to D. System is now executing so we go through prologue: we put ebp on the stack and now ebp and esp point to C. We get the argument at an offset off 8 from C which is at E so we should put second argument at E. Now to leave we pop ebp of the stack so esp points to D. The next instruction we would pull off from D.

    (d) B:0x1ffa4b28 #address to system (*) C:0x1eg4dead #address of our pop gadget D:0xbfdecae0 #address of our argument to system(*) E: 0x1ffa4b28 #address to system(**) F: 0x1ffa4b28 #address to system(***) G:0xbfdecaf0 #address of our argument to system(**) H:0xbfdecaf8 #address of our argument to system(***)

  • Ruchika Gupta

    Note: As we can tell from the end of the previous parts note, if we want to execute system a third time, the address for system would need to be stored at D but we need D to store the argument to the first system call. We cant possibly store two different things in the same place. Thus, we need to have a different tactic when trying to call system three times. Instead of doing two system calls in a row we will sacrifice our second call to system with something that will help us reposition our stack pointer (%esp). We must use a gadget. Of the gadgets we have in (a) the most useful seems to be the third one. A pop will help us move %esp. We replace our second system call with the address of this gadget. This gadget at C gets popped off the stack and executed. %esp is at D. When the pop executes %esp is now at E. Then in return the address at E gets puts into the instruction pointer and here we can put our second call to system. We are now in the same position as c so we interleave the last two system calls in the same way. As we can see the gadget was necessary in letting us chain third system call.

    (e) Address Space Layout Randomization. Randomize where the instructions such as system are stored by choosing random offsets of memory locations at which to place preexisting code when restarting the machine.

    Cost: This takes up extra computing time. As mentioned on the end of the second page of an article1 on address randomization, debugging and supporting randomized executables can be much more difficult.

    Limitations: The addresses cannot feasibly be truly random for attackers and there is only so much granularity one can achieve. Attackers can still probe around with the same system and find patterns to possibly determine parts of the layout. Also

    Canry. After the rip, put in a canary, a randomly chosen 32 bit number, and check to make sure it is the same before using rip. If someone overflows it you can detect that there is a problem.

    Cost: Every type you call a procedure you have to generate/put in a new canary on the stack. Every time you return, you have to doublecheck the canary. Since, you can have many procedure calls and returns this can add a noticeable amount of extra time just for checking.

    Limitations: A canary can help detect a simple buffer overflow but if someone knows it exists they can ensure not overwriting the canary on a buffer overflow. For instance, one can figure out its value and rewrite original on top but still overwrite rip on the stack.

    Use heap. We can store return addresses in random locations on the heap and then on the stack instead of having a rip, you could have a pointer to the heap and grab the return address of the heap. A buffer overflow will no longer overwrite the return address but the pointer to the heap and since the address will be outside the heap range we can detect it.

    Cost: The execution of instructions will be much more complex maintaining state on the stack as well as the heap.

    Limitations: There are probably ways that attackers can modify the heap and chain things together still but it is likely to be more complicated.

    External Source: 1. http://cseweb.ucsd.edu/~hovav/dist/asrandom.pdf

    http://cseweb.ucsd.edu/~hovav/dist/asrandom.pdf

  • Ruchika Gupta

    Problem 3

    (a) Human Factors - When humans think they are protected they will feel they no longer the need to protect themselves as much. Also, humans cant enter the password at light speed thus allowing other humans to see what ones password is. Know your threat model Initially, the threat model was keyloggers but now the threat model has changed. It is now other people who can physically see the cursor on the screen of whoever is entering his/her password.

    (b) Complete mediation: It is important to check access to every object. In this case, since an HTTPS connection to Google is allowed someone can access something they should not be able to access by going around paying for the service. Instead, the airline should have blocked access to 3rd-party sites to ensure complete mediation.

    (c) Security through obscurity Just because, the default code is not openly announced does not mean it is safe to use. Potential invaders have the incentive to find that code and unless its private it wont be safe.

    (d) Least privilege: any application should only be granted the minimum access it needs to successfully complete its job. This reduces the applications scope of harm. The flashlight application does not need to know location, phone call state, or have full network access to provide all its functionalities, so such privileges should not be granted. Human factors- For an average person looking to download the application he or she is likely to not read through all the notifications while downloading an app so is unlikely to change the default privileges granted to the application.

    Problem 4 The code is not memory safe. The while loop keeps incrementing j until the separation character is found but if the separation character is not found it will eventually make an incorrect memory access beyond the scope of s[]. Replace the while line with the following modification to ensure we only check until the end of the array: while(s[j] != sep && j

  • Ruchika Gupta

    Iteration 2: Lets propagate up some requirements. Also, we already know trivially that j