5
C:\>batinjection OFF ^& DEL c.c

batinjection.bat has contents of ECHO %*

I've heard of SQL injection, though i've never actually done it, but is this injection? Are there different types of injection and this is one of them?

Or is there another technical term for this? or a more specific term?

Note- a prior edit had C:\>batinjection OFF & DEL c.c(i.e. without ^%) and ECHO %1(i.e. without %*) which wasn't quite right. I have corrected it. It doesn't affect the answers.

barlop
  • 12,887
  • 8
  • 80
  • 109
  • I should've removed the DEL c.c since I realise now, since phatfingers pointed it out, that it's not injected. Nevertheless, the OFF seems to be. – barlop Nov 24 '11 at 09:33
  • The `& DEL` is executed by the cmd line, it isn't a injecton, to inject a second command use `^&` instead, like `batijection OFF ^& dir` – jeb Nov 24 '11 at 10:23
  • @jeb though then %1 is off, %2 is probably &, %3 is DIR. And if I put quotes around the parameters when calling it, it puts it all in %1 but with quotes so the injection won't work for that. – barlop Nov 24 '11 at 10:38
  • 1
    Obviously the injection depends of the content, `"OFF & DIR"` isn't a problem, but `OFF ^& DIR` will be a problem – jeb Nov 24 '11 at 10:45
  • @jeb but surely ECHO "OFF & DIR" is not going to run DIR even because the quotes get sent to the batch file too – barlop Nov 24 '11 at 10:47
  • Yes, as I said `"OFF & DIR"` isn't a problem, but `OFF ^& DIR` will result in the batch to `echo OFF & DIR` – jeb Nov 24 '11 at 11:03
  • with %*..as you say btw I think our terminology was a bit opposite when you say problem, defining whether the problem is to get the interesting behaviour(as i'm trying to do from my code), or as you say, to prevent it. – barlop Nov 24 '11 at 11:09

4 Answers4

7

Your example presents three interesting issues that are easier to understand when separated.

First, Windows allows multiple statements to be executed on one line by separating with "&". This could potentially be used in an injection attack.

Second, ECHO parses and interprets messages passed to it. If the message is "OFF" or "/?" or even blank, then ECHO will provide a different expected behavior than just copying the message to stdout.

Third, you know that it's possible to inject code into a number of scriptable languages, including batch files, and want to explore ways to recognize it so you can better defend against it in your code.

It would be easier to recognize the order in which things are happening in your script if you add an echo statement before and after the one you're trying to inject. Call it foo.bat.

@echo off
echo before
echo %1
echo after

Now, you can more easily tell whether your injection attempt executed at the command line (not injection) or was executed as a result of parameter expansion that broke out of the echo statement and executed a new statement (injection).

foo dir

Results in:

before
dir
after

Pretty normal so far. Try a parameter that echo interprets.

foo /?

Results in:

before
Displays messages, or turns command-echoing on or off.

  ECHO [ON | OFF]
  ECHO [message]

Type ECHO without parameters to display the current echo setting.
after

Hmm. Help for the echo command. It's probably not the desired use of echo in that batch file, but it's not injection. The parameters were not used to "escape out" of the limits of either the echo statement or the syntax of the batch file.

foo dog & dir

Results in:

before
dog
after
[A spill of my current directory]

Okay, the dir happened outside of the script. Not injection.

foo ^&dir/w

Results in:

before
ECHO is off.
[A spill of my current directory in wide format]
after

Now, we've gotten somewhere. The dir is not a function of ECHO, and is running between the before and after statements. Let's try something more dramatic but still mostly harmless.

foo ^&dir\/s

Yikes! You can pass an arbitrary command that can potentially impact your system's performance all inside an innocuous-looking "echo %1".

phatfingers
  • 9,770
  • 3
  • 30
  • 44
  • hmm, hadn't ever done dir\ without a space, nice. I should've noticed the &dir or & dir was running after, by having echo on. 'cos you see the line echo and what follows it. You say it is injection if the parameters were used to "escape out" of the limits of either the echo statement or the syntax of the batch file. And you beautifully said "executed as a result of parameter expansion that broke out of the echo statement and executed a new statement (injection)." I'm curious though, you say if it breaks the syntax of the batch file.. any example of such a thing? – barlop Nov 24 '11 at 20:56
  • i'm off to bed now unfortunately, but presumably a batch file wouldn't run if the syntax of it was broken – barlop Nov 24 '11 at 20:56
  • The ^& originally pointed out by @jeb is simplest example you're likely to find of escaping out of the intended "echo" command and injecting a new command. You're passing "&" as a literal inside of a variable and your batch file, after expanding it, is interpreting it and running it after the echo command is completed. – phatfingers Nov 24 '11 at 21:07
  • Yes I understand all that. I'm just saying that doesn't break the syntax of the batch file. If it did, the batch file wouldn't run. And it's still very much within batch file syntax. – barlop Nov 24 '11 at 21:17
  • 1
    A more complex example would be if you put quotes around your %1. The simple ^&dir would no longer inject, but you could then escape out of the quotes using [ foo ^"^&dir^ \ ]. The ^" passes in a closing quote, the ^& initiates a new command, "dir \"" is executed, which looks weird but does the job. – phatfingers Nov 24 '11 at 21:28
  • @barlop I said "broke out", like someone breaking out of a jail, not just "broke". I suppose you could do something like "foo ^&bar" and trigger an error condition. – phatfingers Nov 24 '11 at 21:45
  • had to remove the space after foo(otherwise it thinks what follows is going to %2). But that's impressive.. also I didn't realise dir abc" and dir "abc still worked. Howcome batfile foo^"^&dir^ ^ ^ \ <-- works as expected, but when I try to put some escaped spaces after foo, it seems to not work?(it acts like the consecutive escaped spaces after foo aren't escaped). but the escaped spaces after dir do escape. batfile foo^ ^ ^ ^"^&dir^ ^ ^ \ – barlop Nov 24 '11 at 21:59
  • i'll look into what's going on there, though you've answered the question. i'll accept this more recent answer instead of the previous one, since it's more recent. – barlop Nov 25 '11 at 08:23
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5337/discussion-between-phatfingers-and-barlop) – phatfingers Nov 25 '11 at 09:12
4

Yes, it's a type of injection, and it's one of the big problems with batch files, that mostly it isn't a purposefully attac, most of the time you simple get trouble with some characters or word like OFF.

Therefore you should use technics to avoid this problems/vulnerabilitys.

In your case you could change your batch file to

set "param1=%*"
setlocal EnableDelayedExpansion
echo(!param1!

I use echo( here instead of echo. or something else, as it is the only known secure echo for all appended contents.

I use the delayed expansion ! instead of percent expansion, as delayed expansion is always safe against any special characters.

To use the delayed expansion you need to transfer the parameter into a variable and a good way is to use quotes around the set command, it avoid many problems with special characters (but not all).

But to build an absolutly secure way to access batch parameters, the way is quite harder.
Try to make this safe is tricky
myBatch.bat ^&"&"

You could read SO: How to receive even the strangest command line parameters?

The main idea is to use the output of a REM statement while ECHO ON.
This is safe in the way, that you can't inject code (or better: only with really advanced knowledge), but the original content can be changed, if your content is something like.

myBatch.bat myContent^&"&"%a

Will be changed to myContent&"&"4

Community
  • 1
  • 1
jeb
  • 78,592
  • 17
  • 171
  • 225
  • Is %1 quite well defended? e.g. in batinjection OFF ^& DEL c.c it won't ECHO beyond OFF since %2 seems to be &, and %3 seems to be DEL. %* is vulnerable, but it seems %1 is quite defended? – barlop Nov 24 '11 at 10:46
  • I changed it to `%*`, but the idea is the same – jeb Nov 24 '11 at 11:00
1

AFAIK, this is know as command injection (which is one of types code injection attack).

The later link lists various injection attacks. The site (www.owasp.org) is an excellent resource regarding web security.

VinayC
  • 47,395
  • 5
  • 59
  • 72
  • That is not an example of command injection. See http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/ntcmds_shelloverview.mspx?mfr=true describing what the "&" does. – phatfingers Nov 24 '11 at 09:19
  • @phatfingers Yes i'm sure he knows what & does, and so do I. I thought the & was getting injected to the bat file but apparently not. Nevertheless, the OFF is. So it's some kind of injection there.. not sure what. – barlop Nov 24 '11 at 09:34
  • @barlop The %1 is supposed to expand to OFF. That's the normal and intended function of a batch file parameter. – phatfingers Nov 24 '11 at 15:32
  • @phatfingers Yes, he erred in seeing the intended design and not spotting the bug. And he answered for what my code would've been had it been what I intended it. He probably accidentally overlooked the bug, I didn't realise there was a bug either. To get the behaviour I intended, I should've done %* and ^& and what he says is true had I not had that bug in there. – barlop Nov 24 '11 at 15:40
  • If you had given a valid example of command injection, then this would have been a very helpful answer, but can be misleading if someone is trying to understand injection. The ^& case @jeb presented is injection, but the OFF case presented in your example is not. – phatfingers Nov 24 '11 at 17:06
  • @phatfingers hmm, I was thinking then maybe it was code injection if not command injection..would OFF be a keyword in batch language.. IF is as much batch language as ECHO is. It's just built into CMD.EXE So a command to ECHO would be code too.. like OFF in the context of ECHO OFF. "off" isn't just any old data. I suppose perhaps it could be called a keyword. Thus it is "code injection". – barlop Nov 24 '11 at 18:52
  • @phatfingers, wow - so many comments while I am away! @barlop, thanks for defending me! While answering, I had overlooked `&` behavior and @phatfingers was spot to point that out! Said that the batch file is still susceptible of injection because it doesn't escape the input - so in this case, the batch code wouldn't print `OFF` keyword as it was the intent of the code. Many thanks to @jeb to provide excellent answer in the regard. – VinayC Nov 25 '11 at 04:06
  • Vinay, the whole point was to inject and get interesting behaviour(the code injection)! Not the other way around(defending my code). The bug was that it didn't because I didn't escape the &. On seeing that, I thought, oh well, at least I injected OFF which is code..(I wasn't trying to print OFF by the way). But phatfingers says (and his definition seems sensible) that it's not code injection unless it breaks out of the statement it is passed into, and contains a new one. So injecting a keyword into a statement doesn't cut it and isn't really, or just isn't, code injection. – barlop Nov 25 '11 at 08:36
1

There are multiple applications of injection one can generalize as "language injection". SQL Injection and Cross Site Scripting are the most popular, but others are possible.

In your example, the ECHO statement isn't actually performing the delete, so I wouldn't call that injection. Instead, the delete happens outside of the invocation of the batinjection script itself.

phatfingers
  • 9,770
  • 3
  • 30
  • 44
  • To help clarify, try "dir & dir". Note that dir is executed twice, but it's not a result of an injection vulnerability in your dir binary-- you're just running multiple commands on one command line. – phatfingers Nov 24 '11 at 09:14
  • +1 for spotting that about the & but it's a side issue (albeit a highly significant one) more relevant as a comment. – barlop Nov 24 '11 at 09:36
  • what if you do batinjection "OFF & DEL c.c"? – vidstige Nov 24 '11 at 09:40
  • @vidstige see comments to my question, it won't work (won't inject). 'cos e.g. echo "ABC & DIR" won't read as ECHO ABC & DIR. The quotes make it just echo with quotes ECHO "ABC & DIR". WHat would work(inject) is no quotes, and if the batch file says %* instead of %1 – barlop Nov 24 '11 at 14:46
  • 1
    @barlop, your batch file is vulnerable to injection as-is, but you aren't injecting anything into it, even with the changes you're proposing in your prior comment. Try, "batinjection ^&dir". – phatfingers Nov 24 '11 at 17:59
  • ^&dir very smooth.. you deserve an accept for that one + your other good points. – barlop Nov 24 '11 at 18:45