Following my OSX bash bug discovery the other week what about this baby.
Just to let you guys know, since my post Sinclair Spectrum days where it was impossible to do a syntax error I do a great deal of syntax juggling to see what works on the few languages that I know, and I have done it for years, a form of hacking if you like......
I found this and mentioned it to someone I know on a python list.
NOTE: The help in the second code snippet. It seems that the string length is printed to sys.stderr .
The guy said it was part of the standard library in Version 3.x.x, NOT in Version 2.7.x and lower.
This IS actually in Python 3.x's standard library!? <Shock!>
I don't know about the latest Python 3.6.1 as I have not installed it yet.
The use of Python's exit function here is none standard but it does NOT give an error.
INSTEAD it gives a return code of the string length.
Surely this HAS to be a bug?
Last login: Wed Jun 7 13:16:13 on ttys000
AMIGA:amiga~> python3.5
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> help(sys.stdout.write)
>>> sys.stdout.write("Hello World!\n")
Hello World!
13
>>> exit(sys.stdout.write("Hello World!\n"))
Hello World!
AMIGA:amiga~> echo "$?"
13
AMIGA:amiga~> _
OUCH!
The help(sys.stdout.write) on python3.5.x
Help on built-in function write:
write(text, /) method of _io.TextIOWrapper instance
Write string to stream.
Returns the number of characters written (which is always equal to
the length of the string).
(END)
import sys
print("Now in Python script!")
sys.exit(sys.stdout.write("Goodbye World!\n"))
Results, same system as before...
Last login: Thu Jun 8 14:33:04 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> chmod 755 PythonRC.sh
AMIGA:amiga~/Desktop/Code/Shell> ./PythonRC.sh
Hello World!
Now in Python script!
Goodbye World!
Return code is 15...
AMIGA:amiga~/Desktop/Code/Shell> _
EDIT:
Makes one wonder what a string greater than 255 characters would give, (wrap around the 255 bash shell boundary). What about returning these values to other languages and OSes?
For me, python is a large snake, or a flying circus, but what you show above would be the expected behaviour and absolutely makes sense to me. In the languages I know, exit (or similar) can take a value, even from a variable or a function, which becomes the program's "exit code". Why not deploy write 's return value of 15? awk example:
awk 'END {X=7; exit X}'
echo $?
7
For values greater than 255, usually the lower byte is evaluated.
I seem to recall you making a thread about this before, and it was determined that printing the return values to stderr was a feature Python does in interactive mode.
As for it returning 15? It's actually very standard to give exit() a code in most languages, if Python didn't it'd be the weird one. And it is documented, here:
Yes, the exit value is communicated to BASH, the calling process, that is its function, to tell it whether the program succeeded or failed.
import os
print("Inside the Python script.")
text=10
text=input("Enter your text:- ")
exit(os.system(text))
print("This will never be reached...")
Result:-
Last login: Thu Jun 8 18:43:20 on ttys000
AMIGA:amiga~> cd Desktop/Code/Shell
AMIGA:amiga~/Desktop/Code/Shell> chmod 755 exit_malicious.sh
AMIGA:amiga~/Desktop/Code/Shell> ./exit_malicious.sh
Inside bash shell here.
Inside the Python script.
Enter your text:- echo "Launch my malicious code here whilst exiting Python..."
Launch my malicious code here whilst exiting Python...
Back inside bash shell with exit code 0...
AMIGA:amiga~/Desktop/Code/Shell> _
@Corona688...
No that was something entirely different using the shell's exit, it is on here I will find the pointer.
EDIT:
I appreciate this is hypothetical but if I can create this then a deep professional would know fully how to exploit it.
---------- Post updated at 07:36 PM ---------- Previous update was at 06:58 PM ----------
'END' just hangs on this machine so 'BEGIN' instead.
Hmmm, so this is normal proceedure?
Last login: Thu Jun 8 19:21:58 on ttys000
AMIGA:amiga~> awk --version
awk version 20070501
AMIGA:amiga~> awk 'BEGIN { x=13; x=system("ls -l"); exit x; }'
total 2120
-rwxr-xr-x 1 amiga staff 217121 20 May 14:23 06500.sh.txt
-rw-r--r-- 1 amiga staff 5128 22 May 14:16 06500.txt
drwxr-xr-x 3 amiga staff 102 2 Jan 15:42 Applications
-rw-r--r-- 1 amiga staff 20715 3 Jun 13:47 AudioScope.Circuits
-rw-r--r-- 1 amiga staff 315 3 Jun 13:47 AudioScope.Config
-rw-r--r-- 1 amiga staff 118305 3 Jun 13:47 AudioScope.Manual
-rwxr-xr-x 1 amiga staff 220419 3 Jun 12:00 AudioScope.sh
-rwxr-xr-x 1 amiga staff 220418 3 Jun 11:45 AudioScope.sh~
-rw-r--r-- 1 amiga staff 220047 24 May 18:35 AudioScope24-05-2017.sh
-rw-r--r-- 1 amiga staff 6307 3 Jun 13:47 AudioScope_Quick_Start.Notes
drwx------+ 12 amiga staff 408 3 Jun 20:25 Desktop
drwx------+ 8 amiga staff 272 31 Dec 15:23 Documents
drwx------+ 22 amiga staff 748 7 Jun 13:12 Downloads
drwx------@ 58 amiga staff 1972 18 May 18:08 Library
drwx------+ 3 amiga staff 102 24 Oct 2016 Movies
drwx------+ 6 amiga staff 204 14 Dec 22:16 Music
-rwxr-xr-x 1 amiga staff 751 18 May 17:39 NewCLI
drwx------+ 6 amiga staff 204 16 May 14:23 Pictures
drwxr-xr-x 3 amiga staff 102 11 Dec 17:34 Programs
drwxr-xr-x+ 6 amiga staff 204 18 May 18:36 Public
drwxr-xr-x 56 amiga staff 1904 18 May 17:45 Scope
drwxr-xr-x 27 amiga staff 918 3 Jun 12:01 Temp
drwxr-xr-x 4 amiga staff 136 14 Oct 2016 URL
-rw-r--r-- 1 amiga staff 28518 31 May 20:00 sample.txt
drwxr-xr-x@ 14 amiga staff 476 7 Nov 2016 sox-14.4.2
-rwxr-xr-x 1 amiga staff 751 20 May 09:07 xterm
AMIGA:amiga~> echo "Return code, $?..."
Return code, 0...
AMIGA:amiga~> _
I can't tell what value os.system.text will return. Is it a function returning successfully? Certainly not an integer value. I ponder a pointer of which the low order byte is 0.
It doesn't "hang", it reads from stdin / tty, so hit a <CTRL>-D as an EOF char.
Yes, exactly ls -l completed successfully and returned a 0.
So one is allowed to execute code AFTER exit has been called even if it is an ASCII string inside a variable, from awk AND Python and I thought Python was strict, what about Perl and others?
Awk's exit is a statement and Python's is a function.
Maybe it is just me but this should never be allowed to happen if the RC is not an integer. BTW thanks for the Ctrl-D heads up, I had forgotten all about that, however 'ls -l' is still executed.
Hi Corona688...
It was this, it always needs a redirection to a file for it to work however, so nothing like the other two and technically MUCH safer:-
Last login: Thu Jun 8 21:10:58 on ttys000
AMIGA:amiga~> exit 10 $( ls -l /tmp/ > /tmp/text )
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
Last login: Thu Jun 8 21:11:40 on ttys000
AMIGA:amiga~> cat /tmp/text
total 0
drwx------ 3 amiga wheel 102 8 Jun 18:27 com.apple.launchd.QBBc1cRjqo
drwx------ 3 amiga wheel 102 8 Jun 18:27 com.apple.launchd.iC1FUcCphs
-rw-r--r-- 1 amiga wheel 0 8 Jun 21:12 text
AMIGA:amiga~> _
And yes, I know why the 'text' file_length reads zero, 0.
You don't "execute code AFTER exit" - you add one (or more) routines to the sequence of tasks the programme has to perform before giving control back to the caller, e.g. closing files, releasing locks, freeing allocated memory. If it is a write , you'd mayhap do it before stdout is closed, if it is just a number, you reference it just on exiting.
Both - whatever they are - start quitting the programme.
Pascal wouldn't allow non-integers, C mayhap would - python might be somewhere in between.