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

python3: tubes.ssh.run() - env(dict) - binary literals and strings in values are encoded incorrectly #1437

Closed
cameronotw opened this issue Feb 27, 2020 · 2 comments · Fixed by #1602
Assignees
Labels

Comments

@cameronotw
Copy link

Hi,

I tried to do write automagical solver of some wargame with use of pwntools. I got the problem when it comes to set environment variable for execution on remote host via ssh by system() method (aka run()).

As to not disclose the challange for others, I prepared some examplary problem instead of mentioning wargame itself. If you want to know it exactly ask me on my loginname on Gmail Dot Com.

Bear in mind that maybe I miss some python skill so sorry if You find it invalid. I also open to fix it and test.

Here it goes. In local directory on builder@localhost there is small shell script named echo.sh which is very simple and look for environment variable.

#!/bin/bash

env | grep varia

There we go with trying to get some bytes back.

Python 3.8.1 (default, Jan 22 2020, 06:38:00) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pwn import *                                                                                                                                    

In [2]: pwnlib.__version__                                                                                                                                   
Out[2]: '4.2.0dev'

In [3]: _ssh = ssh(host='localhost',user='builder')                                                                                                          
[x] Connecting to localhost on port 22
[+] Connecting to localhost on port 22: Done
[*] builder@localhost:
    Distro    Unknown 
    OS:       linux
    Arch:     amd64
    Version:  4.19.101
    ASLR:     Enabled

In [4]: _run1 = _ssh.run(b'varia=asdf ./echo.sh')                                                                                                            
[x] Opening new channel: b'varia=asdf ./echo.sh'
[+] Opening new channel: b'varia=asdf ./echo.sh': Done

In [5]: _run1.recvall()                                                                                                                                      
[x] Receiving all data
[x] Receiving all data: 0B
[x] Receiving all data: 11B
[+] Receiving all data: Done (11B)
[*] Closed SSH channel with localhost
Out[5]: b'varia=asdf\n'

In [6]: _run2 = _ssh.run(b'./echo.sh',env={'varia':b'asdf'})                                                                                                 
[x] Opening new channel: b'./echo.sh'
[+] Opening new channel: b'./echo.sh': Done

In [7]: _run2.recvall()                                                                                                                                      
[x] Receiving all data
[x] Receiving all data: 0B
[x] Receiving all data: 12B
[+] Receiving all data: Done (12B)
[*] Closed SSH channel with localhost
Out[7]: b'varia=basdf\n'

In [8]: _run3 = _ssh.run(b'./echo.sh',env={'varia':'asdf'})                                                                                                  
[x] Opening new channel: b'./echo.sh'
[+] Opening new channel: b'./echo.sh': Done

In [9]: _run3.recvall()                                                                                                                                      
[x] Receiving all data
[x] Receiving all data: 0B
[x] Receiving all data: 11B
[+] Receiving all data: Done (11B)
[*] Closed SSH channel with localhost
Out[9]: b'varia=asdf\n'

ipython_output

Here, we see that additional b letter was added in case of binary litteral.

Bigger problem is when we provide the binary literal or string literal to it and one got's b letter and apostrophes, but second got 'latin1' encoding (same output with str(bytes,'latin1') ).

Python 3.8.1 (default, Jan 22 2020, 06:38:00) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from pwn import *                                                                            

In [2]: _ssh = ssh(host='localhost',user='builder')                                                  
[x] Connecting to localhost on port 22
[+] Connecting to localhost on port 22: Done
[*] builder@localhost:
    Distro    Unknown 
    OS:       linux
    Arch:     amd64
    Version:  4.19.101
    ASLR:     Enabled

In [3]: _run1 = _ssh.run(b'varia=asdf\x90 ./echo.sh')                                                
[x] Opening new channel: b'varia=asdf\x90 ./echo.sh'
[+] Opening new channel: b'varia=asdf\x90 ./echo.sh': Done

In [4]: _run1.recvall()                                                                              
[x] Receiving all data
[x] Receiving all data: 0B
[x] Receiving all data: 12B
[+] Receiving all data: Done (12B)
[*] Closed SSH channel with localhost
Out[4]: b'varia=asdf\x90\n'

In [5]: _run2 = _ssh.run(b'./echo.sh',env={'varia':b'asdf\x90'})                                     
[x] Opening new channel: b'./echo.sh'
[+] Opening new channel: b'./echo.sh': Done

In [6]: _run2.recvall()                                                                              
[x] Receiving all data
[x] Receiving all data: 0B
[x] Receiving all data: 18B
[+] Receiving all data: Done (18B)
[*] Closed SSH channel with localhost
Out[6]: b"varia=b'asdf\\x90'\n"

In [7]: _run3 = _ssh.run(b'./echo.sh',env={'varia':'asdf\x90'})                                      
[x] Opening new channel: b'./echo.sh'
[+] Opening new channel: b'./echo.sh': Done

In [8]: _run3.recvall()                                                                              
[x] Receiving all data
[x] Receiving all data: 0B
[x] Receiving all data: 13B
[+] Receiving all data: Done (13B)
[*] Closed SSH channel with localhost
Out[8]: b'varia=asdf\xc2\x90\n'

ipython_output_2

@zachriggle
Copy link
Member

zachriggle commented Feb 28, 2020 via email

@heapcrash
Copy link
Collaborator

@Arusekk will know better how to fix this

Arusekk added a commit to Arusekk/pwntools that referenced this issue Jul 7, 2020
heapcrash added a commit that referenced this issue Jul 10, 2020
* Enhance tubes.ssh bytes handling

Closes #1437

* Add tests

* grep is actually nasty

* Update CHANGELOG.md

Co-authored-by: Heap Crash <66139157+heapcrash@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants