Different results when running C program from Python Subprocess vs in Bash - python

I've got a string/argument that I'd like to pass to a C program. It's a string format exploit.
'\xb2\x33\02\x08%13x%2$n'
However, there seems to be different behaviours exhibited if I call the C program from Python by doing
subprocess.Popen(["env", "-i", "./practice", '\xb2\x33\02\x08%13x%2$n'])
versus
./practice '\xb2\x33\02\x08%13x%2$n'
The difference is that the string exploit attack works as expected when calling the script via subprocess, but not when I call it through the CLI.
What might the reason be? Thanks.

Bash manpage says:
Words of the form $'string' are treated specially. The word expands to
string, with backslash-escaped characters replaced as specified by the
ANSI C standard. Backslash escape sequences, if present, are decoded
as follows: [snipped]
\xHH the eight-bit character whose value is the hexadecimal
value HH (one or two hex digits)
Then would you please try:
./practice $'\xb2\x33\02\x08%13x%2$n'

Related

Removing backslashes in a string in python [duplicate]

I'm creating a dictionary for which one of the value is a string with backslash,I know that python is automatically adding escape sequence.But at the end when you print the dictionary it's still printing that value with muliple backslashes,Now i have to pass this dictionary to another tool which is not expecting multiple backslashes,So currently I'm forced to manually remove a backslash is there a way to remove the backslash from the value of dictionary automatically.
(Pdb) print value2
"\x01\x02\x03\x04\x05"
(Pdb) value2
'"\\x01\\x02\\x03\\x04\\x05"'
You are confusing string representations with string values.
When you echo a string object in the Python interpreter, the output is really produced by printing the result of the repr() function. This function outputs debugging friendly representations, and for strings, that representation is valid Python syntax you can copy and paste back into Python.
print on the other hand, just writes the actual value in the string to the terminal. That's rather different from the Python syntax that creates the value. A backslash in the string prints as a backslash, you wouldn't see a backslash if there wasn't one in the value.
In Python string literal syntax, the \ backslash character has special meaning, it's the first character of an escape sequence. So if you want to have an actual backslash in the value of the string, you would need to use \\ to 'escape the escape'. There is other syntax where the backslash would not have special meaning, but the repr() representation of a string doesn't use that other syntax. So it'll output any backslash in the value as the escape sequence \\.
That doesn't mean that the value has two backslashes. It just means that you can copy the output, and paste it into Python, and it'll produce the same string value.
You can see that your string value doesn't have double backslashes by looking at individual characters:
>>> value2 = '"\\x01\\x02\\x03\\x04\\x05"'
>>> value2
'"\\x01\\x02\\x03\\x04\\x05"'
>>> print value2
"\x01\x02\x03\x04\x05"
>>> print value2[0]
"
>>> print value2[1]
\
>>> print value2[2]
x
>>> value2[0]
'"'
>>> value2[1]
'\\'
>>> value2[2]
'x'
Printing value2[1] shows that that single character is a backslash. Echoing that single character shows '\\', the Python syntax to recreate a string with a single character.
When you echo dictionaries or lists or other standard Python containers, they too are echoed using valid Python syntax, so their contents all are shown by using repr() on them, including strings:
>>> d = {'foo': value2}
>>> d
{'foo': '"\\x01\\x02\\x03\\x04\\x05"'}
Again, that's not the value, that's the representation of the string contents.
On top of that, container types have no string value, so printing a dictionary or list or other standard container type will only ever show their representation:
>>> print d # shows a dictionary representation
{'foo': '"\\x01\\x02\\x03\\x04\\x05"'}
>>> print d['foo'] # shows the value of the d['foo'] string
"\x01\x02\x03\x04\x05"
You'd have to print individual values (such as d['foo'] above), or create your own string value from the components (which involves accessing all the contents and building a new string from that). Containers are not meant to be end-user-friendly values, so Python doesn't provide you with a string value for them either.
Strings can also contain non-printable characters, characters that don't have a human-readable value, such as a newline, or a tab character, and even the BELL character that'll make most terminals go beep when you write one of those to them. And in Python 2, the str type holds bytes, really, and only printable characters in the ASCII range (values 00 - 7F) considered when producing the repr() output. Anything outside is always considered unprintable, even if you could decode those bytes as Latin-1 or another commonly used codec.
So when you do have special characters other than \ in the string, you'd see this in the representation:
>>> value_with_no_backslashes = "This is mostly ASCII with a \b bell and a newline:\nSome UTF-8 data: 🦊"
>>> print value_with_no_backslashes # works because my terminal accepts UTF-8
This is mostly ASCII with a bell and a newline:
Some UTF-8 data: 🦊
>>> value_with_no_backslashes
'This is mostly ASCII with a \x08 bell and a newline:\nSome UTF-8 data: \xf0\x9f\xa6\x8a'
Now, when I echo the value, there are backslashes, to make sure the non-printable characters can easily be copied and reproduce the same value again. Note that those backslashes are not doubled in the echoed syntax.
Note that representations are Python specific and should only be used to aid debugging. Writing them to logs is fine, using them to pass values between programs is not. Always use a serialisation format to communicate between programs, including command-line tools started as subprocesses or by writing output to the terminal. Python comes with JSON support built in, and for Python-to-Python serialisation with no chance of third-party interference, pickle can be used for almost any Python data structure.

