CS4630 Spring 2021 quizzes



quiz for week 1

Answer the following questions which are based on the lecture material for this week.

Using the distinction we made between viruses and worms in lecture, classify the following:

Question 1 (0.5 pt) (see above)

a screensaver program that automatically emails itself to everyone in the contact list of whoever runs it

also accepted last option because of ambiguity of how it runs; generally, we'd consider such things a worm.

Regrade request
Question 2 (0.5 pt) (see above)

a Microsoft Word file containing macros (scripting supported by Microsoft Word) that modifies other Microsoft Word files to contain the same macros

Regrade request
Question 3 (0.5 pt) (see above)

a program distributed with the installer for a free game that injects ads in webpages

Regrade request
Question 4 (0.5 pt) (see above)

a program that, when run by a user on a corporate network, installs a copy of itself to every machine that user can remote desktop into and which injects ads in webpages

Regrade request
Question 5 (0.5 pt) (see above)

a program that is installed by visiting a malicious webpage that exploits a bug in some webbrowsers that records the keystrokes of the current user

Regrade request
Question 6 (2 pt)

Consider the following x86-64 assembly snippet in AT&T syntax:

movq $0x400000, %rax
movq $0x480, %rbx
movq $0x100, %rcx
movb (%rax, %rbx), %cl
addq $1, %rcx

or the same snippet rewritten in Intel syntax:

mov    rax,0x400000
mov    rbx,0x480
mov    rcx,0x100
mov    cl,BYTE PTR [rax+rbx*1]
add    rcx,0x1

After this runs the value of %rcx will be equal to _______?

Regrade request

The following questions are about how the Linux x86-64 calling convention would apply to the function foo in

struct pair {
    int a;
    int b;
};

void foo(struct pair w, int x, int y, double z);

To help answer these questions, some possible strategies include:

Question 7 (1 pt) (see above)

The argument w will be passed:

I should have written (((long) w.b << 32) | (unsigned int) w.a) or similar to prevent sign extension of w.a causing the upper bits to be wrong; so accepted both the almost-right answer and none of the above

Regrade request
Question 8 (1 pt) (see above)

The argument x will be passed:

  1. also accepted this answer, to account for students who thought w did not use %rdi, in which case %edi would be correctr register for x

Regrade request
Question 9 (1 pt) (see above)

The argument z will be passed:

Regrade request
Return to course pageReturn to index 

quiz for week 2

Answer the following questions which are based on the lecture material for this week.

Question 1 (2 pt)

In x86-64, there are at least two ways to encode addl %ecx, %eax (Intel syntax: add EAX, ECX). One is 01 c8 (writing as a list of byte values in hexadecimal). What is another?

