4

我想在受强制门户保护的 wifi 网络上连接一个基于 ESP8266 的传感器(我没有其他选择,我不能要求减损)。我有一个登录名/密码来连接。

在一台基本的计算机上,当我连接到网络并发出 Internet 请求时(例如,我在 google 上搜索“bl”),我得到一个这样的页面:https://url:1003/fgtauth?12291a0aff04200a

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <style type="text/css">
    ...
    </style>
    <body>
<div class="oc">
  <div class="ic">
    <form action="/" method="post">
      <input type="hidden" name="4Tredir" value= "https://www.google.com/search?q=test&ie=utf-8&oe=utf-8">
      <input type="hidden" name="magic" value="12291a0aff04200a">
      <input type="hidden" name="answer" value="0">
      <h1 class="logo">
        GENERAL CONDITIONS
      </h1>
      <p>
      I.    OBJET <br /> <br />
      Some blabla..
      </p>
      <h2>
        Do you agree to the above terms?
      </h2>
      <div class="fec">
        <input type="submit" value= "Yes, I agree" onclick="sb('1')">
        <input type="submit" value= "No, I decline" onclick="sb('0')">
      </div>
    </form>
   </div>
   </div>
   <script>
     function sb(val) {
       document.forms[0].answer.value = val;
       document.forms[0].submit();
      }
    </script>
  </body>
</html>

所以,我们在这个页面中看到我们得到了一个“神奇的值”,它实际上是会话的一个 id。当我点击同意按钮时,我得到这个页面https://url:1003/

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <style type="text/css">
    ...
    </style>

    <title>
      Firewall Authentication
    </title>
  </head>
  <body>
    <div class="oc">
      <div class="ic">
        <form action="/" method="post">
        <input type="hidden" name="4Tredir" value= "https://www.google.com/search?q=bl&ie=utf-8&oe=utf-8">
        <input type="hidden" name="magic" value="122713150676bec1">
        <h1 class="logo">
          Authentication Required
        </h1>
      <h2>
        Please enter your username and password to continue.
      </h2>
        <div class="fer">
          <label for="ft_un">
            Username:
          </label>
            <input name="username" id="ft_un" style="width:245px">
            <br>
          </div>
          <div class="fer">
            <label for="ft_pd">
              Password:
            </label>
            <input name="password" id="ft_pd" type="password" style="width:245px">
          </div>
          <div class="fer">
            <input type="submit" value= "Continue">
          </div>
        </form>
      </div>
    </div>
  </body>
</html>

在这里,我填写用户名和密码,它会将它们发送到返回空白页面的服务器,并返回 OK。

所以,我想从 ESP8266 做这一步。我分两步看到:

  • 请求页面
  • 得到结果并存储魔法
  • 伪造“同意”请求页面
  • 伪造一个“user/id/magic”请求页面

ESP8266 请求页面的示例可以在这里找到: https ://github.com/iobridge/ThingSpeak-Arduino-Examples/blob/master/Ethernet/Arduino_to_ThingSpeak.ino 我们在这里看到,我们可以发送 POST 请求:

client.print("POST /update HTTP/1.1\n");

这里有一个解析页面的好例子:http: //blog.nyl.io/esp8266-led-arduino/

所以,我可能会这样做并发布答案,但首先我需要一些关于如何创建上述“假”请求的线索。

有任何想法吗 ?

4

1 回答 1

7

ESP8266 不仅能够使用 HTTPS,事实上最新的 ESP8226 Arduino 代码库包括一个 WiFiClientSecure 类,用于连接到 HTTPS 服务器。

假设这个页面永远不会改变,并且您使用的是 Arduino 环境,您需要编写一些基本函数。其中之一将是GET您已经链接的初始功能,并检查您是否收到了所需的页面,或者您是否被定向到门户。如果您被定向到门户,则需要编写一个等效POST函数来发送“我同意”响应。

现在,此POST功能将要求您将 HTTP 表单编码的有效负载发送到包含“Answer”值的服务器 - 您可以在此处阅读http://www.w3.org/TR/html401/interact/forms.html #h-17.13。由于您(可能)不希望页面发生更改,因此您可以将其硬编码为如下所示:

client.println("POST / HTTP/1.1");
// $PORTAL_HOST should be the host of the captive portal, e.g. 10.1.1.1
client.println("Host: $PORTAL_HOST");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: 8");
client.print("\n");
client.print("Answer=1");

发送该有效负载后,您应该会收到您的辅助用户/密码页面。从那里通过indexOf/substring或类似的东西提取魔术/会话是一件简单的事情,然后用您现在提取的数据(如果需要)重复上述代码。

如果您需要更好地了解您将发送的具体内容,我建议您打开浏览器上的调试/网络选项卡,并查看浏览器在定向到此门户页面时发送的确切数据。您将希望尽可能地模拟这一点。

于 2015-11-19T23:12:56.163 回答