Fanomezana fiara Yealink T19 + boky adiresy dynamique

Rehefa tonga niasa ho an'ity orinasa ity aho dia efa nanana angon-drakitra momba ny fitaovana IP, mpizara maromaro misy asterisk ary patch amin'ny endrika FreeBPX. Ankoatr'izay, ny analoga PBX Samsung IDCS500 dia niara-niasa ary, amin'ny ankapobeny, dia ny rafi-pifandraisana lehibe ao amin'ny orinasa, ny IP telephony dia niasa ho an'ny departemantan'ny varotra ihany. Ary ny zava-drehetra dia ho nanohy ny mahandro toy izany, fa indray andro tsara dia nomena ny didy hamindra ny olona rehetra amin'ny IP telephony, fe-potoana nifanarahana, fitaovana novidina ary ny drafitra hamindra ny orinasa ho amin'ny taonjato faha-21.
Ny zavatra voalohany manomboka manahy amin'ny toe-javatra toy izany dia ny fitomboan'ny isan'ny telefaonina sets izay mila tantanina na ahoana na ahoana, ny zavatra faharoa izay tena mampanahy dia ny telefaonina boky. Raha afaka manampy antsika amin'ny voalohany ny Manager Endpoint (izay, raha ny marina, dia nesorina tamin'ny dikan-teny farany an'ny FreePBX), dia nisy fanontaniana nipoitra tamin'ilay boky:

  • Voalohany, ahoana no hiantohana ny fahamarinany rehefa miova tsy tapaka ny toerana/fahadiovan'ny mpampiasa?
  • Faharoa, ny fomba depersonalize tanteraka ny finday. Ary tsy fenoy ny anaran'ny contact isaky ny mandeha?

Nahaliana ny olana, tsy niandry ela ny vahaolana. Ankehitriny dia homeko ny lisitra feno, ary avy eo dia hojerentsika izany.

from scapy.all import sniff
from scapy.layers.inet import IP
import mysql.connector
import ldap
import getpass
import tftpy
import requests
import os
import time
from string import replace

def conn_ldap(login):
    ad = ldap.initialize('ldap://***.local')
    ad.simple_bind_s('voip@***.local', 'password')
    basedn = 'OU=IT,DC=***,DC=LOCAL'
    basedn_user = 'OU=***,OU=***,DC=***,DC=LOCAL'
    scope = ldap.SCOPE_SUBTREE
    filterexp = "(&(sAMAccountName=" + login + ")(ObjectClass=person))"
    filterexp2 = "(&(ObjectClass=organizationUnit))"
    attrlist = ['cn']
    attrlist2 = ['OU']
    search = ad.search_s(basedn, scope, filterexp, attrlist)
    adname = search[0][1]['cn'][0].decode('utf-8')
    if adname == ' ':
        search = ad.search_s(basedn_user, scope, filterexp2, attrlist2)
        for i in range(1, len(search)+1):
            group = search[i][1]['ou'][0]
            basedn_user2 = 'OU='+group+','+basedn_user
            search = ad.search_s(basedn_user2, scope, filterexp, attrlist)
            adname = search[0][1]['cn'][0].decode('utf-8')
            if adname != ' ':
                return adname
        adname = search[0][1]['cn'][0].decode('utf-8')
    ad.unbind_s()
    return adname


