Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssh.process -- Cannot provide empty argv #2217

Closed
goreil opened this issue Jul 8, 2023 · 0 comments · Fixed by #2234
Closed

ssh.process -- Cannot provide empty argv #2217

goreil opened this issue Jul 8, 2023 · 0 comments · Fixed by #2234

Comments

@goreil
Copy link
Contributor

goreil commented Jul 8, 2023

The following code fails:

from pwn import *
s = ssh("bandit0", "bandit.labs.overthewire.org", 2220, "bandit0")
io = s.process([""], executable="/bin/sh")
io.interactive()
Traceback (most recent call last):
  File "<string>", line 110, in <module>
ValueError: execve: argv first element cannot be empty

We expect to open the process, but instead we get an error.

Debugging

The culprit is ssh.py:1034

os.execve(exe, argv, env)

os.execve disallows empty argv[0].

Proposed solution

Instead of using os.execve, we can use ctypes to call the execve function from libc. Below is a POC to call execve in python2 (python3 works the same but strings need to be replaced with bytes)

import ctypes
# All strings need to be replaced to bytes in python3
exe = "/bin/sh"
argv = []
envp = {"A":"A"}

def get_string_list(string_list):
    #Transform a list of bytes into a ctypes array of char pointers
    char_p_array = (ctypes.c_char_p * len(string_list))()
    for i, string in enumerate(string_list):
        char_p_array[i] = ctypes.c_char_p(string)

    return char_p_array

# Transform envp from dict to list
envp = [k + "=" + v for k,v in envp.items()]

c_exe = ctypes.c_char_p(exe)
c_argv = get_string_list(argv)
c_envp = get_string_list(envp)

# Call execve
libc = ctypes.CDLL(None)
libc.execve(c_exe, c_argv, c_envp)
@Arusekk Arusekk linked a pull request Jul 24, 2023 that will close this issue
peace-maker added a commit that referenced this issue Sep 14, 2023
* Fix bug at ssh.py:process() - empty argv[0] Error

Before this, process.py relied on `os.execve` which disallows an empty
argv or argv[0] == "".
This commit replaces `os.execve` with  `ctypes.CDLL(None).execve` to
call the C-Library function directly which allows an empty argv.

* Add #2225 to stable changelog

* Better ctypes syntax

* Add error message if cytpes.execve fails.

* Updata CHANGELOG.md

* ssh.py: python2 compatibility for os.environb

* Add check that "=" not in misc.normalize_argv_env

This check checks prevents the use of "=" in the
key of an environment variable, which is generally
impossible.

* ssh.process: Seperate cases for empty argv[0]

This commit seperates the cases for an empty argv[0]
from normal cases.

* ssh.py delete leftover comment

---------

Co-authored-by: Youheng Lü <90871590+Youheng-Lue@users.noreply.github.com>
Co-authored-by: Arusekk <arek_koz@o2.pl>
Co-authored-by: peace-maker <peace-maker@wcfan.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant