几乎OCR即可获得VPNBook密码。 PHP + Mikrotik

最近,VPNBook开始发布密码而不是纯文本作为图像。 我想:“好吧,怎么办。”并开始寻找解决这个问题的方法。 我们可以识别PHP中的“图片”密码VPNBook。 当然,还有Mikrotik的脚本。

长期以来,我在路由器(Mikrotik)上从VPNBook.com设置了自动的免费PPTP VPN隧道,并成功使用了直到最近。 我不会详细介绍,它们在“ 在Mikrotik上为VPN配置自动接收密码 ”一文中进行了介绍。 在出现问题之前,可以简单地从html页中提取VPNBook的密码,例如:

preg_match('/Password: <strong>([^<]+)/', $homepage, $matches); print($matches[1]) 

最近,密码已成为“图片”。 首先想到的是使用光学文本识别。 我开始尝试可以识别密码的在线和离线OCR服务。 我向Winand致以问候,在这个问题上我们与他通讯。 通常,我遇到的最后一个OCR是Tesseract,它开箱即可确定密码,但有错误。 但是可以教他新的字体,这是我要做的。 当我选择一种看起来像“图片字体”的字体时,想到的是它很简单,尽管它看起来像Windows的终端字体或Linux的终端字体。 瞧-原来它只是一个内置的PHP字体,带有数字(大小)5。接下来,我放弃了OCR,编写了一个PHP脚本,该脚本在生成的字典中查找“图片”密码的字符。 词典是一组可能的颜色和大小相同的密码字符的图像。 搜索通过匹配图像完成。 这是一个简单的逆向工程。 考虑到原始性,我认为VPNBook上图像的当前版本不会持续很长时间。

Vpnbook.php脚本


Sprite返回一个密码字符串。

 <?php //   $wchar = 9; $hchar = 13; $strDict = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 '; $imgDict = imagecreatetruecolor(2 + strlen($strDict)* $wchar, $hchar); $bg = imagecolorallocate($imgDict, 0xF6, 0xF6, 0xF6); $textcolor = imagecolorallocate($imgDict, 0x4C, 0x4C, 0x4C); imagefill($imgDict, 0, 0, $bg); imagestring($imgDict, 5, 2, 0, $strDict, $textcolor); //  cURL $ch = curl_init(); //  url,      curl_setopt($ch, CURLOPT_URL, 'https://www.vpnbook.com/password.php'); //  ,      string curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); // also, this seems wise considering output is image. //   $output = curl_exec($ch); //  cURL curl_close($ch); $imgOCR = imagecreatefromstring($output); // $imgOCR = imageCreateFromPng('password.png'); //      10  . 2 + 10*9 = 92 < 100 $maxchar = floor((imagesx($imgOCR) - 2) / 9); $imgBox = imagecreatetruecolor($wchar, $hchar); $hashDict = Array(); //   for ($k = 0; $k < strlen($strDict) ; $k++) { imagecopy($imgBox, $imgDict, 0, 0, 2 + $k * $wchar, 0, $wchar, $hchar); $hashStr = ""; for($y = 0; $y < $hchar ; $y++) for($x = 0; $x < $wchar; $x++) $hashStr .= (imagecolorat($imgBox, $x, $y) != 0xF6F6F6)? '1': '0'; $hashDict[$hashStr] = $strDict[$k]; } //     for ($k = 0; $k < $maxchar ; $k++) { imagecopy($imgBox, $imgOCR, 0, 0, 2 + $k * $wchar, 0, $wchar, $hchar); $hashStr = ""; for($y = 0; $y < $hchar ; $y++) for($x = 0; $x < $wchar; $x++) $hashStr .= (imagecolorat($imgBox, $x, $y) != 0xF6F6F6)? '1': '0'; $tempchar = $hashDict[$hashStr]; if ($tempchar==' ') break; print($tempchar); } /*header('Content-type: image/png'); imagepng($imgOCR); */ //var_dump($hashDict); imagedestroy($imgDict); imagedestroy($imgOCR); imagedestroy($imgBox); ?> 


计划B.来自Twitter的密码


