Posts Tagged ‘Command Injection’

Some time ago, Luca phoned me and said: Hey, I’ve just written a simple backdoor for Windows! I used netcat and a Batch script. No need to compile! Just few lines of interpreted code!

I answered back: What about data encryption? You had to use anything like crypcat or other tricks such as SSH tunneling.

He replied: I didn’t need data encryption then netcat was sufficient. I bet you won’t able to log in!

I concluded: I’m not a security expert but I can’t draw back! Where to connect? Give me your IP and the port you are using…

He gave me his IP and the port number.

The game started. I trivially got connected by using this command:

c:\Users\Marco> nc IP PORT

His machine replied immediately, sending back some characters that made a basic (textual) login mask:

Please insert your username and your password:

username>

I gave a try:

Please insert your username and your password:

username> luca

 

Please insert your username and your password:

username> luca
password>

 

Please insert your username and your password:

username> luca
password> 04031988

 


Please insert your username and your password:

username> luca
password> 04031988

Login Error!

And the application stopped the connection. My friend chuckled and said: It’s not easy, is it?! My access credentials are not so stupid!

I had to think about the script he wrote. I had to discover a flaw. This was a Secure Programming matter and I read one of the best books about this topic: Secure Programming with Static Analysis, by Brian Chess and Jacob West.

I thought that he used Batch. I knew it could suffer from Command Injection: when the script requires an input (say, the username), the idea is to feed it with a special string, containing shell metacharacters. When the batch interpreter, for example, makes a comparison (say, with an IF statement), it’ll unwittingly execute my malicious code. I assumed he had written something like:


if "%username%" == "REAL USERNAME" --check the password--

In this case, I could forge this special string:


a" == "a" cmd

The “executed” IF statement could be (when the variable ‘username’ got expanded) :


if "a" == "a" cmd " == "REAL USERNAME" --check the password--

The IF test is obviously true and then cmd will be run. No matter what comes after cmd, it will cause an error (bad syntax) but only after cmd ends its execution!

It surprisingly worked:

Please insert your username and your password:

username>a" == "a" cmd
password>never mind
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Users\Luca\>

Bingo! We got access to the machine! My friend got astonished: You cheated, didn’t you?!

I replied: No, I’ve discovered you did not validate my input! That’s all.

I will spare you the end of our conversation. He was snivelling all the time.

Let’s talk about some details of his flawed script.

The ingredients of our story are netcat and Batch. In short, netcat opens TCP/UDP sockets, for free. You can create a peer-to-peer chat or a port scanner using less than 10 characters of code. A certain option permits to execute a program when the connection gets established. For example, in our story, Luca created a TCP server, listening at port 3000. When someone gets connected, the program (Luca’s script) got executed. Here’s the code:

C:\Users\Luca\>nc -l -p 3000 -e bad_backdoor.bat

Batch is the Windows scripting language, apparently it seems underpowered (lots of people say that it is not a proper programming language) but I don’t think so because I created a heap of useful scripts, complete applications and other programming tricks. Old times. Good times. In any case, if you want to learn, I recently found this amazing website containing a lot of tricks and good tips.

What about our story? – you’re whinging.

Ok, I’ll talk about that.

Command Injection vulnerabilities exist when a program executes a command that an attacker can influence. These vulnerabilities take two primary forms:

  • An attacker can change the command that the program executes: The attacker explicitly controls what the command is.
  • An attacker can change the environment in which the command executes: The attacker implicitly controls what the command means.
We are mostly in the first form. The second form occurs when an attacker can change the meaning of a command by altering an environment variable or by inserting a malicious executable in the program’s search path.
Luca convinced himself of sending me his code. Let me show you his script:
@echo off
echo Please insert your username and your password:
echo.
set /p username=username^>
set /p password=password^>

if  "%username%" == "his_username" (
	if "%password%"=="his_pwd" goto loggedin
)

echo Login Error
pause>nul
exit

:loggedin

call cmd

echo "Bye..."

exit

Simple but unsecure code.

I repeat why it is a gip: the input is not handled. I can deceive the IF statement and make it execute a command to my liking (for example launching a shell!). This is possible by mixing characters and metacharacters (a metacharacter can express an idea about how to process the characters that follow the metacharacter). For example, we can force the IF statement to compare two trivially equal strings (“a” == “a”) and execute a shell (cmd) if that comparison succeds (IF “a” == “a” cmd). Our malicious username can be:  a” == “a” cmd .

What is the moral of the story? Don’t trust input. Perform checks or metacharacters substitution. Here are some ideas for Batch programmers:

  • Replace possibile “malicious” strings: the expression set username=%username:cmd=% cuts off the presence of “cmd” in your username variable. Similarly,  set username=%username:”=% blots out the metacharacter ” .
  • Rename system executables, change paths and defend your environment.
  • Perform a character-by-character comparison. In Batch you can do that by extracting substrings, iteratively: set first_character=%username:~0,1%set second_character=%username:~1,1%, etc. This is the most effective (although tedious) way to validate the user input in Batch. The script I’m going to show you has a flaw, find it!
  • Shrink your input-variables to their expected lengths.

I sended the new script back to Luca:

@echo off

echo Please insert your username and your password:

echo.

set /p username=username^>

set /p password=password^>

rem     no & please (metacharacter substitution)

set username=%username:&=%

set password=%password:&=%

rem     your username's length (shrinking)

set username=%username:~0,12%

rem     your password's length (shrinking)

set password=%password:~0,7%

rem     no " please (metacharacter substitution)

set username=%username:"=%

set password=%password:"=%

if "%username%" == "his_username" (

       if "%password%"=="his_pwd" goto loggedin

)

echo Login Error

pause>nul

exit

:loggedin
rem     new executables and paths
call %absolutepath%\my_new_cmd

echo "Bye..."

exit

I know what you are thinking. Efficiency, huh? Well, dont’ care about efficiency! First of all, the login is not frequent and the input strings are hopefully short. Second, remember that, in this context, security is a critical matter: what if you are the fastest login service in the world but anyone can join the party? For the umpteenth time software development reveals its real nature: tradeoffs. Choose the best compromise you need and you can afford! Good luck if you want to write the both fastest and safest software!

I’ve never known if Luca employed a new script, but he definitely decided to consider input validation and security issues!

This was the first “Security tale” and I hope you’ll never be in Luca’s shoes!

Don’t forget to spread the word: Validate the user input!