Starting from assignment 2, I'll using a kali linux VM to do the homework.
- Assignmnet 2
Question 1 - File Permissions
Following the steps:
Daddy told me about cool MD5 hash collision today. I wanna do something like that too!
ssh firstname.lastname@example.org -p2222 (pw:guest)
Login pwnable's server through port 2222:
Checking the file permissions:
The answers to the questions:
Which user owns the file
col_pwnowns the file col.
Which files in this directory can the users in the group
col.ccan be read by the users in group
col. Current user is in the group
col, so the current user can
r-x, which are reading and executing to the file.
col.chas been set that everyone is readable(
What does the SUID flag do?
SUIDis a type of special permissions, files with
SUIDpermission could be excuted as if the owner is excuting it.
sindicates the file has
In my opinion,
SUIDis normally used by the command, for example: while a none root user change its password, he need to use command
passwd, which has
SUIDpermission to modify the password file(
What exactly does
-r-sr-x---tell us about the file
col? Be sure to explain who is allowed to do what.
-r-sr-x---, the first
-tells us it is a file.
For the owner of the file:
r-sis the permissions the owner has, means
SUID, allow other user execute it with the owner's permission.
For the users in group
col: they have
r-xpermission, which is
For current logged in user col: The current user is in the group
col, so he can
For other users(root not included): no permission allowed
The following pictures I found at http://www.csit.parkland.edu/~smauney/csc128/permissions_and_links.html and https://pamirwebhost.com/check-linux-file-permissions-with-ls/ are very helpful with leaning the linux file permissions:
Question 2 - Basics of C
Create the source file by using
vi flag.c and paste the code into the file:
Then save the file (
Compile the source code by
gcc flag.c -O ex_flag, compile and save the binary to
ex_flag and finally, execute it:
So for the questions:
What is the flag?
The program outputs
Here's your HINT, and the
flag = HINT.
What command(s) did you use to compile and run this program?
gccto compile the source code. After compiling it, the output file will automatically has the execute permission, so I execute using
Question 3 - Basics of Computer Memory
What I understand about memory:
in a X86 32-bit system, every process has a 32-bit long virtual address and it has an offset compared to the physical address.
in a X86 32-bit system, virtual address space is allocated to two part, kernel space and user space. Kernel space normally takes up to 1G space at high address, the rest is user space which is 3G.
Each process has the following memory space:
On linux system, we can take a look at the memory map:
And at the bottum of the memory is stack:
What I understand about endianness:
Endianness defines how a operating system read memory, from high address to low address or the oppsite order.
Answers to the questions:
What is the number 3735928559 in hexadecimal form?
0xDEADBEEF (I used an online converter)
Suppose this number was stored as an integer (i.e.,
inttype) in little-endian format at memory address 0x12345678. Fill in the following memory map showing where each byte is stored. If the value is unknown/not relevant, leave it as
First of all, little-endian means the last byte of the data is stored at the lowest address. In terms of
0xDEADBEEF, the least significant is
EF(the last). Because the number is stored at memory address
0x12345678, the start of the memory is
0x12345678(lowest address). So,
EFshould be placed at address
Address | Value ------------------------- ... | 0x12345674 | 0x?? 0x12345675 | 0x?? 0x12345676 | 0x?? 0x12345677 | 0x?? 0x12345678 | 0xEF 0x12345679 | 0xBE 0x1234567a | 0xAD 0x1234567b | 0xDE
Question 4 - Collision Challenge
First login the server:
ssh email@example.com -p2222
After login, I checked the directory using
ls, I find that there's a file called flag, it's possible where the flag is. My mission is to access the file. Then I checked flag file's permission using
ls -l .
So, flag is owned by col_pwn. Before I tried other stuff, I checked if my current user is on the sudoer list using
sudo cat flag.
But I'm not a sudoer. I have a new idea while dealing with sudo, on January 26, 2021, someone found sudo has a buffer overflow bug, which is exploitable by any user on the machine. So, I look this up on Google and find this article https://www.sudo.ws/alerts/unescape_overflow.html. Here's a test to check if the machine has the bug:
To test whether your version of sudo is vulnerable, the following command can be used:
sudoedit -s /
A vulnerable version of sudo will either prompt for a password or display an error similar to:
sudoedit: /: not a regular file
A patched version of sudo will simply display a usage statement, for example:
usage: sudoedit [-AknS] [-a type] [-C num] [-c class] [-D directory] [-g group] [-h host] [-p prompt] [-R directory] [-T timeout] [-u user] file ...
If the sudoers plugin has been patched but the sudo front-end has not, the following error will be displayed:
sudoedit: invalid mode flags from sudo front end: 0x20002
Here's what i find:
And the OS has been patched.
Next, I opened col.c to see the code using
vi col.c :
So, the question became how to make
0x21DD09EC equal to
After reviewing the
check_password() function, it takes the char input, force convert to int, copy it to the location of pointer
ip, then add them together like numbers. From the notice, I know the input is 20-bytes long. And one int takes up 4 bytes, so it's 20/4=5 numbers I need know.
Now I convert
0x21DD09EC to decimal(
568134124) to figure out the 5 numbers. However, 568134124 cannot be divided by 5.
So, I just take the integer part
113626824 and mutiply it with 4 (I also could set the first 4 number as 113626825, the rest is the same) ,
113626824 * 4 = 454507296. Now I have 4 numbers, the rest value would be the fifth number.
568134124 - 454507296 = 113626828. Check if this is correct,
113626824 * 4 + 113626828 = 568134124.
Now I have the 5 numbers:
113626824 - 113626824 - 113626824 - 113626824 - 113626828
In hex format:
0x06C5CEC8 0x06C5CEC8 0x06C5CEC8 0x06C5CEC8 0x06C5CECC
Finally, we input the numbers like the course website(https://whisperlab.org/introduction-to-hacking/lectures/collision):
Surprisingly, the answer is wrong:
I stucked here, so I googled. In this article https://0xrick.github.io/pwn/collision/#Exploitation, it says that the system is little-endian, I'm not sure where this is come from. I did not find anything related to this. So, I use a python program to check if the system is little-endian.
python -c "import sys;print(sys.byteorder=='little')"
And it is little-endian:
So, I need to reverse the input and try again:
Eventually, I have the flag:
Flag: daddy! I just managed to create a hash collision :)
Question 5 - bof Challenge
The challenge asks me to download 2 files, so I did. And it seems
bof is a executable file, so I give it excute permission and run it:
nc pwnable.kr 9000 is running the same program:
The next step is to analysis the source code, I use vim to see the code,
func() then exit, the logic is in function
func(). It has an integer input
key, then compare the key with
0xcafebabe. Before comparison, the program requires a std input from keyboard and save it to a 32 bytes char variable
overflowme, so it's possible to overflow variable
overflowme and write the data (
0xcafebabe) to the address where variable
key is. This will make the varibale
key equal to
0xcafebabe and calls
system("/bin/sh") then enter a new bash. (
gets() function in C language does not validate the memory, it just wirte everything it gets to the memory address)
I'll try to get the exploit on my local kali linux and then use it on pawnable.kr's server. This time, I'll only use gdb to debug the program, but I could also use a gun program on kali linux to debug it. In order to debug c program with GDB, I need to re-compile
bof.c with flag
gcc -g3 -m32 bof.c -o new_bof .
-g3 means compile full debug information to the binary(It's ok to use g3, because it's a small program, while debug complex program, -g is much preferred).
-m32 means compile it to 32-bit binary.
But it did not work:
It seems that I don't have
stdio.h header, and this is impossible on a linux machine with gcc. So, I googled the error:
ok, I need to install 32-bit library manully. Kali linux use apt to manage the packages, so I only need to
apt-get install gcc-multilib to install mulilib.
Then run gcc to compile it again, and it worked just fine:
Great! GDB is not installed too:
After install GDB, I can finally debug the program:
Then I use
run to start the program and try something random just to play with it.
I take a look at the source code, I understand I need to set a breakpoint at the comparison to check the value in
key. (it's just partial code in the picture)
Now run the program, I put a long string to overflow it:
So, the key's value is replaced with
0xffffd180, I tried again without overflow:
Now I know the buffer overflow could work on this program. So, I use an online tool genrate a string(https://wiremask.eu/tools/buffer-overflow-pattern-generator/) which is very easy to use on buffer overflow. What I used here is
I could use the string to find where is target place.
I know it overflows the varibable at the start of
Ab . Next is to find the content of variable
key, then I know the place to overflow key's data.
I learned to print the key as a sequence of 4 characters on the class tutorial notes.
The bold words are where key is. Now I can set any value I want to key.
So, the expoit string is
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6A + \xbe\xba\xfe\xca.
Since it doesn't matter what content is in the overflow variable, so I replace the long string with one char
Now I have the overflow string, so I'll use a python script to help me input it:
(python -c "print 'q'*52 +'\xbe\xba\xfe\xca'"; cat) | nc pwnable.kr 9000
This pythin script will input the data to pwnable.kr's 9000 port. It's like running a local program
./bof. The difference is piped the data to a remote server.
Finally, I have the user
col's shell and use it to get the flag.
And the flag is
daddy, I just pwned a buFFer :)