借助vvsvic提示符,我提供了一个替代脚本简单实现,可从VPNBook Twitter(https://twitter.com/vpnbook/)检索密码
 <?php function url_get_html($url) { //  cURL $ch = curl_init(); //  url      curl_setopt($ch, CURLOPT_URL, $url); //        string curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //   $output = curl_exec($ch); //  cURL curl_close($ch); //   return $output; } $homepage = url_get_html('https://twitter.com/vpnbook'); preg_match('/Password: ([^<]+)/', $homepage, $matches); // Print the entire match result // var_dump($matches); print($matches[1]) // print_r($matches); ?> 


Mikrotik VPNBook脚本


必须每分钟从sheduler调用该脚本。 该脚本监视PPTP连接的状态,并在断开连接时调用整个过程以请求新密码,因此Mikrotik不会“使用错误的密码多次尝试打开连接,而是在1分钟内完成重新连接。” 它还监视错误时的错误以获取和文件获取,以更准确地确定已接收到密码。

 # VPNBookScript v2 :global VPNBookpIfName "pptp-out1" :global VPNBookServerAddresses {"euro217.vpnbook.com";"euro214.vpnbook.com";"us1.vpnbook.com";"us2.vpnbook.com";"ca1.vpnbook.com";"de233.vpnbook.com";"fr1.vpnbook.com"} #:if ([:typeof $VPNBookServerAddresses] != "array") do={ # :set VPNBookServerAddresses {"euro217.vpnbook.com";"euro214.vpnbook.com";"us1.vpnbook.com";"us2.vpnbook.com";"ca1.vpnbook.com";"de233.vpnbook.com"} #} :global VPNBookErr false :global VPNBookPassFile "VPNBookPass.txt" :global VPNBookPass :global VPNBookRun #:global TToken "4.....................2" #:global TChatId "2342432...9" :global VPNBookServerIndex :if ([:typeof $VPNBookServerIndex] != "num") do={:set VPNBookServerIndex 0} :if ([/interface pptp-client get $VPNBookpIfName running]) do={ :set VPNBookRun true } else { :if (!$VPNBookRun) do={ :set VPNBookServerIndex ($VPNBookServerIndex + 1) :if ($VPNBookServerIndex>=[:len $VPNBookServerAddresses]) do={:set VPNBookServerIndex 0} } else { :set VPNBookRun false } :if (![/interface pptp-client get $VPNBookpIfName disabled]) do={/interface pptp-client set $VPNBookpIfName disabled=yes} :do {/tool fetch url="http://server/vpnbookpass.php" dst-path=$VPNBookPassFile} on-error={:set VPNBookErr true} :delay 2 :do {:set VPNBookPass [/file get $VPNBookPassFile contents]} on-error={:set VPNBookErr true} :if (!$VPNBookErr) do={ :if ([/interface pptp-client get $VPNBookpIfName password] != $VPNBookPass) do={/interface pptp-client set $VPNBookpIfName password=$VPNBookPass} :if ([/interface pptp-client get $VPNBookpIfName connect-to] != $VPNBookServerAddresses->$VPNBookServerIndex) do={/interface pptp-client set $VPNBookpIfName connect-to=($VPNBookServerAddresses->$VPNBookServerIndex)} :log info ("VPNBook: Attempt to connect to: ".($VPNBookServerAddresses->$VPNBookServerIndex).". Password: $VPNBookPass") # /tool fetch url=("https://api.telegram.org/bot$TToken/sendmessage\?chat_id=$TChatId&text=VPNBook: Attempt to connect to: ".($VPNBookServerAddresses->$VPNBookServerIndex).". Password: $VPNBookPass") keep-result=no /interface pptp-client set $VPNBookpIfName disabled=no } } 

我还建议在PPP配置文件中添加用于断开连接(断开事件)的PPTP接口的断开连接,以便重新连接甚至在1分钟之内也不会泛洪。

因此,如果成功接收到新密码,则1分钟内的主脚本将建立pptp-out1连接。

 add change-tcp-mss=yes name=VPNBook on-down=\ ":if (![/interface pptp-client get pptp-out1 disabled]) do={\r\ \n /interface pptp-client set pptp-out1 disabled=yes\r\ \n}" only-one=yes use-compression=yes use-encryption=required use-ipv6=no use-mpls=no use-upnp=no 

Source: https://habr.com/ru/post/zh-CN420373/


All Articles