def tftp_file_change(config,place,adname,current_account,current_account_password):

    client = tftpy.TftpClient("192.168.0.3", 69)
    client.download('template.cfg', place)
    fileread = open(place, 'r')
    line = fileread.readlines()
    fileread.close()
    line[5] = (('account.1.label = ').encode('utf-8') + adname.encode('utf-8') + 'n')
    line[2] = (('account.1.auth_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[3] = (('account.1.display_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[6] = (('account.1.password = ').encode('utf-8') + current_account_password[0][0] + 'n')
    filewrite = open(place, 'w')
    for i in line:
      filewrite.write(i)
    filewrite.close()
    print place
    print config
    client.upload(config,place)


def get_phone_inform(ipaddr):
    fileconf = requests.get('http://admin:admin@'+ipaddr+'/servlet?phonecfg=get[&accounts=1]')
    conf = fileconf.text.split('|')
    current_account = conf[2]
    return current_account


def sniff_frame():
    pcapf = sniff(count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060")
    if len(pcapf) == 0:
        exit()
    frame = pcapf[0]
    macaddr = frame.src
    print macaddr[:8]
    if macaddr[:8] != '80:5e:c0':
        exit()
    ipaddr = frame[0][IP].src
    return macaddr, ipaddr


def conn_mysql(query,fquery,macaddr,qwery2):
    connect = mysql.connector.connect(host='192.168.0.3', database='voip', user='voip_wr', password='***')
    cursor = connect.cursor()
    cursor.execute(fquery)
    state = cursor.fetchall()
    state = bool(state[0][0])
    if state == True:
        cursor.execute(qwery2)
        connect.commit()
        connect.close()
    else:
        cursor.execute(query)
        connect.commit()
        connect.close()


def check_account(current_account):
    connect = mysql.connector.connect(host='192.168.0.3', database='asterisk', user='voip_wr', password='***')
    cursor = connect.cursor()
    qwery = 'select data from sip where id=' + current_account + ' and keyword="secret";'
    cursor.execute(qwery)
    password = cursor.fetchall()
    if password == ' ':
        exit()
    else:
        return password


if __name__ == '__main__':
    macaddr, ipaddr = sniff_frame()
    current_account = get_phone_inform(ipaddr)
    current_account_password = check_account(current_account)
    macaddr = macaddr.replace(':', '')
    ipaddr = ipaddr.decode('utf-8')
    adname = conn_ldap(getpass.getuser())
    query = 'INSERT INTO station (mac, ip, name, number) VALUES (' + '"' + macaddr + '",' + '"' + ipaddr + '",' + '"' + adname + '",' + '"' + get_phone_inform(ipaddr) + '"' + ')'
    qwery2 = 'UPDATE station SET ip=' + '"' + ipaddr + '"' + ', name=' + '"' + adname + '"' + ', number=' + '"' + get_phone_inform(ipaddr) + '"' + ' WHERE mac=' + '"' + macaddr + '"'
    fquery = 'SELECT EXISTS(SELECT mac FROM voip.station WHERE mac=' + '"' + macaddr + '")'
    query = query.encode('utf-8')
    fquery = fquery.encode('utf-8')
    config = macaddr + '.cfg'
    place = os.path.expanduser("~") + "" + "AppDataLocal" + config
    conn_mysql(query,fquery,macaddr,qwery2)
    tftp_file_change(config,place,adname,current_account,current_account_password)
    requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=AutoP')
    requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=Reboot')

Ny programa dia mandeha amin'ny solosain'ny mpampiasa ary miasa raha toa ka mifandray amin'ny tambajotra amin'ny alàlan'ny telefaona ny solosaina, satria tsy afaka miasa ho vavahady ny Yealink T19.

Voalohany, mila mahatakatra isika raha mifandray izy io? ary inona no mac sy ip ny findainay.

def sniff_frame():
    pcapf = sniff(count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060")
    if len(pcapf) == 0:
        exit()
    frame = pcapf[0]
    macaddr = frame.src
    print macaddr[:8]
    if macaddr[:8] != '80:5e:c0':
        exit()
    ipaddr = frame[0][IP].src
    return macaddr, ipaddr

Eto izahay dia mampiasa ny sniff function avy amin'ny scapy framework, miaraka amin'ny fanampiany dia mahazo fonosana udp efa voafaritra mialoha, miandry 70 segondra ary raha tsy mahazo na inona na inona izahay dia mivoaka.

count=1, timeout=70, filter="dst host 192.168.0.3 and port 5060"

Manaraka, ataontsika antoka fa Yealink tokoa ilay fitaovana ary mamerina ny soatoavina ilaina (ip sy mac).

Amin'ny fampiasana fangatahana manokana, dia mahita ny kaonty ankehitriny amin'ny telefaona izahay. Mba hanaovana izany, dia alaina avy amin'ny telefaona ny fampifanarahana amin'izao fotoana izao ary alaina.

def get_phone_inform(ipaddr):
    fileconf = requests.get('http://admin:admin@'+ipaddr+'/servlet?phonecfg=get[&accounts=1]')
    conf = fileconf.text.split('|')
    current_account = conf[2]
    return current_account

Fantaro ny tenimiafina ho an'ity kaonty ity. Mba hanaovana izany dia mitodika any amin'ny latabatra asterisk.sip sy ny saha data ao anatiny.

def check_account(current_account):
    connect = mysql.connector.connect(host='192.168.0.3', database='asterisk', user='voip_wr', password='***')
    cursor = connect.cursor()
    qwery = 'select data from sip where id=' + current_account + ' and keyword="secret";'
    cursor.execute(qwery)
    password = cursor.fetchall()
    if password == ' ':
        exit()
    else:
        return password

Eny, ho an'ny dingana farany dia mifandray amin'ny ldap AD izahay ary mampiasa sAMAccountName azo tamin'ny alàlan'ny fiasa getpass.getuser() alaivo ny cn an'ny mpampiasa ankehitriny (izay matetika misy ny anarana fenon'ny mpampiasa).

def conn_ldap(login):
    ad = ldap.initialize('ldap://***.local')
    ad.simple_bind_s('voip@***.local', 'password')
    basedn = 'OU=***,DC=***,DC=LOCAL'
    basedn_user = 'OU=***,OU=***,DC=***,DC=LOCAL'
    scope = ldap.SCOPE_SUBTREE
    filterexp = "(&(sAMAccountName=" + login + ")(ObjectClass=person))"
    filterexp2 = "(&(ObjectClass=organizationUnit))"
    attrlist = ['cn']
    attrlist2 = ['OU']
    search = ad.search_s(basedn, scope, filterexp, attrlist)
    adname = search[0][1]['cn'][0].decode('utf-8')
    if adname == ' ':
        search = ad.search_s(basedn_user, scope, filterexp2, attrlist2)
        for i in range(1, len(search)+1):
            group = search[i][1]['ou'][0]
            basedn_user2 = 'OU='+group+','+basedn_user
            search = ad.search_s(basedn_user2, scope, filterexp, attrlist)
            adname = search[0][1]['cn'][0].decode('utf-8')
            if adname != ' ':
                return adname
        adname = search[0][1]['cn'][0].decode('utf-8')
    ad.unbind_s()
    return adname

Mifandray amin'ny latabatra efa noforonina ao anaty angon-drakitra (namorona azy io aho) ary ampidiro daholo izay nianarantsika, izany hoe: ip, mac, username.

def conn_mysql(query,fquery,macaddr,qwery2):
    connect = mysql.connector.connect(host='192.168.0.3', database='voip', user='voip_wr', password='***')
    cursor = connect.cursor()
    cursor.execute(fquery)
    state = cursor.fetchall()
    state = bool(state[0][0])
    if state == True:
        cursor.execute(qwery2)
        connect.commit()
        connect.close()
    else:
        cursor.execute(query)
        connect.commit()
        connect.close()

Afaka mijanona eto isika, satria efa namorona boky adiresy mavitrika, mety hanontany ianao, fa nandeha lavidavitra kokoa aho ary nanampy fitaovana famatsiana mandeha ho azy eto.

Mba hanaovana izany, dia alaina avy amin'ny mpizara tftp efa nomanina mialoha ny fandrindrana môdely iray, izay anaovanay ny fanovana ary tehirizinay ho mac.cfg. Izany hoe, ho an'ny Yealink dia misy karazany roa ny fanamafisana, ny iray manerantany, ary ny faharoa dia mihatra amin'ny finday manokana ary tokony ho endrika mac_phone.cfg

Aorian'ny fanovana rehetra ao amin'ny rakitra ary mamonjy azy amin'ny mpizara tftp, dia manome baiko ny telefaona izahay mba hanome sy hamerina ny fitaovana.

def tftp_file_change(config,place,adname,current_account,current_account_password):

    client = tftpy.TftpClient("192.168.0.3", 69)
    client.download('template.cfg', place)
    fileread = open(place, 'r')
    line = fileread.readlines()
    fileread.close()
    line[5] = (('account.1.label = ').encode('utf-8') + adname.encode('utf-8') + 'n')
    line[2] = (('account.1.auth_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[3] = (('account.1.display_name = ').encode('utf-8') + current_account.encode('utf-8') + 'n')
    line[6] = (('account.1.password = ').encode('utf-8') + current_account_password[0][0] + 'n')
    filewrite = open(place, 'w')
    for i in line:
      filewrite.write(i)
    filewrite.close()
    print place
    print config
    client.upload(config,place)

requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=AutoP')
requests.get('http://admin:admin@'+ipaddr+'/cgi-bin/ConfigManApp.com?key=Reboot')

Aorian'ny famerenan'ny fitaovana dia mahazo ny anarana fenoy eo amin'ny efijery finday + boky adiresy feno feno foana amin'ny endrika angon-drakitra, ary ny sisa tavela dia ny manampy XML sy PHP kely hanehoana ny atiny. Betsaka ny ohatra toy izany, na ny YEALINK aza dia manana azy ireo.

PS: Ho an'ny scalability lehibe kokoa, azonao atao ny mamindra ny toe-javatra lehibe (variables) ao anaty rakitra misaraka.

Source: www.habr.com

Add a comment