RSS
 

Archive for the ‘Exploitation’ Category

BlankMediaGames/Town Of Salem Data Breach (2020 Update)

06 Jan 2020

Overview

Town of Salem, a video game produced by BlankMediaGames was breached around 1 year ago on the 3rd of January 2019. It is reported that the total row count of that database that was breached is 8,388,894 which included some 7,633,234 unique email addresses.

Shortly after this breach in early 2019, hackers attacked and successfully cracked ~2.4 million passwords from the breach due to the weak MD5 encryption used. These cracked passwords were initially sold on the black market but were later released to the public on public forums.

Shockingly however, these passwords were never reset as part of the breach. Exactly one year later, a huge number of accounts are still working with the same credentials that were exposed during the breach. This has led to malicious bot writers creating Town of Salem bots with the only purpose of joining ranked games to:

  • intentionally game throw,
  • post hate speech/racial slurs,
  • spam chat to advertise,
  • impersonate other players in hopes of getting them falsely reported/banned,
  • afk / idle

Validating the breach (1 Year Later)

The cracked dump included 2,418,341 cracked entries in email:user:password format.
I decided to write a script to categorise these breached accounts. This script would iterate all user:password combinations and attempt to authenticate with the main Town of Salem game server at live4.tos.blankmediagames.com:3600. There is no login rate limiting in place so we could bruteforce the credentials at full throttle.

For each authentication attempt, one of the following responses was sent back by the server:

  • LOGIN_SUCCESS (successfully authentication)
  • LOGIN_FAILED (invalid credentials, password has been changed since breach)
  • LOGIN_BANNED (account is banned)
  • LOGIN_PASSWORD_CHANGE_REQUIRED (account has been marked as requiring a password change)

We are only interested in accounts that return LOGIN_SUCCESS as these are the only accounts that can be used by bot makers to ruin games.
Running a quick scan shows that many of the very first entries are still authenticating successfully.

Out of the 2,418,341 accounts scanned, it was discovered that as of 29/12/2019:

  • 961,874 accounts returned LOGIN_SUCCESS
  • 1,048,665 returned LOGIN_FAILED
  • 29,159 returned LOGIN_BANNED
  • 378,643 returned LOGIN_PASSWORD_CHANGE_REQUIRED

Responsible Disclosure

These findings were reported to BlankMediaGames via email.
Shapesifter13 (community manager) also reached out via Discord to help fast-track the process (thanks!):

Resolution

On 03/01/2020, the Town of Salem game servers were restarted for an update to address this issue:

It is important to note that it appears that BlankMediaGames were already addressing this issue coincidentally at the same time I was researching it and they moved a lot of accounts from the LOGIN_SUCCESS state to the LOGIN_PASSWORD_CHANGE_REQUIRED state. However, they did not initially address every exposed password I had access to in the first batch of database patches.

After the patches, previously cracked passwords now require the user to go through the password change recovery process.

Hopefully this resolves the problematic botting situation in Town of Salem for now.

Timeline

29/01/2019 – Obtain breach dump to perform analysis
01/01/2020 – Finish running script and gather results. Report to BMG via email.
03/01/2020 – BlankMediaGames perform database patch addressing majority of leaked passwords.
10/01/2020 – BlankMediaGames perform database patch addressing remaining leaked passwords.

 
3 Comments

Posted in Exploitation

 

Simple Buffer Overflow Example

23 Nov 2015

I’m posting this example because the current buffer overflow examples on the web are not that good. This is a step by step guide to how to exploit a program that is vulnerable to a buffer overflow attack.

The Code

This is the vulnerable code that we will be attacking. In this case, the call to strcpy is unsafe as the number of bytes that we copy into buffer (buf) is controlled by the caller which allows us to write more bytes than the size of the buffer (ie more than 1024 bytes).

Test Machine

Code was compiled on and exploited on a Ubuntu 14.04 64-bit machine.

Preparation

Compile the C program using gcc with the following flags:

This turns off stack execution and the stack protector which are anti-exploit features built into GCC. This particular example will require executing code from the stack.

We also compiled for 32 bit architecture for the purposes of this example.

Furthermore, we must turn off Address Space Layout Randomization (ASLR), a memory protection feature implemented in most modern UNIX operating systems. You can review all the different Ubuntu security features here.

To disable ASLR on Ubuntu:

You can also try this to spawn a shell with ASLR disabled:

Step by step guide

At this stage you should have compiled your program and have disabled ASLR. I decided to call my program exploit.

Start up gdb with your program like this:

Then run:

0

In this case we know strcpy returns a pointer to its destination (which is our buffer) and this pointer will be stored in EAX register after strcpy returns. So we want to put a breakpoint after strcpy returns so we can look at the values of the registers. So we note the next
address which in this case is: 0x080484c8

Now make a breakpoint by typing:

Okay, now let’s feed our program enough bytes to cause it to crash! Our buffer size is 1024 so let’s pick a number larger than that like 1050 to try and get a segmentation fault.
Type:

Note: Here we are using perl to easily print 1050 bytes. The character we are printing (raw) is the ‘\x90’ character which corresponds to the NOP assembly instruction. The NOP instruction is the no operation instruction which does nothing but take up a clock cycle. You will see why this is important later.
Now, gdb should stop at the breakpoint that we set earlier.

