Repository: Gallopsled/pwntools

Issue:
ssh.process(..., cwd=) is broken
It looks like `cwd` is always set to `'.'` regardless of what the actual working directory is.

This breaks fetching core files with `CorefileFinder`.

```py
s=ssh('level1', 'io.netgarage.org', password='level1')

# set_working_directory creates a temporary working directory for all follow-up processes
s.set_working_directory()
# [*] Working directory: '/tmp/tmp.Nq3ANxhDBR'
io = s.process(['pwd'])
io.recvall()
# b'/tmp/tmp.Nq3ANxhDBR\n'
io.cwd
# '.'

# cwd= specifies a directory to work out of
io = s.process(['pwd'], cwd='/tmp')
io.recvall()
# b'/tmp\n'
io.cwd
# '.'
```


Discussion:
It looks like we do not pass `cwd=` to the `ssh_process()` invocation.  Separately, the variable is named `wd` for `ssh_channel`.  I'm in favor of renaming the `wd=` to `cwd=`, since it's unlikely anybody ever manually invoked `ssh_channel` or `ssh_process`.
I think this is kind of fixed on current dev, please check

Resolving patch:
diff --git a/pwnlib/tubes/ssh.py b/pwnlib/tubes/ssh.py
--- a/pwnlib/tubes/ssh.py
+++ b/pwnlib/tubes/ssh.py
@@ -57,7 +57,7 @@ class ssh_channel(sock):
     #: Command specified for the constructor
     process = None
 
-    def __init__(self, parent, process = None, tty = False, wd = None, env = None, raw = True, *args, **kwargs):
+    def __init__(self, parent, process = None, tty = False, cwd = None, env = None, raw = True, *args, **kwargs):
         super(ssh_channel, self).__init__(*args, **kwargs)
 
         # keep the parent from being garbage collected in some cases
@@ -68,9 +68,9 @@ def __init__(self, parent, process = None, tty = False, wd = None, env = None, r
         self.tty  = tty
         self.env  = env
         self.process = process
-        self.cwd  = wd or '.'
-        if isinstance(wd, six.text_type):
-            wd = packing._need_bytes(wd, 2, 0x80)
+        self.cwd  = cwd or '.'
+        if isinstance(cwd, six.text_type):
+            cwd = packing._need_bytes(cwd, 2, 0x80)
 
         env = env or {}
         msg = 'Opening new channel: %r' % (process or 'shell')
@@ -80,8 +80,8 @@ def __init__(self, parent, process = None, tty = False, wd = None, env = None, r
         if isinstance(process, six.text_type):
             process = packing._need_bytes(process, 2, 0x80)
 
-        if process and wd:
-            process = b'cd ' + sh_string(wd) + b' >/dev/null 2>&1; ' + process
+        if process and cwd:
+            process = b'cd ' + sh_string(cwd) + b' >/dev/null 2>&1; ' + process
 
         if process and env:
             for name, value in env.items():
@@ -841,8 +841,11 @@ def process(self, argv=None, executable=None, tty=True, cwd=None, env=None, time
             >>> sh = s.process(executable='/bin/sh')
             >>> str(sh.pid).encode() in s.pidof('sh') # doctest: +SKIP
             True
-            >>> s.process(['pwd'], cwd='/tmp').recvall()
+            >>> io = s.process(['pwd'], cwd='/tmp')
+            >>> io.recvall()
             b'/tmp\n'
+            >>> io.cwd
+            '/tmp'
             >>> p = s.process(['python','-c','import os; os.write(1, os.read(2, 1024))'], stderr=0)
             >>> p.send(b'hello')
             >>> p.recv()
@@ -1068,7 +1071,7 @@ def is_exe(path):
 
             script = 'echo PWNTOOLS; for py in python3 python2.7 python2 python; do test -x "$(which $py 2>&1)" && echo $py && exec $py -c %s check; done; echo 2' % sh_string(script)
             with context.quiet:
-                python = ssh_process(self, script, tty=True, raw=True, level=self.level, timeout=timeout)
+                python = ssh_process(self, script, tty=True, cwd=cwd, raw=True, level=self.level, timeout=timeout)
 
             try:
                 python.recvline_contains(b'PWNTOOLS')        # Magic flag so that any sh/bash initialization errors are swallowed
@@ -1151,7 +1154,7 @@ def system(self, process, tty = True, wd = None, env = None, timeout = None, raw
 
         Examples:
             >>> s =  ssh(host='example.pwnme')
-            >>> py = s.run('python3 -i')
+            >>> py = s.system('python3 -i')
             >>> _ = py.recvuntil(b'>>> ')
             >>> py.sendline(b'print(2+2)')
             >>> py.sendline(b'exit()')
@@ -1159,6 +1162,11 @@ def system(self, process, tty = True, wd = None, env = None, timeout = None, raw
             b'4\n'
             >>> s.system('env | grep -a AAAA', env={'AAAA': b'\x90'}).recvall()
             b'AAAA=\x90\n'
+            >>> io = s.system('pwd', wd='/tmp')
+            >>> io.recvall()
+            b'/tmp\n'
+            >>> io.cwd
+            '/tmp'
         """
 
         if wd is None:
@@ -1844,6 +1852,13 @@ def set_working_directory(self, wd = None, symlink = False):
             >>> _=s.set_working_directory(symlink=symlink)
             >>> assert b'foo' in s.ls().split(), s.ls().split()
             >>> assert homedir != s.pwd()
+
+            >>> _=s.set_working_directory()
+            >>> io = s.system('pwd')
+            >>> io.recvallS().strip() == io.cwd
+            True
+            >>> io.cwd == s.cwd
+            True
         """
         status = 0
 


Test patch: