Ticket #2797: enumlookup.agi.patch

File enumlookup.agi.patch, 7.4 kB (added by evilbunny, 4 years ago)

Removed initial compression line as it was pointless and made decompression optional, added @ to prevent gzinflate from echo'ing error messages if the string isn't encrypted

  • enumlookup.agi

    old new  
    77// Originally written for use with FreePBX. 
    88 
    99// Based on e164.org's enum.php script, available on http://www.e164.org/enum.phps 
     10// Extended version based on http://www.e164.org/enum2.phps 
    1011 
    1112/* --------WARNING--------- 
    1213 *  
     
    2526// Go through the ENUM providers and look for the number. 
    2627 
    2728$dialstr = ""; 
     29// Set $allow_plain_text to false to disable unencrypted DNS ENUM lookups. 
     30$allow_plain_text = true; 
    2831 
    2932foreach ($enums as $enum) { 
    3033  // Are we using php5 and can use get_dns_record? 
    31     if (function_exists("dns_get_record")) { 
     34  if (function_exists("dns_get_record")) { 
     35    if ($enum == 'e164.org' && function_exists("socket_create") && 
     36      function_exists("mcrypt_module_open") && 
     37      function_exists("openssl_public_encrypt")) { 
     38      $arr = get_encrypted($lookup, $enum); 
     39    } 
     40 
     41    if ((!isset($arr) || $arr === false) && $allow_plain_text != false) { 
    3242      $arr = get_php5($lookup, $enum); 
     43    } 
    3344  // else, do we have Pear Net DNS? 
    3445  // Disabled, as I couldn't easily get it working on my machine 
    3546  //} elseif ((@include 'Net/DNS.php') =='OK') { 
    3647  //  $arr = get_pear($arpa); 
    37   } else
     48  } elseif($allow_plain_text != false)
    3849    @exec('dig -h > /dev/null 2>&1 ', $res, $var); 
    3950    if ($var != 127) {  
    4051      $arr = get_dig($lookup, $enum); 
     
    120131  } 
    121132} 
    122133 
     134function byte_values($value, $start = false, $num = false) { 
     135  $stop = strlen($value); 
     136  if($num === false) 
     137    $num = $stop - $start; 
     138 
     139  $ret = 0; 
     140  for($x = $start; $num > ($x - $start); $x++) 
     141    $result |= (ord($value{$x}) << 8 * (($num - ($x - $start))-1)); 
     142 
     143  return $result; 
     144} 
     145 
     146function get_encrypted($lookup, $enum) { 
     147  global $AGI; 
     148 
     149  $nl = "\n"; 
     150  $pubkey = '-----BEGIN PUBLIC KEY-----'.$nl. 
     151    'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwfwG13TTC4TBlKvz8CUKW'.$nl. 
     152    's01QOWhGXklhPlanI8yzcuv9I97CwH38RjsyrTl2rOrfW6jKPZv3yDzqBYvapDwAe'.$nl. 
     153    'ZsosjUQu3kulUn6oWH5hn70OtJ4lLTBIl077sSoZp8LsTyP2rQzdQ1YT4hO+Yd+4Z'.$nl. 
     154    't9KHkd4o8FxHbeYoexa2A/wTlKBXLCLDGqrR8Uzvipm4wiFvA2UCIw/id30DXzLfh'.$nl. 
     155    '1CvOhkLOOZ9YhaxSglD0TiGlWiztHEti0Fyxepf58cYthQxZpku7plqx4jUg521dT'.$nl. 
     156    'e58KPwYA8lUUrNeZUofBFlAyYTMWetZL/L/WQ4cebFRghPBXRrWuXhbOqx8MxuVuV'.$nl. 
     157    'lpEhjQqFXZp8PqgSne6avkzspBxARmU3f2XkfuZo4vrliRhm/9+P8eVxK3bYB8V+d'.$nl. 
     158    'c2wtVGTAIG6BFj1Cq/0uQNugPC0AZ62e6+6Dlz7XcBwAU6RsqlgkWA3Rg+kJYWnGd'.$nl. 
     159    'W16JnrAKAJxTnVdE5MoV7mGubypuy8whIj3JAgMBAAE='.$nl. 
     160    '-----END PUBLIC KEY-----'.$nl; 
     161 
     162  $AGI->verbose("Encrypted DNS look up $lookup on $enum",3); 
     163  $arpa = $enum; 
     164  for ($i = 0; $i < strlen($lookup); $i++) 
     165    $arpa = $lookup[$i].".".$arpa; 
     166 
     167  dns_get_record('e164.org', DNS_NS, $NS, $additonal); 
     168  foreach($NS as $key => $host) 
     169    $servers[] = $host['target']; 
     170 
     171  if(($socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) === false || 
     172    socket_bind($socket, '0.0.0.0', 0) == false) 
     173    return false; 
     174 
     175  $rnd = fopen('/dev/urandom', 'r'); 
     176  $urnd = fgets($rnd, 16); 
     177  fclose($rnd); 
     178  $key = substr(hash('sha1', $urnd, 1), 0, 16); 
     179  $td = mcrypt_module_open('rijndael-128', '', 'cbc', ''); 
     180  $key = substr($key, 0, mcrypt_enc_get_key_size($td)); 
     181 
     182  $bits = explode('.', $arpa); 
     183  $tmp = ''; 
     184  foreach($bits as $bit) 
     185    $tmp .= chr(strlen($bit)).$bit; 
     186  $hostname = $tmp; 
     187 
     188  foreach($servers as $server) 
     189  { 
     190    $IPs = dns_get_record($server, DNS_A, $NS2, $add2); 
     191    foreach($IPs as $IP) 
     192    { 
     193      $server_address = $IP['ip']; 
     194      $qryID = rand(0,65535); 
     195      $qry = chr($qryID >> 8).chr($qryID % 256).chr(1).chr(0).chr(0). 
     196        chr(1).chr(0).chr(0).chr(0).chr(0).chr(0).chr(1).$hostname. 
     197        chr(0).chr(0).chr(35).chr(0).chr(1).chr(0).chr(0).chr(41). 
     198        chr(16).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0).chr(0); 
     199 
     200      openssl_public_encrypt($key.$qry, $encrypted, $pubkey); 
     201      $strlen = strlen($encrypted) + 3; 
     202      $encrypted = chr($strlen >> 8).chr($strlen % 256).chr(255).$encrypted; 
     203 
     204      $len = socket_sendto($socket, $encrypted, strlen($encrypted), 0, $server_address, 53); 
     205 
     206      $dnsreply = $read = ''; 
     207      $strlen = 0; 
     208      do 
     209      { 
     210        $streams = array($socket); 
     211        if(@socket_select($streams, $write = NULL, $except = NULL, 2) <= 0) 
     212          break; 
     213 
     214        socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 0, 'usec' => 1)); 
     215        while(($flag = @socket_recv($socket, $buf, 4096, 0)) > 0) 
     216        { 
     217          $read .= $buf; 
     218          if($strlen == 0) 
     219            $strlen = (ord($buf{0}) << 8) + ord($buf{1}); 
     220 
     221          if($strlen > 0 && strlen($read) >= $strlen) 
     222          { 
     223            $cipher_text = substr($read, 3); 
     224            $iv_size = mcrypt_enc_get_iv_size($td); 
     225            $iv = substr($cipher_text, 0, $iv_size); 
     226            $cipher_text = substr($cipher_text, $iv_size); 
     227 
     228            $plain = false; 
     229            if(mcrypt_generic_init($td, $key, $iv) != -1) 
     230              $plain = mdecrypt_generic($td, $cipher_text); 
     231 
     232            mcrypt_generic_deinit($td); 
     233            mcrypt_module_close($td); 
     234 
     235            if(($dnsreply = @gzinflate($plain)) == false) 
     236              $dnsreply = $plain; 
     237            $replyID = byte_values($dnsreply, 0, 2); 
     238 
     239            if($replyID == $qryID) 
     240              break(4); 
     241            unset($dnsreply); 
     242          } 
     243        } 
     244      } while(1); 
     245    } 
     246  } 
     247 
     248  if(!isset($dnsreply{0})) 
     249    return false; 
     250 
     251  $querys = byte_values($dnsreply, 4, 2); 
     252  $ans = byte_values($dnsreply, 6, 2); 
     253 
     254  $queries = $answers = array(); 
     255  $offset = 12; 
     256  for($i = 0; $i < $querys; $i++) 
     257  { 
     258    while(($nextlen = byte_values($dnsreply, $offset++, 1)) > 0) 
     259    { 
     260      if(isset($queries[$i]['hostname'])) 
     261        $queries[$i]['hostname'] .= '.'; 
     262      $queries[$i]['hostname'] .= substr($dnsreply, $offset, $nextlen); 
     263      $offset += $nextlen; 
     264    } 
     265 
     266    $queries[$i]['type'] = byte_values($dnsreply, $offset, 2); 
     267    $offset += 2; 
     268    $queries[$i]['class'] = byte_values($dnsreply, $offset, 2); 
     269    $offset += 2; 
     270  } 
     271 
     272  for($i = 0; $i < $ans; $i++) 
     273  { 
     274    if(byte_values($dnsreply, $offset, 2) == 49164) 
     275    { 
     276      $answers[$i]['hostname'] = $queries[0]['hostname']; 
     277      $offset += 2; 
     278    } else { 
     279      while(($nextlen = byte_values($dnsreply, $offset++, 1)) > 0) 
     280      { 
     281        if(isset($answers[$i]['hostname'])) 
     282          $answers[$i]['hostname'] .= '.'; 
     283        $answers[$i]['hostname'] .= substr($dnsreply, $offset, $nextlen); 
     284        $offset += $nextlen; 
     285      } 
     286    } 
     287 
     288    $answers[$i]['type'] = byte_values($dnsreply, $offset, 2); 
     289    $offset += 2; 
     290    $answers[$i]['class'] = byte_values($dnsreply, $offset, 2); 
     291    $offset += 2; 
     292    $answers[$i]['ttl'] = byte_values($dnsreply, $offset, 4); 
     293    $offset += 4; 
     294    $datalength = byte_values($dnsreply, $offset, 2); 
     295    $offset += 2; 
     296    $off2 = 0; 
     297    $record = substr($dnsreply, $offset, $datalength); 
     298    $offset += $datalength; 
     299    $answers[$i]['prio']  = byte_values($record, $off2, 2); 
     300    $off2 += 2; 
     301    $answers[$i]['order'] = byte_values($record, $off2, 2); 
     302    $off2 += 2; 
     303    $flagslength = byte_values($record, $off2++, 1); 
     304    $answers[$i]['flag'] = substr($record, $off2, $flagslength); 
     305    $off2 += $flagslength; 
     306    $srvlength = byte_values($record, $off2++, 1); 
     307    $tech = $answers[$i]['tech'] = substr($record, $off2, $srvlength); 
     308    $off2 += $srvlength; 
     309    $regexlen = byte_values($record, $off2++, 1); 
     310    $bit = explode('!', substr($record, $off2, $regexlen)); 
     311    $URI = ereg_replace($bit[1], $bit[2], '+'.$lookup); 
     312    if($URI[3] == ':') 
     313      $URI[3] = '/'; 
     314    if($URI[4] == ':') 
     315      $URI[4] = '/'; 
     316    $answers[$i]['URI'] = $URI; 
     317  } 
     318 
     319  if (count($answers) > 0) { 
     320    return $answers; 
     321  } else { 
     322    return null; 
     323  } 
     324} 
     325 
    123326 
    124327// helper functions 
    125328function get_var( $agi, $value) 
     
    133336  } 
    134337  else return ''; 
    135338} 
    136  
    137 ?>