Using pwntools process interactive mode to control python3 - python

I am trying to use pwntools to control a python3 session. Here is my code:
from pwn import process
r = process(['python3'])
r.interactive()
However, after I enter r.interactive(), when I type into the terminal, the python3 sub-process has strange reactions. At least I do not see my commands echoed back most of the times.
I also tried to call python3 in a bash session, but the same thing happens.
$ python3
Python 3.8.5 (default, Jan 27 2021, 15:41:15)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import process
>>> r = process(['bash'])
[x] Starting local process '/usr/bin/bash'
[+] Starting local process '/usr/bin/bash': pid 119080
>>> r.interactive()
[*] Switching to interactive mode
echo hello
hello
echo this is bash
this is bash
python3
print(1)
print(2)
print(3)
exit
echo hello
File "<stdin>", line 5
echo hello
^
SyntaxError: invalid syntax
Why is this happening? Is it a bug in pwntools, or are there some configurations I overlook?

You need to specify the PTY in your shell, so like this:
$ python3
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pwn import *; r = process(['python3'], stdin=PTY, raw=False); r.interactive()
[x] Starting local process '/usr/bin/python3'
[+] Starting local process '/usr/bin/python3': pid 2984281
[*] Switching to interactive mode
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1+1
1+1
2
>>>

Related

Python os.environ doesn't show empty environment variables

After an environment variable is exported and set to empty, I can't get its value in Python with os.environ. Is it expected?
Examples:
## export TEST_ENV_VAR
(base) ➜ Code export | grep TEST_ENV_VAR
TEST_ENV_VAR=''
(base) ➜ Code python
Python 3.8.12 (default, Oct 12 2021, 13:49:34)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> 'TEST_ENV_VAR' in os.environ
False
## export TEST_ENV_VAR=''
(base) ➜ Code export | grep TEST_ENV_VAR
TEST_ENV_VAR=''
(base) ➜ Code python
Python 3.8.12 (default, Oct 12 2021, 13:49:34)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> 'TEST_ENV_VAR' in os.environ
True
## export TEST_ENV_VAR='TEST'
(base) ➜ Code export | grep TEST_ENV_VAR
TEST_ENV_VAR=TEST
(base) ➜ Code python
Python 3.8.12 (default, Oct 12 2021, 13:49:34)
[GCC 7.5.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> 'TEST_ENV_VAR' in os.environ
True
The three samples above run in three different new terminals. I modified the .zshrc file to export different values. What's the difference between export foo and export foo=''?
There is a difference between "Shell variables" and "Environment Variables" - see here - A shell variable is only available to the shell setting it whereas an environment variable is available to all child processes as well.
In bash - you can get the list of environment variables with env, and add to the environment variables with export
SHELL_VAR="10"
env | grep SHELL_VAR # No result
export ENV_VAR=100
env | grep ENV_VAR # ENV_VAR=100
Python shell (child process) picks the environment variables when you try an os.environ
'SHELL_VAR' in os.environ # False
'ENV_VAR' in os.environ # True
The issue is the way you are defining your variables.
When you just do:
export FOO
no variable is actually exported unless FOO has been defined previously:
FOO=''
export FOO
or concomitantly:
export FOO=''
If FOO appears in env | grep FOO, it should appear in os.environ.

how to read the value returned by sys.exit() and store it in a variable

I have a python script with sys.exit(0) or sys.exit(-1) in the end (0 or 1 depending on whether an error has occurred). How do I store this 0 or 1 in a variable? For example, in an environment variable or in a variable used by a perl script
If you run your python code in a normal shell you have the $? variable:
$ python yourscript.py
$ echo $? # this will echo the sys.exit value
This is also valid inside your perl script:
system("python yourscript.py");
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
If you are in windows use %ERRORLEVEL%:
CMDPROMPT>python
Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win 32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.exit(-1)
CMDPROMPT>echo %ERRORLEVEL%
-1
CMDPROMPT>python
Python 2.7.3 (default, Apr 10 2012, 23:24:47) [MSC v.1500 64 bit (AMD64)] on win 32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.exit(0)
CMDPROMPT>echo %ERRORLEVEL%
0
CMDPROMPT>

eshell starts python IDLE instead of running script when editing remotely

With Emacs 24.3.1, I get this when editing through Tramp/ssh in eshell:
/<remotepath> $ bash
/<remotepath> $ python test.py
hello world!
/<remotepath> $ exit
exit
/<remotepath> $ python test.py
Python 2.6.6 (r266:84292, Oct 12 2012, 14:23:48)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
The file test.py is:
print "hello world!"
Bash is version 4.1.2. Does anyone have any explanation for this behavior?
I don't know eshell, but my guess is you forget to pass the positional parameters when creating your alias:
# don't forget the quotes
# ▼ ▼
~ $ alias python '/path/to/alternate/python $*'
# ▲▲
# don't forget positional parameters
See http://www.emacswiki.org/emacs/EshellAlias

How to run cmd windows netsh command using python?

I am trying to run the following netsh command on Windows 7 however It returns incorrect syntax
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.system("netsh interface ipv4 set interface ""Conexão de Rede sem Fio"" metric=1")
The syntax of the file name, directory name or volume label is incorrect.
1
>>>
What's wrong?
os.systemis a very old choice and not really recommended.
Instead you should consider subprocess.call() or subprocess.Popen().
Here is how to use them:
If you don't care about the output, then:
import subprocess
...
subprocess.call('netsh interface ipv4 set interface ""Wireless Network" metric=1', shell=True)
If you do care about the output, then:
netshcmd=subprocess.Popen('netsh interface ipv4 set interface ""Wireless Network" metric=1', shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE )
output, errors = netshcmd.communicate()
if errors:
print "WARNING: ", errors
else:
print "SUCCESS ", output

Unknown screen output of manually installed Python 2.7

I installed Python 2.7 today using:
./configure --prefix=/home/zhanwu/local --enable-shared --enable-profiling --with-pydebug
make install
Then I keep getting something like "[37745 refs]" on screen after each function call:
[zhanwu#cluster ~]$ ~/local/bin/python
Python 2.7.1 (r271:86832, Jun 16 2011, 17:45:05)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
[37745 refs]
>>> print 'test'
test
[37745 refs]
>>> sys.exit()
[18048 refs]
[zhanwu#cluster ~]$
What does those numbers mean? Anything wrong here and can I get rid of them?
uname -a result:
[zhanwu#cluster ~]$ uname -a
Linux cluster.xxx.xxx.xxx 2.6.18-128.1.14.el5 #1 SMP Wed Jun 17 06:38:05 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux
You get these because you configured the build with --with-pydebug. They denote the number of references Python is currently keeping track of. To get rid of them, configure without --with-pydebug.

Categories

Resources