Gallopsled / Gallopsled/pwntools
ssh_process::getenv ignores environment and returns wrong result
- Dominant language
- Python
- Stars
- 13.7k
- Forks
- 1.9k
- Avg merge
- 6d 23h
- Merged PRs (30d)
- 3
Description
### Introduction
`ssh_process::getenv` returns an incorrect result and ignores overridden environment variables with `process` or `system`.
### Example
With `script.py` containing:
```python
#!/usr/bin/env python2
from pwn import *
context.log_level = 'error'
user = 'narnia0'
host='narnia.labs.overthewire.org'
password='narnia0'
port=2226
s = ssh(user=user, host=host, password=password, port=port)
p = s.process('/narnia/narnia0', env={'FOO': 'BAR'})
print(hex(p.getenv('FOO')))
```
Running it gives:
```
$ ./script.py
1
```
### Possible fix
Using the following patch:
```diff
diff --git a/pwnlib/tubes/ssh.py b/pwnlib/tubes/ssh.py
index fd3a0307..bfcc4ab4 100644
--- a/pwnlib/tubes/ssh.py
+++ b/pwnlib/tubes/ssh.py
@@ -365,6 +365,7 @@ class ssh_process(ssh_channel):
script = ';'.join(('from ctypes import *',
'import os',
'libc = CDLL("libc.so.6")',
+ 'libc.getenv.restype = c_voidp',
'print os.path.realpath(%r)' % self.executable,
'print(libc.getenv(%r))' % variable,))
@@ -998,7 +999,7 @@ os.execve(exe, argv, env)
script = 'for py in python2.7 python2 python; do test -x "$(which $py 2>&1)" && exec $py -c %s check; done; echo 2' % sh_string(script)
with context.local(log_level='error'):
- python = ssh_process(self, script, tty=True, raw=True, level=self.level, timeout=self.timeout)
+ python = ssh_process(self, script, tty=True, env=env, raw=True, level=self.level, timeout=self.timeout)
try:
result = safeeval.const(python.recvline())
```
It returns:
```
$ ./script.py
0xffffefe5
```
### Notes
`ssh::getenv` needs similar patching for the result type (even though I'm not sure why it is used for, since it doesn't handle `argv` nor `env`).
Contributor guide
Assessment
This issue has not been assessed yet.