[UNIX] Ultimate PHP Board Multiple Vulnerabilities
- From: SecuriTeam <support@xxxxxxxxxxxxxx>
- Date: 20 Jun 2006 14:06:20 +0200
The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion
The SecuriTeam alerts list - Free, Accurate, Independent.
Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html
- - - - - - - - -
Ultimate PHP Board Multiple Vulnerabilities
------------------------------------------------------------------------
SUMMARY
" <http://www.myupb.com/ourscripts_upb.php> UPB is a forum/message board
script."
Improper design and lack of user input filtering allows attackers to
perform Multiple code executions, Private Key Collision Gene,
Decryption/Encryption, Session Management and Multiple Directory
Traversals in Ultimate PHP Board.
DETAILS
Vulnerable Systems:
* Ultimate PHP Board version 1.96 GOLD
Cryptography:
The Cryptographic algorithm used in Ultimate PHP Board is unique. This is
a huge red flag, there are many public Cryptographic algorithms that are
far more secure than this one. The Cryptographic algorithm used is a
symmetric key block cypher. This block cypher is two way and has a key.
There are Two cryptography issues affecting this application. One is an
implementation issue, the other is a non-trivial attack against the block
cypher its self.
The implementation issue is that the key used to encrypt and decrypt
*should* have been private. The fact that this key is a static value
distributed with the web application, allows for the non brute force
decryption of passwords in a default installation of Ultimate PHP Board.
This fast decryption is provided in the exploit code. A very simple
patch for this implementation issue would be to generate a random key
before using the block cypher.
The encryption and decryption can be found in:
/textdb.inc.php line 324:
function t_encrypt($text,$key){
There is another issue affecting this block cypher, the generation of key
collisions. This is a NON-Trivial attack on this block cypher. What is
needed is a plain text value and its corresponding cypher text. This
can be obtained by legitimately singing up for an account then singing
in. The password used to login is the plain text, and the cypher text is
the pass_env cookie value. With the plain and cypher text data an
offset can be generated. This offset can be used to generate up to 256
key collisions. The offset alone can be used for encryption and
decryption.
the authors encryption algorithm can be expressed as:
cypher_text[x] = text[x] + key[x] - key[x+1]
or
cypher_text[x] - text[x] = key[x] key[x+1]
This creates an offset:
offset[x] = key[x] key[x+1]
offset[x] = cypher_text[x] - text[x]
which means that every key has an offset and the offset alone can be used
to encryption and decryption:
cypher_text[x] = text[x] + offset[x]
text[x] = offset[x] - cypher_text[x]
All 256 possible key collisions can be generated from the key collision.
Collision is possible because the starting character does not affect the
algorithm, what matters is the difference between characters. The
encoding is using the extended ascii set: http://www.lookuptables.com/ .
The exploit code generates keys 0-255, or 256 possible combinations. If
you give the function a number like 256, the character will overflow
resulting in the value of 0, 257 is 1, 258 is 2, and so on.
Some examples using the key distributed with Ultimate PHP board 1.96 Gold
Key:120 = xeozzkjoggo
Cypher:D((4D72@9(
Plain :1234567890
This is the first eleven characters of the real key:
Key:119 = wdnyyjinffn
Cypher:D((4D72@9(
Plain :1234567890
Key:118 = vcmxxihmeem
Cypher:D((4D72@9(
Plain :1234567890
The same keys in uppercase are also collisions:
Key:88 = XEOZZKJOGGO
Cypher:D((4D72@9(
Plain :1234567890
Key:87 = WDNYYJINFFN
Cypher:D((4D72@9(
Plain :1234567890
Key:86 = VCMXXIHMEEM
Cypher:D((4D72@9(
Plain :1234567890
Not all of the keys print out properly due to control characters in the
ASCII set, however all keys can be used for encryption and decryption,
which is shown in the exploit code.
An attack is possible using this key collision weakness. For the sake of
argument lets say that the encryption algorithm is implemented correctly
with a secure private key. An attacker could change there password to a
very long string then login using that long password. If the attacker
creates the longest password, then the attacker will be able to decrypt
every password by access /db/users.dat using the exploit code. I wonder
how many people have the same password for there e-mail account as there
Ultimate PHP Board account...
First of all a block cypher should not be used for a password, one should
use a one way hash. Second of all there are many many publicly available
encryption algorithms that are in orders of magnitude more secure than
this. Keep in mind SHA-0, SHA-1 and MD5 are broken, so please STOP USING
THEM. Even though MD5 is broken it is still more secure than this current
system.
Session:
Due to the way that sessions are handled decryption of the password is not
needed to login. Sessions are immortal; the web application does a
string compare of the cookie with the value in the database. On a
default install of UPB the administrative login is user name: Admin
password: admin This login has the most privileges on the board with
the value of 3. This is the first account with the id value of 1.
The cookie value for this account is:
Cookie: user_env=Admin; pass_env=tZbi%7D; power_env=3; id_env=1
This cookie should allow authentication on a default install of UPB. This
information session is immortal. when you login with your user name and
password on the system your cookie is given a time stamp, however this
time stamp is not necessary for authentication.
Session management has been done so well in PHP with session_start() and
the $_SESSION supper global it seems a shame to try and replace it. You
should never use a login name and password for a session ID. The value
should be a securely randomly generated value that is only used for that
session.
Database:
UBP uses an in house developed database implementation called TextDB.
Text Database was written by Tim Hoeppner (aka Pilot) on the Ultimiate
PHP Board (UPB) Team . I'm glad i had the privilege to find these
NON-SQL database injection attacks. This database currently suffers from
two major vectors of injection. One vector allow for the injection of an
arbitrary login. The other allows an attacker to write and over-write an
arbitrary file on the remote system.
In order to understand the attack the reader should get some background
information about the database.
One line in the database looks like this:
Admin<~>tZbi}<~>3<~><~><~>on<~><~>http://<~>db/users.dat<~><~><~><~><~>20<~><~>1
the corresponding users.def :
user_name<~>password<~>level<~>email<~>view_email<~>mail_list<~>location<~>url<~>avatar<~>icq<~>aim<~>msn<~>sig<~>posts<~>date_added<~>id
The database is a (FILO) First In Last Out Stack, each cell is separated
by an '' and each record is separated by a new line. This storage system
is not much more complex than Coma Separated Values(CSV) system of data
storage.
There are two values which could be described as special words: [NL] and
[NR]. The database records a newline character '\n' as the [NL] key
word. The [NR] word is used to pass multiple records to the add()
function, thus the [NR] is converted into a '\n'.
file /UBP/textdb.inc line 21 in function add($record, $db, $new) :
$every = explode("[NR]", $record);
Try navigating to register.php fill out the forum then enter this as the
signature:
s<~>0<~>2006-04-17[NR]NewAdmin<~>m<~>3<~><~><~><~><~>1<~><~><~><~><~>13<~><~>1<~>4000000000
(note: there are no new lines or quote marks in the exploit string)
This will create and administrator login with the login name of: NewAdmin
and the password is Z. It is possible to inject an administrative
account regardless of the status of magic_quotes and does not rely on
manipulating a global variable.
The function add() puts a unique id at the end of the string and is
stored in the cell name id . The id needs to be known in order to
reconstruct a valid cookie session data. This exploit string is
injecting a full record, add generates the sequential id and adds it to
the end of the record which does not affect execution.
Directory Traversal:
The second type of database injection in this system allows an attacker to
drop an arbitrary file. This vulnerability leads to code execution. In
version 1.8 and below the entire database folder /db/ was viewable by
your web browser, the patch uses an apache .htaccess file which does not
allow access to anyone using apache. With this database injection its
possible to overwrite the .htaccess with a commented out junk data
allowing an attacker full read access to the database. Over writing of
files is important, mysql's into outfile will NOT allow you to
overwrite a file.
This is possible regardless of the status of register_globals; however
magic_quotes does need to be off because a NULL byte must be injected to
control the file extension.
The reason why the register_globals doesn't matter is because the
following code implements the same functionality as register_globals:
func.inc.php line 19:
while (list ($key, $val) = each ($HTTP_GET_VARS)) {
$$key = $val;
}
while (list ($key, $val) = each ($HTTP_POST_VARS)) {
$$key = $val;
}
while (list ($key, $val) = each ($HTTP_COOKIE_VARS)) {
$$key = $val;
}
Simple yet so effective, elegant because of its power and size. These
nine lines of code result in the systematic failure of security. Its
effects cascade throughout the program allowing an attacker to assume
total control. Smaller variations of this exist, but each of them have
there own beauty.
An arbitrary file can be created on the remote system using directory
traversal attack accessible from newpost.php. The file name is
controlled by $id. By injecting a ../ the attacker can control what
directory to inject the file. By injecting a hex encoded null byte %00 at
the end of $id the attacker can control the extension type. This is
because PHP is built on C. In the C programming language (as well as
others) a null byte signify the end of the data in an array. The null
byte is absolutely necessary in an array, without it the C function will
not know when to stop and could continue to read until it wonders into
memory not owned by the process this will cause a segmentation fault,
trespassers will be shot.
$id is only validated if it is sent as a GET; as a result of registering
globals we can send $id as a post or a cookie and still be able to hit the
add() function. UBP does check for '<' and '>', this prevents the
injection of javascript and php, however by no means stops the injection
of perl CGI. The add() function also introduces a lot of junk data,
however this junk can be commented out for some attacks. Such as
commenting out the .htaccess file.
$icon needs to be controlled by the attacker because it allows an
attacker to control the first few characters of the file. $icon must
exist in the POST or the request is rejected. The $message which is sent
via post contains the arbitrary perl cgi to be executed by the remote
server:
[NR]use CGI qw(:standard);print header;print "one";print " two";print "
three";#
[NR] is used again in this attack. Instated of using it to inject an
administrative account, its used to get a vital new line for formating
the dropped file. There can't be any new lines in the perl payload
itself and it needs to end with a '#' to comment out junk created by the
database implementation.
Using this database injection an attacker can drop a perl cgi file,
however cgi must be made executable on a Unix type system. These rights
can be given to the file using chmod. A user on a Unix type system can
only chmod files that that user owns. This means that if you are using
chmod within PHP then apache's user must own the file. A file created
by PHP can be chmod'ed by PHP; thus the payload can be chmod()'ed in this
way.
file UPB/close.php line: 12
chmod("./db/$id/$t_id.dat", 0555);
both $id and $t_id can be controlled by an attacker. Directory traversal
is possible using '../../' and '%00' (null byte in hex) can be used to
remove .dat.
chmod 555 give a file the following rights:
-r-xr-xr-x
That makes any file on the system an attacker chooses to be executable and
readable. Its ironic that this close feature was created to prevent
access but instead its a critical part in remote code execution process.
Remote code execution using the database could have been foiled on most
system by changing only ONE BIT. That is decreasing the byte value of 5
by one bit, making it 554. chmod 555 is most likely three bits off from
what was intended which is chmod 444 which makes a file read only:
-r r r--
There is also open.php which suffer from the same directory traversal
attack making a file chmod 666. This allows an attacker to make an
arbitrary file readable and writable. chmod 666 gives a file the
following access rights:
-rw-rw-rw-
Using this database to drop a Perl CGI is not a very realistic remote code
execution attack. The reason why is that not only does perl cgi have to
be installed, but the attacker has to know the location of perl. This
attack vector was created to show the security issue in this NON-SQL
database implementation.
Attackers don't have to use such a theoretical attack to obtain code
execution, instead there is fairly straight forward PHP execution
available in the administrative area. Its the best method for remote code
execution on this system. The php code is stored and then included during
execution. One could easily install a php-back-door into the main page.
This is also a great point of entree for a type 2 (heighest level) cross
site scripting issue. Type 2 XSS is great for subjecting browsers to
exploits. This PHP remote code execution attack could be stopped by
storing the configuration information in the database.
With administrative access one is able to then access the vulnerable
function calls in:
admin_chatconfig.php admin_configcss.php admin_config.php
admin_config2.php
The data is sent to corresponding file 'do' file :
admin_chatconfigdo.php admin_configcssdo.php admin_configdo.php
admin_configdo2.php
Every item is vulnerable to code execution; in total there are 120
individual variables that allow for code execution. Of course only one of
which is necessary to gain control.
For any of the configuration fields add this Prof of concept code to the
end:
";phpinfo(); $crap="1
All functions add the nectary ; to complete the line and then the
payload is written to a configuration file and then included during
execution. To remove the php injection go back to the injected
config.php and and submit the configuration values without modification.
A fix for this hole is to store these configuration values in the
database.
There are two separate methods of gaining administrative access and remote
code execution. The first method that is the easiest and the most sure
fire. First one needs to inject an administrative login, then use the
php injection in the configuration files to execute code. A second
method of gaining administrative access could be used, by gaining access
to /db/users.dat then decrypting an administrative password . The other
method of code execution would be to sign up for an account then use the
perl cgi upload attack which is available in the exploit code.
Ultimate PHP Board is a huge target for botnet spammers. For one all
working Ultimate PHP Boards need to be able to e-mail new users there
randomly generated password for there first login. So all fully
functional Ultimate PHP Boards can be used to send spam. Also Ultimate
PHP Board's database will contain a valid e-mail addresses for every user.
IRC is a popular method of controlling a botnet, Ultimate PHP Board
has a chat feature that could be used in the same way. Lastly the Type 2
Cross Site Scripting could be used to further spread the botnet by
exploiting code execution holes in visitor's web browsers.
At the top of the vendors site it reads :
All of the features you expect, without the SQL mess
How dare you insult SQL, As a LAMP developer I find that very offensive.
SQL is an amazing system that I am grateful for. You should be ashamed
for saying that when what you have to offer is not even close to as
functional or secure. There is no advantage in using these in house
abominations of security. It is not a waste of time to develop a rival
technology to the main stream, after all thats how these systems get
replaced. But when you developed a rivaling technology with no intention
of surpassing readily available Open Source solutions, you are just
wasting your time. The Ultimate PHP Board Development team isn't bad,
however they wasted a lot of time developing functions that have already
been developed.
This database implementation does make this web application easier to
install, but at what cost? Obviously this database implementation is
vulnerable to injection, even remote code execution! A better solution
is to utilize some kind of SQL database, at the very least SQLite which
has been built into php5. UBP could use SQLite and still keep its zero
configuration install.
I suggest removing the use of global variables, this has been shown to be
a security train wreck. Such a bad security issue that its being flat out
removed in PHP6. I also suggest using PHP's built in session handling
functions which work very well. The Cryptography issues should be solved
by using a mainstream one way hash function. In general UBP seem to be
trying to reinvent the wheel. Basic functionality such as the database,
sessions, and encryption have been taken care of so that the average
developer can work on the real problem at hand. Doing your own
implementation of such heavily used tools will most likely result in
inefficient and insecure code.
ADDITIONAL INFORMATION
The information has been provided by <mailto:mbrooks@xxxxxxxxxxxxxxxxx>
mbrooks.
The original article can be found at:
<http://www.kliconsulting.com/users/mbrooks/UPBadvisory.rtf>
http://www.kliconsulting.com/users/mbrooks/UPBadvisory.rtf
========================================
This bulletin is sent to members of the SecuriTeam mailing list.
To unsubscribe from the list, send mail with an empty subject line and body to: list-unsubscribe@xxxxxxxxxxxxxx
In order to subscribe to the mailing list, simply forward this email to: list-subscribe@xxxxxxxxxxxxxx
====================
====================
DISCLAIMER:
The information in this bulletin is provided "AS IS" without warranty of any kind.
In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.
- Prev by Date: [EXPL] CesarFTP Buffer Overflow (Metasploit)
- Next by Date: [EXPL] Ultimate PHP Board Multiple Vulnerabilities (Exploit)
- Previous by thread: [EXPL] CesarFTP Buffer Overflow (Metasploit)
- Next by thread: [EXPL] Ultimate PHP Board Multiple Vulnerabilities (Exploit)
- Index(es):
Relevant Pages
|