Skip to content

Instantly share code, notes, and snippets.

@princebot
Last active July 28, 2017 10:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save princebot/e18a1ef011e84fee4509be2264bb27a6 to your computer and use it in GitHub Desktop.
Save princebot/e18a1ef011e84fee4509be2264bb27a6 to your computer and use it in GitHub Desktop.
A command injection example.
# This is my stream-of-consciousness attempt to figure out why
# https://twitter.com/asdizzle_/status/890496680495374336 works.
#
# As the tweet says, many validator techniques (filters and WAFs?) prohibit
# spaces, $, {, or } and such. This uses shell-fu to get around that by using
# command substitution (the backticks).
#
# Basically, everything in backticks is evaluated before the shell executes
# the "real" command, uname.
#
# It uses a here-string to send a command to PHP interpreter; the result of
# the PHP command becomes the arguments/options for uname.
#
# Note: It uses backticks instead of $() for substitution, and instead of the
# shell's syntax for escape-string-literals — $'' — because dollar sign is
# expected to be a prohibited character.
# Command in example is uname`cat<<<'<?="\x20"?>'|php`-a
# The result is uname -a
# Breakdown:
# uname does not take any arguments, only short options, e.g., -a
uname
# start a command substitution
`cat<<<
# <<< starts a string substitution, which evaluates a string or variable
# and uses it as input to a command. the string we're substituting is the
# ASCII code for a space: \x20 = hex 20 = 32 = space.
'<?="\x20"?>'
# cat sends the output of command to php, which evaluates the above as a
# space and prints it; this becomes the result of the command substitution.
|php`
-a
# Another example: uname`cat<<<'<?="\x2d\x61"?>'|php`
# This also resolves to uname -a. The only difference is this version uses PHP
# to generate the space, the dash, AND the a.
#
# You can do the same with any escape codes you can pipe through PHP.
@JeremyNGalloway
Copy link

can you come up with a way to write a file? say, some arbitrary text to ~/.ssh/authorized_keys

@princebot
Copy link
Author

no, don't think you can write to a file because of the way shell expansions work.

the shell checks if a redirection is going to occur BEFORE it does all its expansions and substitutions. so something like uname >$(echo foo.txt) would work, redirecting output to foo.txt. but that's because > was already present BEFORE substitutions occurred.

doing something like uname $(echo '>foo.txt') wouldn't work.

tl;dr: no, shells are complicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment