ns3 criptografia de senha / algoritmo de hashing (Zyxel)

1

Eu tenho que restaurar uma senha na minha conexão Zyxel Keenetic for PPPoE. Em running-config, ele possui uma senha criptografada em algum tipo de algoritmo de criptografia / hash chamado ns3 . Alguém sabe o que é esse ns3 ? Existe um software de bruteforcing ou descrição detalhada sobre este algoritmo?

Eu sei que a senha é de cerca de 7-9 sinais, então eu acho que é possível usar o bruteforce ...

(config)> show running-config
! $$$ Model: ZyXEL Keenetic II
! $$$ Version: 2.0
! $$$ Agent: http/ci
! $$$ Last change: Mon,  2 Nov 2015 10:11:09 GMT
! $$$ Md5 checksum: d1e916f8e32515c1ba8182e3ee6b6a85
system
    set net.ipv4.ip_forward 1
    set net.ipv4.tcp_fin_timeout 30
    set net.ipv4.tcp_keepalive_time 120
    set net.ipv4.netfilter.ip_conntrack_tcp_timeout_established 1200
    set net.ipv4.netfilter.ip_conntrack_max 4096
    set vm.swappiness 100
    hostname packo-router
    clock date  2 Nov 2015 13:11:45
    clock timezone Europe/Moscow
    domainname PCK
!
ntp server 0.pool.ntp.org
ntp server 1.pool.ntp.org
ntp server 2.pool.ntp.org
ntp server 3.pool.ntp.org
known host SAMSUNG_NOTEBOOK_PACKO ommited
known host home_main_packo ommited
access-list _WEBADMIN_GuestWiFi
    deny tcp 0.0.0.0 0.0.0.0 192.168.1.0 255.255.255.0
!
isolate-private
dyndns profile _WEBADMIN
!
interface Switch0
    port 4
        mode access
        access vlan 1
    !
    port 3
        mode access
        access vlan 1
    !
    port 2
        mode access
        access vlan 1
    !
    port 1
        mode access
        access vlan 101
    !
    port 0
        mode access
        access vlan 101
    !
    up
!
interface Switch0/VLAN1
    description "Home VLAN"
    security-level private
    ip dhcp client dns-routes
    ip dhcp client name-servers
    up
!
interface Switch0/VLAN101
    description InetPort
    security-level public
    ip address dhcp
    ip dhcp client dns-routes
    ip dhcp client name-servers
    ip mtu 1500
    ip global 700
    ip adjust-ttl inc 1
    igmp upstream
    up
!
interface WifiMaster0
    country-code RU
    compatibility BGN
    channel width 40-below
    power 10
    up
!
interface WifiMaster0/AccessPoint0
    name AccessPoint
    description "Wi-Fi access point"
    mac access-list type none
    security-level private
    authentication wpa-psk ns3 <ommited>
    encryption enable
    encryption wpa2
    ip dhcp client dns-routes
    ip dhcp client name-servers
    ssid PCK
    hide-ssid
    wmm
    up
!
interface WifiMaster0/AccessPoint1
    name GuestWiFi
    description "Guest access point"
    mac access-list type none
    security-level private
    authentication wpa-psk ns3 <ommited>
    encryption enable
    encryption wpa2
    ip address 192.168.2.1 255.255.255.0
    ip dhcp client dns-routes
    ip dhcp client name-servers
    ip access-group _WEBADMIN_GuestWiFi in
    ssid ArGuest
    up
!
interface WifiMaster0/AccessPoint2
    mac access-list type none
    security-level public
    ip dhcp client dns-routes
    ip dhcp client name-servers
    down
!
interface WifiMaster0/AccessPoint3
    mac access-list type none
    security-level public
    ip dhcp client dns-routes
    ip dhcp client name-servers
    down
!
interface WifiMaster0/WifiStation0
    security-level public
    encryption disable
    ip address dhcp
    ip dhcp client dns-routes
    ip dhcp client name-servers
    up
!
interface UsbModem0
    description MegaFon
    usb device-id 12d1 1001
    modem connect dial *99#
    no ipv6cp
    lcp echo 30 3
    ipcp default-route
    ipcp name-servers
    ipcp dns-routes
    ipcp vj cid
    no ccp
    security-level public
    authentication identity gdata
    authentication password ns3 QP/a3C96cTqJxMboZoZojIZB
    authentication chap
    ip dhcp client dns-routes
    ip dhcp client name-servers
    ip mtu 1400
    ip global 300
    ip apn internet
    connect
    up
!
interface Bridge0
    name Home
    description "Home network (Wired and wireless hosts)"
    inherit Switch0/VLAN1
    include AccessPoint
    security-level private
    ip address 192.168.1.1 255.255.255.0
    ip dhcp client dns-routes
    ip dhcp client name-servers
    igmp downstream
    up