(You may want to refer to the Intel manuals' reference for the add instruction: encoding summary or page 133 135 [corrected late 14 Feb] of this PDF.)

Answer:
Key: /0?3\s*[cC]1/
Regrade request

Consider the following ELF program header as dumped by objdump ([...] represents parts of the output of objdump being omitted for brevity)

a.out:     file format elf64-x86-64
a.out
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x0000000000401090

Program Header:
[...]
    LOAD off    0x0000000000000000 vaddr 0x0000000000400000 paddr 0x0000000000400000 align 2**12
         filesz 0x0000000000000528 memsz 0x0000000000000528 flags r--
    LOAD off    0x0000000000001000 vaddr 0x0000000000401000 paddr 0x0000000000401000 align 2**12
         filesz 0x0000000000000225 memsz 0x0000000000000225 flags r-x
    LOAD off    0x0000000000002000 vaddr 0x0000000000402000 paddr 0x0000000000402000 align 2**12
         filesz 0x0000000000000180 memsz 0x0000000000000180 flags r--
    LOAD off    0x0000000000002e10 vaddr 0x0000000000403e10 paddr 0x0000000000403e10 align 2**12
         filesz 0x0000000000000228 memsz 0x0000000000000230 flags rw-
[...]
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
   RELRO off    0x0000000000002e10 vaddr 0x0000000000403e10 paddr 0x0000000000403e10 align 2**0
         filesz 0x00000000000001f0 memsz 0x00000000000001f0 flags r--
[...]
Question 2 (2 pt) (see above)

Based on the program headers, how many bytes of possibly-executable machine code are in the executable? (Write your answer as a base-10 number of bytes like 123 or a base-16 number of bytes prefixed by 0x like 0x7b.)

Answer:
Key: /0[xX]0*225|549/
Regrade request
Question 3 (2 pt) (see above)

Based on the program headers, what is the minimum address to which part of the executable should be loaded? Write your answer as a base-16 number.

Answer:
Key: /(?:0[xX])?0*(?:400000)/
Regrade request
Question 4 (2 pt)

In lecture, we discussed how Vienna edited its code and data in memory before copying it into an executable to account for each executable having Vienna at a different location (depending on the size of the executable).

We mentioned that some of these modifications could have been avoided by replacing assembly instructions that encode an address directly with ones that encode an address relative to the current address. This would have further simplified Vienna's infection code.

Which of the following modifications to code and data that Vienna makes (to customize itself for a particular executable) could have been avoided using this strategy? Select all that apply.

  1. needs to go a varying number of bytes, depending on where new code added

  2. still need to replace original executable bytes and restore them for correctness

Regrade request
Question 5 (2 pt)

Each of the following are features of ELF executables. Which of them would prevent Vienna's strategy of appending its code to the executable file and adding a jump to the executable to that code from working on an ELF executable (without Vienna doing substantial additional work to "fix" the executable file)? Select all that apply.

  1. no change to how Vienna works, so long as it doesn't overwrite this information

  2. no change to how Vienna works. (The intent of this question was about the purpose information, not anything specifying restrictions on read/write/execute. Dropped because of the ambiguity)

  3. Vienna would need to make other changes

Regrade request
Return to course pageReturn to index 

quiz for week 3

Answer the following questions which are based on the lecture material for this week.

Question 1 (3 pt)

We mentioned several techniques in lecture by which virus-like malware can embed itself in executables.

Which, if any, of the following techniques would likely be detected by anti-virus software that checked whether file lengths of executables changed? (In the options below, a segment refers to something like a ELF segment, like is specified by a LOAD operation in an ELF program header.) Select all that apply.

  1. not an executable file

Regrade request
Question 2 (2 pt)

In lecture we mentioned that the CIH virus inserted its part of its code into "cavities" it found in an executable, and then had some code it inserted reassemble that code in memory and jump to the reassembled code. Which, if any, of the following were advantages of this approach over jumping to the location of the cavities? Select all that apply.

  1. some students observed that CIH uses space in the header to store its cavity index. I did not consider this part of the CIH "approach" we described in the question, but accepted either answer for this option as a result

Regrade request
Question 3 (2 pt)

We discussed in lecture how executables often contain unused space. Probably a compiler and/or linker could avoid this unused space. Which, if any, of the following would be likely properties of the resulting executable (when compared to an executable generated without avoiding unused space)? Select all that apply.

  1. should have been phrased "machine code in the resulting executable that uses ..." for greater clarity

Regrade request
Return to course pageReturn to index 

quiz for week 4

Question 1 (1 pt)

Suppose a Linux program set one of the entries of its global offset table to point to a function foo while it was running. Which of the following would be likely outcomes of this? Select all that apply.

  1. foo itself unchanged

  2. if GOT entry was used for a standard library function, all calls are likely to use that GOT entry

  3. if GOT entry was used for a standard library function, all calls are likely to use that GOT entry

Regrade request
Question 2 (2 pt)

Suppose a virus wanted to edit a dynamic linking stub like

0000000000001050 <puts@plt>:
    1050:       f3 0f 1e fa             endbr64 
    1054:       f2 ff 25 75 2f 00 00    bnd jmpq *0x2f75(%rip)        # 3fd0 <puts@GLIBC_2.2.5>

(or in Intel syntax):

0000000000001050 <puts@plt>:
    1050:       f3 0f 1e fa             endbr64 
    1054:       f2 ff 25 75 2f 00 00    bnd jmp [RIP + 0x2f75]        # 3fd0 <puts@GLIBC_2.2.5>

so that calls to puts@plt would call the virus code stealthily.

If it replaced the jmpq instruction with a call to the virus code and make it unlikely that the virus would be noticed, then which would be the best way (of the choices below) to end the virus code?

  1. half-credit; the jump instruction is relative to the current program counter

  2. would not run the actual standard library function, likely to cause program to behave badly

Regrade request

To evade detection by pattern-matching like malware often tries to change their code each time they make a copy. Some of these techniques are readily detectable by regular-expression matching.

Suppose we start with self-replicating malware code matched using a signature for the following code:

0000000000000000 <loop>:
   0:   48 31 24 c6             xor    %rsp,(%rsi,%rax,8)
   4:   48 ff c8                dec    %rax
   7:   7d f7                   jge    0 <loop>

(or in Intel syntax:

0000000000000000 <loop>:
   0:   48 31 24 c6             xor    [rsi+rax*8],rsp
   4:   48 ff c8                dec    rax
   7:   7d f7                   jge    0 <loop>

)

Which can be matched using the flex pattern \x48\x31\x24\xc6\x48\xff\xc8\x7d\xf7

Recall that in flex:

Question 3 (2 pt) (see above)

Suppose to evade this kind of detection, the malware adds between 1 and 4 (chosen randomly) nops between the xor %rsp,(%rsi,%rax,8) and dec %rax instructions. Assume all the inserted nops are one-byte instructions encoded using the byte 90 (which is written as hexadecimal). Which of the following is a pattern that could match the modified malware without causing a very large number of false positives? Select all that apply.

  1. matches \x90 (90 -- nop), likely many false positives; doesn't match inserted nops

  2. only matches with c6 byte of xor instruction is omitted (happens to encode (%rsi,%rax,8)), which will break it.

Regrade request
Question 4 (2 pt) (see above)

Suppose to evade this kind of detection, the malware changes the register %rsp in the xor instruction to %rbx, %rcx, %rdx, or %rbp (chosen at random). Which of the following would be the best pattern for matching the modified malware without causing a very large number of false positives?

[Note that you can use an assembler to help answer this question.]

  1. the 24 byte includes the rgister number for %rsp. It also encodes some other information, so this pattern will match some additional types of instructions, but it's the only choice that matches the variants specified, and it doesn't match much extra.

Regrade request
Return to course pageReturn to index 

quiz for week 5

In lecture, we divided self-replicating malware that varies their machine code into three categories, which we will define as follows for the following two questions:

Question 1 (1 pt) (see above)

Suppose antimalware software works by periodically scanning the memory of loaded programs for fixed strings (known to be present in malware). Which of these types of malware are likely to evade this antimalware software? Select all that apply.

I was thinking about looking for signatures based on machine code, but if we're thinking about data used at runtime, they'd likely be decoded and that's a potential avenue even for metamorphic malware. So accepted either answer for C.

Regrade request
Question 2 (1 pt) (see above)

Suppose rather than relying on signatures based on machine code, uses signatures based on the file accesses made by programs. Which of these types of malware are likely to evade this antimalware software? Select all that apply.

accepted "metamorphic" on the theory that metamorphic malware's mutations might add bogus file accesses, but that would not be typical

Regrade request
Question 3 (2 pt)

We mentioned in lecture that some malware uses stealth or rootkit-style techniques in an attempt to remain hidden from antimalware software and/or system administrators. Suppose, as part of this stealth strategy, such a malware overrode the operating system's function for listing the contents of directories. Which of the following would be the most likely behavior of the overriden function?

Regrade request
Question 4 (2 pt)

Sometimes malware computes a hash of its own machine code and data and compares it to a stored value. In which of the following circumstances would this check likely fail? Select all that apply.

Regrade request

Consider the following C function:

int example() {
    char address[1000];
    char name[100];
    int points;
    ReadInputInto(name);
    points = LookupPointsFor(name);
    ReadInputInto(address);
    return Process(name, points, address);
}

where the ReadInputInto copies a value from the input into its argument. If the value input is too long, then ReadInputInto will exceed the bounds of the buffer given as an argument.

Suppose when this is compiled, the compiler places:

where "the stack pointer" refers to the stack pointer's value in the function's body, such as just before the calls to scanf.

Question 5 (2 pt) (see above)

An attacker who controls the input for address could change the value for points by putting their desired value for points _____ bytes into the input for address. (Write your answer as a base 10 number.)

Answer:
Key: 1100
Regrade request
Return to course pageReturn to index 

quiz for week 6

Answer the following questions about the lecture material for this week.

For the following questions, consider the following C function which is vulnerable to stack smashing:

int read_number() {
    char buffer[20];
    int ch; unsigned i = 0;
    while (1) {
        ch = getchar();
        if (ch == '\n' || ch == EOF) break;
        buffer[i] = ch; 
        i += 1;
    }   
    buffer[i] = '\0';
    return atoi(buffer);
}

which is compiled to the following (annotated) assembly:

read_number:
        /* save old values of three registers used for temporaries
           and local variables */
        pushq   %r12
        pushq   %rbp
        pushq   %rbx

        /* i (%ebx) = 0 */
        xorl    %ebx, %ebx

        /* allocate 32 bytes on the stack for buffer */
        subq    $32, %rsp  /* Intel syntax: sub RSP, 32 */

        /* buffer (%r12) = stack pointer */
        movq    %rsp, %r12 /* Intel syntax: mov R12, RSP */
        jmp     loop_entry

loop_top:
        /* end of loop: */
        /* buffer[i] = ch; */
        movb    %al, (%r12,%rbx)
        /* i += 1 */
        addq    $1, %rbx
loop_entry:
        /* start of loop */
        call    getchar@PLT /* ch (%eax) = getchar() */

        /* if (ch == '\n' (10) || ch == EOF)  break */
        cmpl    $10, %eax
        je      loop_end
        cmpl    $-1, %eax
        jne     loop_top

loop_end:
        /* buffer[i] = '\0' */
        movl    %ebx, %ebp      /* Intel syntax: mov EBP, EBX */
        movb    $0, (%rsp,%rbp) /* Intel syntax: mov [RSP + RBP], 0 */

        /* atoi(buffer) */
        movq    %r12, %rdi      /* Intel syntax: mov RDI, R12 */
        call    atoi@PLT

        /* deallocate stack space, restore saved registers */
        addq    $32, %rsp       /* Intel syntax: add RSP, 32 */

        /*  restore previously saved values */
        popq    %rbx
        popq    %rbp
        popq    %r12
        ret
Question 1 (2 pt) (see above)

If the stack smashing technique discussed in lecture were used to exploit this function, then the attacker's malicious code would execute:

Regrade request
Question 2 (2 pt) (see above)

If the stack smashing technique discussed in lecture were used to exploit this function, then the attacker would make their pointer to the malicious code start at byte number ____ of input, considering the first byte of input to be byte number 0. (Write your answer as a decimal number.)

Answer:
Key: 56

32 bytes allocated for buffer + 8 * 3 bytes for saved registers

Regrade request
Question 3 (2 pt)

Which of the following would be the most useful information that might be leaked by an information leak vulnerability for an attacker attempting to perform a buffer overflow despite stack canaries?

  1. might contain the stack canary value

I decided to drop this quesiton giving everyone credit for it. The other answers are useful for avoiding address randomization (or the difficulty of predicting the location of things on the stack in general) if you already have an arbitrary memory overwrite, but not for defeating stack canaries in particular. I understand, however, the interpretation that that might give one the ability to sidestep the existence of stack canaries in the first place, and I should've explicitly mentioned doing a stack smashing attack.

Regrade request
Question 4 (2 pt)

Consider the following C function ReadAndProcess:

void ReadAndProcess(FILE *in) {
    const unsigned int MAX_DATA_ITEMS = 10000;
    unsigned int size;
    unsigned long tag;
    int *data = malloc(MAX_DATA_ITEMS * sizeof(int));
    fread(&size, 4, 1, in);
    unsigned int data_count = size / sizeof(int);
    if (data_count > MAX_DATA_ITEMS) {
        fprintf(stderr, "TOO BIG!\n");
        abort();
    } else {
        fread(&tag, 8, 1, in);
        fread(&data[0], size - 8, 1, in);
        DoSomethingWith(tag, data, data_count);
    }
}

(The C standard library fread(p, S, N, i) reads S*N bytes from the file i into the buffer pointed to by p.)

This function is intended to read data in the following binary format:

But if the compiler performs arithmetic in the code above using 4-byte unsigned ints, then this code may attempt to overflow the heap-allocated buffer data. Give an example of a value for size the attacker could choose to trigger the overflow. Write your answer as a base-10 number.

Answer:
Key: /^(?:0|1|2|3|4|5|6|7)$/
Regrade request
Return to course pageReturn to index 

quiz for week 7

Answer the following questions about the lecture material for this week.

Question 1 (2 pt)

Suppose a buffer vulnerable to overflow is stored in a struct like the following:

struct vulnerable_struct {
    char buffer[128];
    long *current;
};

void vulnerable(struct vulnerable_struct *s) {
    scanf("%s", s->buffer);  // <-- CAN OVERFLOW s->buffer 
    s->current = atol(s->buffer);
}

(atol converts a string to an long; if the string contains extra text after the integer (e.g. "102cf"), it returns the integer at the beginning.)

One way an attacker can exploit the buffer overflow is by overwritin the adjacent value of s->current. Which of the following values could be useful [not in original question, but should have been: to place in s->current] as part of turning this exploit into something that would trigger execution of code of the attacker's choice? Select all that apply.

Also accepted selecting everything. My intention was to ask specifically about values that would be useful to put into current, but what I wrote could easily be interpreted as asking about values that would be nice to know for the exploit overall.

Regrade request
Question 2 (2 pt)

In lecture we mentioned relocation read-only (RELRO), in which information filled in by the dynamic linker, like global offset tables and virtual function tables, is configured to be read-only immediately after the program loads. Which of the following would be prevented by RELRO? Select all that apply.

Regrade request
Question 3 (2 pt)

Suppose a prorgam supports multiple user interfaces. To implement this functionality, it chooses between several different sets of user interface functions based on a configuration parameter. Each user interface is represented by a struct containing pointers to relevant functions:

    struct ui_functions {
         /* this declares a field 'DisplayString' which is a pointer to
             function returning void and taking a const char * argument */
        void (*DisplayString)(const char *);
        void (*LocateFile)(const char*, const char *, int);
        ...
    };

A global variable points to the currently active set of functions:

    struct functions *current_ui_functions;

At program startup, the program allocates a new instance of this struct on the heap, initializes its function pointers based on a configuration file, and then sets current_ui_functions to point to that new instance of the struct.

After startup, the program would call particular functions using this global variable using code like:

    (current_ui_functions->DisplayString)(argument);

(which could also be written ((*current_ui_functions).DisplayString)(argument).)

Suppose that in order to prevent buffer overflow attacks from interfering with this, the program arranged for guard pages to be placed on either side of the pointer current_ui_functions. Which of the following operations would these guard pages be likely to prevent? Select all that apply.

  1. would need guard pages around the struct to which current_ui_functions points

wrote current_functions in place of current_ui_functions in the part of the question text about guard page originally; I'm assuming studnets figured out what was meant.

Regrade request
Question 4 (2 pt)

Suppose we have discovered that a program contains the following gadgets at the following addresses:

Suppose also that 0x300000 is the address of a writeable global variable.

Suppose we wanted to use these gadgets to call a function void foo(int x, int y) located at address 0x200000 as if it were called like:

foo(0x42, 0x43);

Which of the following are ROP chains (written with the overwritten return address first, followed by the other values that would be afterwards in memory) which would achieve this? Select all that apply.

  1. jumps to *%rsi

Regrade request
Return to course pageReturn to index 

quiz for week 8

Answer the following questions about the lecture material for this week.

For the following questions, suppose a program uses a function pointer to perform the following call:

(*function_pointer)(attacker_controlled_long, attacker_controlled_string);

on an x86-64 system and an attacker can control the value of function_pointer, and the argument types for this function pointer are long and char*. Assume the program being attacked is configured so that all writeable memory is not executable.

For each of the following questions, the attacker's goal is to run a return-oriented programming chain by selecting appropriate values for function_pointer, attacker_controlled_int, and attacker_controlled_string.

Question 1 (2 pt) (see above)

Which of the following gadgets would be most useful to point function_pointer to in order to achieving the attacker's goal?

  1. useful for attacker --- jump to %rdi, but still need additional gadget to adjust the stack pointer for the rest of the ROP chain

Regrade request
Question 2 (2 pt) (see above)

Suppose function_pointer points to the gadget pushq %rdi; movq %rsi, %rsp; ret. Then the attacker should set attacker_controlled_long and attacker_controlled_str to:

Regrade request

Consider the following extract from objdump output on an executable compiled and linked to fully support ASLR.

000000000000116b <foo>:
    116b:       50                      push   %rax
    116c:       8b 3d ba 2e 00 00       mov    0x2eba(%rip),%edi        # 402c <x>
    1172:       ff 15 98 2e 00 00       callq  *0x2e98(%rip)        # 4010 <f>
    1178:       5a                      pop    %rdx
    1179:       c3                      retq   

000000000000117a <quux>:
    117a:       50                      push   %rax
    117b:       48 8b 35 9e 2e 00 00    mov    0x2e9e(%rip),%rsi        # 4020 <stderr@@GLIBC_2.2.5>
    1182:       48 8d 3d 7b 0e 00 00    lea    0xe7b(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1189:       e8 a2 fe ff ff          callq  1030 <fputs@plt>
    118e:       31 c0                   xor    %eax,%eax
    1190:       5a                      pop    %rdx
    1191:       c3                      retq   

The function foo calls runs a function using a global variable f that is a function pointer.

Since the application fully supports ASLR, when it is loaded, the actual memory addresses will not be the addresses chosen above, but will be selected randomly.

Suppose we discover that when quux calls puts@plt that:

Question 3 (1 pt) (see above)

Based on the information above, what is the address of the function pointer f used by foo? Write your answer as a hexedecimal number. If not enough information is provided, write unknown and explain in the comments.

Answer:
Key: 0x502010
Regrade request
Question 4 (1 pt)

In lecture, we discussed how an attacker might be able to take advantage of a bug that lets them write past the end of an object allocated on the heap with a particular kind of malloc/free implementation. In this attack, the malloc/free implementation kept a doubly linked list in free regions of the heap, and the attacker could overwrite the next and prev pointers for the following free region of the heap using their heap object overflow. As a result, the malloc/free implementation would write a value chosen by the attacker to a memory location chosen by the attacker.

Which of the following would prevent this attack strategy? Select all that apply.

  1. attacker can still overwrite far enough to reach the end

Regrade request
Return to course pageReturn to index 

quiz for week 9

Answer the following questions about the lecture material for this week

Consider the following C snippet:

struct Clipboard {
    /* this declares a pointer to function called 'get'
        returning a const char* and taking a
        struct Clipboard* argument
     */
    const char * (*get)(struct Clipboard*);
    /* this declares a pointer to function called 'set'
       taking a two arguments: a struct Clipboard*,
        and a const char*
     */
    void (*set)(struct Clipboard *, const char *);
    ...
};

struct Clipboard *current_clipboard;



...

void ReadToClipboard() {
    char *buffer = malloc(1024);
    fgets(buffer, sizeof(1024), stdin);
    (current_clipboard->set)(current_clipboard, buffer);
    free(buffer);
}

Suppose an attacker can trigger a use-after-free bug that erroneously frees the object current_clipboard points to and then calls ReadToClipboard(). Suppose the attacker can also arrange for buffer to be allocated memory at the same location as current_clipboard.

Question 1 (2 pt) (see above)

Where in their input (that will be read with fgets) should the attacker place the address of code they would like run?

Regrade request
Question 2 (2 pt)

Which of the following would prevent use-after-free vulnerabilities? Select all that apply.

  1. still have pointers to the function pointers on the heap which can be changed

  2. newly allocated object can write useful data there

Regrade request
Question 3 (2 pt)

In lecture, we mentioned that the C standard library functions strncpy and strncat can be nonintuitive to use as replacements for strcpy (string copy) and strcat (string concatenate) with bounds checking.

For example code, if an attacker could supply input of arbitrary length as the string attacker_input to code like:

char buffer[1024];
strncpy(buffer, attacker_input, sizeof buffer)
puts(buffer);

Then the attacker would likely be able to ___. Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 10

Answer the following questions about the lecture material for week 10.

Question 1 (2 pt)

In lecture, we discussed how a "fat pointer" representation is one strategy to add bounds checking to existing C code.

Suppose we have such a "fat pointer" represented as:

struct MyPtr {
    char *pointer;
    char *minimum;
    char *maximum;
}

as was shown in lecture. Code like

p[10] = 1;

would be converted to something like:

CHECK(p->pointer + 10 >= minimum && p-> pointer + 10 <= maximum);
p->pointer[10] = 1;

(where CHECK(x) is some function that will trigger a crash if x is false).

Similarly, we could convert code like:

memcpy(p, "ABCD", 4);

to code like:

CHECK(_________);
memcpy(p->pointer, "ABCD", 4);

where the blank in CHECK contains:

was originally miskeyed

Regrade request

Consider the following vulnerable C function:

char *vulnerable_copy(char *attacker_input) {
    char *copy = malloc(sizeof(attacker_input) + 1);
    char *in = &attacker_input[0];
    char *out = &copy[0];
    do {
        *out = *in; /* (1) */
        in += 1;    /* (2) */
        out += 1;   /* (3) */
    } while (*in != '\0');
    return copy;
}

Because sizeof(attacker_input) is the size of a pointer attacker_input (8 bytes on x86-64) and [should have been included, but wasn't due to typo: not] the length of string pointed to by attacker_input, this code will go out of bounds of the heap object copy.

Question 2 (2 pt) (see above)

Which of the following techniques we discussed in lecture would prevent this from being exploited by an attacker? Select all that apply.

Regrade request
Question 3 (2 pt) (see above)

For which of the following techniques we discussed in lecture would we expect the actual code run to execute the line marked (1) to include some sort of bounds or validity check? Select all that apply.

  1. check done on pointer arithmetic (2)

Regrade request
Question 4 (2 pt)

Which of the following are advantages of using symbolic execution to produce test cases over using random testing to produce test cases? Select all that apply.

Regrade request
Return to course pageReturn to index 

quiz for week 11

Answer the following questions about the lecture material for this week.

Question 1 (2 pt)

Consider the following function:

int example(int a, int b, int c) {
    if (a > 10) {
        if (b > 10) {
            mystery1(a);
            if (c > 10) {
               mystery2(b);
            } else if (c == 10) {
               mystery3(b);
            }
        }
    }
    if (b == 20) {
        mystery4(a);
    }
}

If we were testing this function via coverage-guided fuzzing, than the fuzz tester would maintain a list of discovered distinct test cases, where a test case was considered distinct if it covered different path than any other test case.

Suppose this list initially contained:

a = 0, b = 0, c = 0
a = 0, b = 20, c = 0
a = 50, b = 50, c = 10

Which of the following variations would be considered new distint test cases? **Select all that apply.*

  1. same path as 50, 50, 10

  2. same path as 0, 0, 0

Regrade request
Question 2 (dropped)

Consider the following C snippet:

int mystery;

void bar(char *p) {
    if (p[0] == 'A') {
        free(p)
    } else {
        strcat(p, "more example");
    }
}

void foo() {
    char *q = malloc(1024);
    strcpy(q, "example");
    bar(q);
    strcat(q, "another example");
    printf("q = %s\n", q);
    free(q);
}

Suppose a static analysis tool warns that a use-after-free may occur when foo() runs, but in the program in which this appears, that does not happen for any possible input. The analysis determines that after bar is Which of the following changes to the static analysis tool would avoid this false positive? Select all that apply.

dropped due to error in question

Regrade request
Question 3 (2 pt)

In lecture we mentioned that constructing an information flow graph might be used to identify probable cases of SQL injection by seeing whether user input flows into a library call that accepts SQL code.

Consider the following (Python-like) pseudocode:

class_id = input()
order = input()
student_id = input()
q = 'SELECT * FROM registrations WHERE class = ' + class_id
if student_id != '':
    q += ' WHERE student_id = ?'
if order == 'id':
    q = q + ' ORDER BY registeration_id ASC'
elif order == 'applied_date' or order == 'enrolled_date':
    q = q + ' ORDER BY ' + order + ' ASC'
else:
    raise Exception("Invalid order")
sql_prepare_query(q)
...

Assuming we used the version of the analysis that did not consider control flow (e.g. a value being used as an if statement condition) to create an edge in the graph, this would detect the value passed to sql_prepare_query came from ___? **Select all that apply.**

  1. false positive: used when set to 'applied_date' or 'enrolled_date' so not exploitable

Regrade request
Question 4 (2 pt)

Consider a dynamic taint tracking system, which tracks, for every value, whether or not it is tainted. Suppose a malware author wanted to defeat this system by creating false positives causing the value x appear to be dependent on y even though it is not really. Which of the following are likely to achieve this goal, if converted to unoptimized assembly (so expressions like y * 0 are not optimized into 0, etc.)? Select all that apply.

  1. dynamic system will execute comparison

  2. y depends on x, x does not depend on y

Regrade request
Return to course pageReturn to index 

quiz for week 12

Answer the following questions about the lecture material for week 12.

Consider the following noncompiling Rust code snippet (where ... represents code omitted for brevity):

struct Student {
    name: String,
    courses: Vec<String>,
}

fn do_something_with(arg: HashMap<String, &Student>) {...}

fn example() {
    let mut first_student = Student {
        name: ..., courses: ...,
    };
    let mut students: HashMap<String, &Student> = HashMap::new();
    students.insert(String::from("Some Name"), &first_student); /* (A) */
    first_student.courses.push(String::from("CS1110")); /* (B) */
    do_something_with(students);
}

The Rust compiler will complain that this code violates the ownership and borrowing rules we discussed in lecture. Specifically, the line labelled (B) attempts to borrow the value first_student (to modify it by pushing onto its courses field) while it is being borrowed because of the line labelled (A) (to insert a reference to it into the HashMap).

(In the interest of helping you understand the Rust code above, this Rust code is approximately equivalent to this C++ code:

struct Student { string name; vector<string> courses; };

void do_something_with(map<string, const Student*> arg) {...}

void example() {
    Student first_student = ...;
    map<string, const Student*> students;
    students["Some Name"] = &first_student;
    first_student.courses.push_back("CS1110");
    do_something_with(students);
}

)

Question 1 (2 pt) (see above)

Does this compiler error represent a use-after-free bug that can occur when the above code is run in a particular way?

Regrade request
Question 2 (2 pt) (see above)

Which of the following would avoid this compiler error? Select all that apply.

  1. meant to write "values"; would move first_student into to the HashMap, so the access to first_student.courses would be disallowed

  2. meant to write "values"; would borrow Student object until the HashMap goes out of scope, so the access to first_student.courses would be disallowed

  3. (Accepted either answer for this question) when I wrote this question I thoguht that Rc<> allowed write access in general (doing proper checks at a runtime). Rc<> does allow writing, but it checks that there is exactly one reference, which wouldn't be true in the scenario above. Using Rc<RefCell> instead would work --- Rc<> would do reference counting, and RefCell<> runtime checking that there is exactly one writer a time. Rc<> doesn't do both because that would be extra overhead, violating Rust's "zero-overhead" philosophy.

Regrade request
Question 3 (2 pt)

Which of the following do Rust's compiler-enforced and standard-library-enforced safety rules ensure (in the absence of code explicitly marked unsafe or bugs in the standard library code or compiler)? Select all that apply.

  1. these can still happen, though Rust ensures they consistently result in a crash. (We didn't mention this in lecture.)

Regrade request
Question 4 (2 pt)

In lecture we mentioned the idea of privilege separation where an application is divided into multiple parts and some parts are sandboxed and run with fewer privilieges than the rest. Suppose we were adding privilege separation to a spreadsheet program. Which of the following components would be good candidates for functionality to implement in the less privilieged part of the spreadsheet program? Select all that apply.

  1. not likely to be a place that encounters malicious input and malicious code seems like it can cause anything to be opened anyways

  2. requires too many privileges to perform, can't really be sandboxed

Regrade request
Return to course pageReturn to index 

quiz for week 13

Question 1 (2 pt)

Which of the following scenarios would using chroot (which changes the effective root directory for a process) and running a program within the chroot environment without system administrator/root permissions be effective for? Assume that chroot is not used in combination with mount namespaces, bind mounts, etc. Select all that apply.

Regrade request
Question 2 (2 pt)

When using containers, such as implemented by docker using Linux's chroot and namespaces features, we would expect containers to protect against a compromised web server running in the container ____. Select all that apply.

Regrade request
Question 3 (2 pt)

Which of the following techniques for confining applications are likely to have the side effect of changing where the application's files are stored? Select all that apply.

Regrade request
Question 4 (2 pt)

According to the principles we discussed for permissions prompts in lecture, it would be best to ____.

Regrade request
Return to course pageReturn to index