Bizarre behavior of python printing non-alphabetic ASCII characters

I have the following Python code:
for num in range(80, 150):
input()
print(num)
print(chr(27))
print(chr(num))
The input() statement is only there to control how quickly the for loop proceeds. I am not expecting this to do anything special, but when the loop hits certain numbers, printing that ASCII character, preceded by ASCII 27 (which is the ESC character) does some unexpected things:
At 92 and 94, the number does not print. http://i.stack.imgur.com/DzUew.png
At 99 (the letter c), a bunch of terminal output gets deleted. http://i.stack.imgur.com/5XPy3.png
At 108 (the letter l), the current line jumps up several lines (but text remains below). (didn't get a proper screencap, I'll add one later if it helps)
At 128 or 129, the first character starts getting masked. You have to type something (I typed "jjj") in order to prevent this from happening on that line. http://i.stack.imgur.com/DRwTm.png
I don't know why any of this happens although I imagine it has something to do with the ESC character interacting with the terminal. Could someone help me figure this out?
It is due to confusion between escape sequences and character-encoding.
Your program is printing escape sequences, including
escapec (resets the terminal)
escape^ (begins a privacy message, which causes other characters to be eaten)
In ISO-8859-1 (and ECMA-48), character bytes between 128 and 159 are considered control characters, referred to as C1 controls. Several of these are treated the same as escape combined with another character. The mapping between C1 and "another character" is not straightforward, but the interesting ones include
0x9a which is device attributes, causing characters to be sent to the host.
0x9b which is control sequence initiator, more usually seen as escape[.
On the other hand, bytes in the 128-159 range are legal parts of a UTF-8 character. If your terminal is not properly configured to match the locale settings, you can find that your terminal responds to control sequences.
OSX terminal implements (does not document...) many of the standard control sequences. XTerm documents these (and many others), so you may find the following useful:
XTerm Control Sequences
C1 (8-Bit) Control Characters (specifically)
Standard ECMA-48:
Control Functions for Coded Character Sets
For amusement, you are referred to the xterm FAQ: Interesting but misleading
Esc with those characters make a special code for terminal .
A terminal control code is a special sequence of characters that is
printed (like any other text). If the terminal understands the code,
it won't display the character-sequence, but will perform some action.
You can print the codes with a simple echo command.
Terminal Codes
For example,
ESC/ = ST, String Terminator (chr(92))
ESC^ = PM, Privacy Message (chr(94)) .
Control Sequences are different based on what terminal do you use.
More about:
Xterm Control Sequences
ANSI escape code
ANSI/VT100 Terminal Control Escape Sequences,

python character set conversion by the compiler

C:\c>python -m pydoc wordspyth^A.split
no python documentation found for 'wordspyth\x01.split'
I understand that python documentation doesn't exist, but why does ^A convert to \x01?
Ctrl+A is a control character with value 1, those are echoed hexidecimal by default. As they might break your prompt/terminal and/or would be illegible.
That pydoc doesn't know about the non-standard function wordspyth doesn't mean there is no documentation
Like Anthon said , ctrl + A is a non-printable character , when you add that to a string in python and the string is printed out, python internally converts many such non-printable characters to printable unicode format.
This was done in Python 3000 through http://legacy.python.org/dev/peps/pep-3138/

python: extended ASCII codes

Hi I want to know how I can append and then print extended ASCII codes in python.
I have the following.
code = chr(247)
li = []
li.append(code)
print li
The result python print out is ['\xf7'] when it should be a division symbol. If I simple print code directly "print code" then I get the division symbol but not if I append it to a list. What am I doing wrong?
Thanks.
When you print a list, it outputs the default representation of all its elements - ie by calling repr() on each of them. The repr() of a string is its escaped code, by design. If you want to output all the elements of the list properly you should convert it to a string, eg via ', '.join(li).
Note that as those in the comments have stated, there isn't really any such thing as "extended ASCII", there are just various different encodings.
You probably want the charmap encoding, which lets you turn unicode into bytes without 'magic' conversions.
s='\xf7'
b=s.encode('charmap')
with open('/dev/stdout','wb') as f:
f.write(b)
f.flush()
Will print ÷ on my system.
Note that 'extended ASCII' refers to any of a number of proprietary extensions to ASCII, none of which were ever officially adopted and all of which are incompatible with each other. As a result, the symbol output by that code will vary based on the controlling terminal's choice of how to interpret it.
There's no single defined standard named "extend ASCII Codes"> - there are however, plenty of characters, tens of thousands, as defined in the Unicode standards.
You can be limited to the charset encoding of your text terminal, which you may think of as "Extend ASCII", but which might be "latin-1", for example (if you are on a Unix system such as Linux or Mac OS X, your text terminal will likely use UTF-8 encoding, and able to display any of the tens of thousands chars available in Unicode)
So, you must read this piece in order to understand what text is, after 1992 -
If you try to do any production application believing in "extended ASCII" you are harming yourself, your users and the whole eco-system at once: http://www.joelonsoftware.com/articles/Unicode.html
That said, Python2's (and Python3's) print will call the an implicit str conversion for the objects passed in. If you use a list, this conversion does not recursively calls str for each list element, instead, it uses the element's repr, which displays non ASCII characters as their numeric representation or other unsuitable notations.
You can simply join your desired characters in a unicode string, for example, and then print them normally, using the terminal encoding:
import sys
mytext = u""
mytext += unichr(247) #check the codes for unicode chars here: http://en.wikipedia.org/wiki/List_of_Unicode_characters
print mytext.encode(sys.stdout.encoding, errors="replace")
You are doing nothing wrong.
What you do is to add a string of length 1 to a list.
This string contains a character outside the range of printable characters, and outside of ASCII (which is only 7 bit). That's why its representation looks like '\xf7'.
If you print it, it will be transformed as good as the system can.
In Python 2, the byte will be just printed. The resulting output may be the division symbol, or any other thing, according to what your system's encoding is.
In Python 3, it is a unicode character and will be processed according to how stdout is set up. Normally, this indeed should be the division symbol.
In a representation of a list, the __repr__() of the string is called, leading to what you see.