!
interface PPPoE0
    description Internet
    no ipv6cp
    lcp echo 30 3
    ipcp default-route
    ipcp name-servers
    ipcp dns-routes
    no ccp
    security-level public
    authentication identity t5ovh5rwxa
    authentication password ns3 57QZ+pHpr1U563wnqus9ZIKM
    ip dhcp client dns-routes
    ip dhcp client name-servers
    ip mtu 1400
    ip global 1000
    ip tcp adjust-mss pmtu
    connect via Switch0/VLAN101
    up
!
ip dhcp pool _WEBADMIN
    range 192.168.1.10 192.168.1.109
    default-router 192.168.1.1
    dns-server 192.168.1.1
    lease 25200
    bind Home
    enable
!
ip dhcp pool _WEBADMIN_GUEST_AP
    range 192.168.2.2 192.168.2.21
    lease 25200
    bind GuestWiFi
    enable
!
ip dhcp host ommited 192.168.1.2
ip dhcp host ommited 192.168.1.3
ip nat Home
ip nat GuestWiFi
ppe
upnp lan Home
user admin
    password md5 ommited
    password nt ommited
    tag cli
    tag http
    tag cifs
    tag printers
!
service dhcp
service dns-proxy
service cifs
service http
service telnet
service ntp-client
service upnp
cifs
    share PrinterNW "C:\printer"
    automount
    permissive
!
printer 03f0:3d17
    name "HP LaserJet P1005"
    type cifs
    port 9100
    firmware storage:/sihpP1005.dl
!
!
(config)>
    
por Евгений Артеменко 10.09.2017 / 14:54

1 resposta

1

O algoritmo de criptografia foi submetido a engenharia reversa por Felis-Sapiens no Antichat.ru , que também postou um script Python para descriptografar as senhas:

$ ./zyxel_scramble.py decode QP/a3C96cTqJxMboZoZojIZB
gdata

$ ./zyxel_scramble.py decode 57QZ+pHpr1U563wnqus9ZIKM
z4c4StLAa6

A ferramenta pode ser encontrada em post # 7 ou aqui :

#!/usr/bin/env python3
#
# zyxel_scramble.py
#
# author: Felis-Sapiens
#
# Decode password from ZyXEL config (NDMS V2)

import sys
from base64 import b64decode, b64encode
from hashlib import md5

def first_step(password, x1, x2):
    x1 &= 0xff
    x2 &= 0xff
    for i in range(len(password)):
        password[i] = (password[i] ^ x2) & 0xff
        x2, x1 = x1 + x2, x2
    return password

def second_step(password):
    x = 0
    for b in password:
        x ^= b
    for i in range(1,8):
        a = ((x >> i) ^ (~x << i)) & 0xff
        x = ((a << i) ^ (~a ^ x)) & 0xff
    for i in range(len(password)):
        password[i] ^= x
    return password


def scramble_decode(password):
    if len(password) % 4 != 0:
        password += '=' * (4 - len(password) % 4)

    password = list(b64decode(password))
    length = len(password)
    if length not in [0x12, 0x24, 0x48]:
        print('ERROR: invalid input length')
        return

    a2 = length // 8
    x2 = password[a2]
    del password[a2]

    a1 = x2 % (length - 1)
    x1 = password[a1]
    del password[a1]

    password = second_step(password)
    password = first_step(password, x1, x2)

    zero_pos = password.index(0)
    if zero_pos != -1:
        length = zero_pos
    return bytes(password[:length]).decode()

def scramble_encode(password):
    old_length = len(password)
    length = len(password)
    if length < 0x13:
        length = 0x12
    elif length < 0x25:
        length = 0x24
    elif length < 0x49:
        length = 0x48
    else:
        print('ERROR: password is too long')
        return

    password = password.encode()
    md5_digest = md5(password).digest()

    password = list(password)
    if length != old_length:
        password.append(0)
        for i in range(old_length+1, length-2):
            password.append((password[i-old_length-1] * 2 + md5_digest[2 + i%14]) & 0xff)

    x1 = md5_digest[0]
    x2 = md5_digest[1]
    password = first_step(password, x1, x2)
    password = second_step(password)
    password.insert(x2 % (length - 1), x1)
    password.insert(length // 8, x2)
    return b64encode(bytes(password))

def main():
    if len(sys.argv) < 3:
        print('Usage: zyxel_scramble.py decode|encode password')
        return

    if sys.argv[1] == 'decode':
        password = scramble_decode(sys.argv[2])
    elif sys.argv[1] == 'encode':
        password = scramble_encode(sys.argv[2])
    else:
        print('ERROR: unknown command', sys.argv[1])
        return
    if password is not None:
        print(password)

if __name__ == '__main__':
    main()
    
por 10.09.2017 / 15:48