Skip to content

Commit cff58e1

Browse files
authored
Allow to passthru kwargs on ssh.__getattr__ convenience function to fix SSH motd problems (#2517)
* Allow to passthru kwargs on `ssh.__getattr__` convenience function Instead of only passing the command arguments themselves to `ssh.system` when using `ssh.somecommand('args')`, allow to specify keyword arguments as well `ssh.somecommand('args', tty=False)`. * ssh: Don't allocate a tty for internal state fetching If the remote server is printing some motd agressively, this could lead to interpreting the motd instead of the requested output. * Use `ssh.system` internally too instead of deprecated `ssh.run` * Update CHANGELOG
1 parent e3a021d commit cff58e1

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ The table below shows which release corresponds to each branch, and what date th
7878
- [#2522][2522] Support starting a kitty debugging window with the 'kitten' command
7979
- [#2524][2524] Raise EOFError during `process.recv` when stdout closes on Windows
8080
- [#2526][2526] Properly make use of extra arguments in `packing` utilities. `sign` parameter requires keyword syntax to specify it.
81+
- [#2517][2517] Allow to passthru kwargs on `ssh.__getattr__` convenience function to fix SSH motd problems
8182

8283
[2507]: https://github.com/Gallopsled/pwntools/pull/2507
8384
[2522]: https://github.com/Gallopsled/pwntools/pull/2522
8485
[2524]: https://github.com/Gallopsled/pwntools/pull/2524
8586
[2526]: https://github.com/Gallopsled/pwntools/pull/2526
87+
[2517]: https://github.com/Gallopsled/pwntools/pull/2517
8688

8789
## 4.15.0 (`beta`)
8890
- [#2508][2508] Ignore a warning when compiling with asm on nix

pwnlib/tubes/ssh.py

+15-11
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ def __init__(self, user=None, host=None, port=22, password=None, key=None,
706706

707707
if self.sftp:
708708
with context.quiet:
709-
self.cwd = packing._decode(self.pwd())
709+
self.cwd = packing._decode(self.pwd(tty=False))
710710
else:
711711
self.cwd = '.'
712712

@@ -1140,7 +1140,7 @@ def run_to_end(self, process, tty = False, cwd = None, env = None, wd = None):
11401140
cwd = wd
11411141

11421142
with context.local(log_level = 'ERROR'):
1143-
c = self.run(process, tty, cwd = cwd, env = env, timeout = Timeout.default)
1143+
c = self.system(process, tty, cwd = cwd, env = env, timeout = Timeout.default)
11441144
data = c.recvall()
11451145
retcode = c.wait()
11461146
c.close()
@@ -1203,7 +1203,7 @@ def __getitem__(self, attr):
12031203
>>> print(repr(s['echo hello']))
12041204
b'hello'
12051205
"""
1206-
return self.run(attr).recvall().strip()
1206+
return self.system(attr).recvall().strip()
12071207

12081208
def __call__(self, attr):
12091209
"""Permits function-style access to run commands over SSH
@@ -1214,10 +1214,12 @@ def __call__(self, attr):
12141214
>>> print(repr(s('echo hello')))
12151215
b'hello'
12161216
"""
1217-
return self.run(attr).recvall().strip()
1217+
return self.system(attr).recvall().strip()
12181218

12191219
def __getattr__(self, attr):
1220-
"""Permits member access to run commands over SSH
1220+
"""Permits member access to run commands over SSH.
1221+
1222+
Supports other keyword arguments which are passed to :meth:`.system`.
12211223
12221224
Examples:
12231225
@@ -1228,6 +1230,8 @@ def __getattr__(self, attr):
12281230
b'travis'
12291231
>>> s.echo(['huh','yay','args'])
12301232
b'huh yay args'
1233+
>>> s.echo('value: $MYENV', env={'MYENV':'the env'})
1234+
b'value: the env'
12311235
"""
12321236
bad_attrs = [
12331237
'trait_names', # ipython tab-complete
@@ -1239,7 +1243,7 @@ def __getattr__(self, attr):
12391243
raise AttributeError
12401244

12411245
@LocalContext
1242-
def runner(*args):
1246+
def runner(*args, **kwargs):
12431247
if len(args) == 1 and isinstance(args[0], (list, tuple)):
12441248
command = [attr]
12451249
command.extend(args[0])
@@ -1248,7 +1252,7 @@ def runner(*args):
12481252
command.extend(args)
12491253
command = b' '.join(packing._need_bytes(arg, min_wrong=0x80) for arg in command)
12501254

1251-
return self.run(command).recvall().strip()
1255+
return self.system(command, **kwargs).recvall().strip()
12521256
return runner
12531257

12541258
def connected(self):
@@ -1348,7 +1352,7 @@ def update(has, total):
13481352

13491353
with context.local(log_level = 'ERROR'):
13501354
cmd = 'cat < ' + sh_string(remote)
1351-
c = self.run(cmd)
1355+
c = self.system(cmd)
13521356
data = b''
13531357

13541358
while True:
@@ -1369,7 +1373,7 @@ def update(has, total):
13691373
def _download_to_cache(self, remote, p, fingerprint=True):
13701374

13711375
with context.local(log_level='error'):
1372-
remote = self.readlink('-f',remote)
1376+
remote = self.readlink('-f', remote, tty=False)
13731377
if not hasattr(remote, 'encode'):
13741378
remote = remote.decode('utf-8')
13751379

@@ -1534,7 +1538,7 @@ def upload_data(self, data, remote):
15341538

15351539
with context.local(log_level = 'ERROR'):
15361540
cmd = 'cat > ' + sh_string(remote)
1537-
s = self.run(cmd, tty=False)
1541+
s = self.system(cmd, tty=False)
15381542
s.send(data)
15391543
s.shutdown('send')
15401544
data = s.recvall()
@@ -1592,7 +1596,7 @@ def upload_dir(self, local, remote=None):
15921596
remote_tar = self.mktemp('--suffix=.tar.gz')
15931597
self.upload_file(local_tar, remote_tar)
15941598

1595-
untar = self.run(b'cd %s && tar -xzf %s' % (sh_string(remote), sh_string(remote_tar)))
1599+
untar = self.system(b'cd %s && tar -xzf %s' % (sh_string(remote), sh_string(remote_tar)))
15961600
message = untar.recvrepeat(2)
15971601

15981602
if untar.wait() != 0:

0 commit comments

Comments
 (0)