Now type:

1

This shows you the registers at this point in the code (right after strcpy has returned). So we know EAX will hold the result of strcpy which will be the pointer to our buffer! We always want to determine the location of our buffer in this type of buffer overflow attack. This is easily done with ASLR off but becomes more challenging when ASLR is left on (see ret2libc exploits).

Note down EAX address. EBP (Extended Base Pointer) is important too but you don’t need to remember it at this stage, just know that we will be overwriting the data at that address later on (EBP overwrite).
Press c to continue and to go past the breakpoint, the program should then end in a segmentation fault. The reason the program is seg faulting is because we have written enough bytes to overwrite the EBP (Extended Base Pointer). So when our C program returns, the IP (instruction pointer) points to the EBP which will contain \x90\x90\x90\x90.  The computer will try to execute assembly inst ructions at this address but will run into invalid instructions resulting in a crash.

Now we need to discover what the smallest number of NOP’s that can be fed to the program that still causes a segmentation fault is.
This is done by trial and error (answer depends on buffer size), simply run the following from gdb until you close in on an answer (obviously substituting in a number for ‘some num’):

Note: Actually its usually buffer size plus 12 bytes (ie 1024+12 bytes) on a typical x86 machine but this is not the case on all architectures. Note that this relies on the buffer variables position in the code. If there was an integer declared before the buffer with a size of 4 bytes then you would have to write 4 bytes more to reach the EBP and cause a segmentation fault.

In this case, we seg fault with exactly 1036 NOPs. So if we feed in 1035 NOPs, no segmentation fault occurs and all is fine.

Now its time for some calculations.
You want to write 1036 NOPs and then (after 1036 NOPs) you want to write 4 bytes (for the return address of EBP we wish to overwrite). Essentially, we want the IP to point to somewhere on the stack that has data that is controlled by us. So lets make it point to the buffer and add valid assembly instructions there which are then executed! This assembly code is our payload or shellcode (because it will spawn a shell).

Our 1036 bytes should also include our shellcode. The shell code we will use is 35 bytes long.

Shell code (standard x86 shellcode):

So, we have:

1036 – 35 = 1001 bytes

So we will write 1001 NOP’s! The reason we do this is simple. We are going to be jumping to a location on the stack (somewhere in our buffer). There is no need to be precise and jump to the exact starting byte of our shell code. We can utilise many NOP operations that are valid assembly instructions that do nothing and put our shellcode at the end of the buffer where it will eventually be executed. This leaves us some margin for error. The sequence of many NOPs is refereed to as a NOP sled.

So our payload now looks like this:

1001 NOPs + 35 bytes (shell code) + 4 bytes (return address which will overwrite EBP)
So now we will construct our almost complete payload, we have:

Now we used AAAA as a dummy address because it’s easy to see in gdb as it shows up as 0x41414141 and is 4 bytes large.
So go back to gdb and run your program using the above arguments like we have done before:

If prompted to start the program from the beginning, press yes .
gdb should have stopped at the breakpoint again. Press c to continue.
Now the program should have seg faulted. Inspect the address in which the program segfaulted. It should be 0x41414141 (which is the “AAAA”, our dummy address). If you see this then you have completed all steps correctly thus far, otherwise you did not.

The final step is to look into memory to find a good address (somewhere in the middle of the NOP sled is best) to use as our actual overwrite address.

Type:

This will show you the memory contents at the ESP (extended stack pointer). Now because we went past our breakpoint and let the program end, our base pointer would have been changed to some garbage. The stack pointer (ESP) still points to the
top of the stack though so that is why we are looking around there.

Press ENTER a few times to inspect memory at higher addresses.
Eventually you will see our 1001 NOPs, once you see our NOPs (series of 0x90 byte values), stop and pick one address that is within the NOP sled. Again, try to pick an address corresponding to somewhere near the middle of the NOP sled.

2

In this case I pick: 0xffffd0a0 which is nice because it is roughly in the middle of the NOP sled.

Finally, exit gdb by typing q and confirming.
We can now create our full payload:

Remember to reverse the address (due to little endianness). So FF FF D0 A0 becomes A0 D0 FF FF.

Make sure the address you picked doesn’t contain a null (0x00) or a space (0x20) as that could break your exploit. This is because a null would stop the assembly instructions from being executed and a space (0x20) would cause your argument to the program to be treated as two arguments.
Now in terminal, simply run your program (exploit) with that argument. And you should see a shell spawn!

Now run whoami, if you see root or another user then you successfully entered their account without a password which demonstrates the severity of the exploit.

3

Some things to note

If you manage to spawn a shell within gdb that could mess up the static addresses of various things so you might want to restart gdb in order to continue to inspect memory etc.

The addresses from gdb and terminal will be somewhat different. So if you pick an address right in the middle of the NOP sled your address could work right off the bat. If you pick an edge address (not a middle one) then it might not work but you can manually try and change the address. So if I pick an edge address in gdb of: 0xffffcf60 and then I go into terminal and it doesn’t work then I could try 0xffffcf80 , then maybe 0xffffcfff , then maybe 0xffffd100 . So I am just increasing the address until it works (ie going up in memory until I land within the NOP sled).

If there is something that is unclear in this guide or incorrect, please let me know!

 
No Comments

Posted in Exploitation