Is there any possible way to display accented characters in Python interpreter?

I am trying to make a random wiki page generator which asks the user whether or not they want to access a random wiki page. However, some of these pages have accented characters and I would like to display them in git bash when I run the code. I am using the cmd module to allow for user input. Right now, the way I display titles is using
r_site = requests.get("http://en.wikipedia.org/w/api.php?action=query&list=random&rnnamespace=0&rnlimit=10&format=json")
print(json.loads(r_site.text)["query"]["random"][0]["title"].encode("utf-8"))
At times it works, but whenever an accented character appears it shows up like 25\xe2\x80\x9399.
Any workarounds or alternatives? Thanks.
import sys
change your encode to .encode(sys.stdout.encoding, errors="some string")
where "some string" can be one of the following:
'strict' (the default) - raises a UnicodeError when an unprintable character is encountered
'ignore' - don't print the unencodable characters
'replace' - replace the unencodable characters with a ?
'xmlcharrefreplace' - replace unencodable characters with xml escape sequence
'backslashreplace' - replace unencodable characters with escaped unicode code point value
So no, there is no way to get the character to show up if the locale of your terminal doesn't support it. But these options let you choose what to do instead.
Check here for more reference.
I assume this is Python 3.x, given that you're writing 3.x-style print function calls.
In Python 3.x, printing any object calls str on that object, then encodes it to sys.stdout.encoding for printing.
So, if you pass it a Unicode string, it just works (assuming your terminal can handle Unicode, and Python has correctly guessed sys.stdout.encoding):
>>> print('abcé')
abcé
But if you pass it a bytes object, like the one you got back from calling .encode('utf-8'), the str function formats it like this:
>>> print('abcé'.encode('utf-8'))
b'abc\xce\xa9'
Why? Because bytes objects isn't a string, and that's how bytes objects get printed—the b prefix, the quotes, and the backslash escapes for every non-printable-ASCII byte.
The solution is just to not call encode('utf-8').
Most likely your confusion is that you read some code for Python 2.x, where bytes and str are the same type, and the type that print actually wants, and tried to use it in Python 3.x.

Categories

Resources