apache 发出不带正斜杠的HTTP请求

33qvvth1  于 2023-10-23  发布在  Apache
关注(0)|答案(3)|浏览(134)

我在Apache访问日志中遇到了一个奇怪的HTTP请求:
“GET www.example.com HTTP/1.0”
使用浏览器(Waterfox、Firefox或Chrome(按此顺序))或PuTTY/cURL|终端如何重现此HTTP请求?最好是localhost,因为我可以实时查看日志。
我做了一些阅读和 * 显然 * cURL只能使绝对的URL请求。我也没有能够复制这与编辑和重新发送在网络面板的水狐。这个请求触发了一些我希望在我的系统中修复的小错误。

polkgigr

polkgigr1#

在终端中,执行任何请求都非常容易。
你可以

  • 在端口80 telnet 127.0.0.1 80上使用telnet。然后你必须写请求(你可能需要快速输入,服务器可能会拒绝你的坏结束行\n而不是\r\n)
  • 要绕过telnet限制,您可以首先使用简单的printf编写请求:
  1. # regular HTTP query
  2. printf 'GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n'
  3. # or the 'absolute url' mode
  4. printf 'GET www.example.com HTTP/1.0\r\n\r\n'
  5. # or even the official absolute uri mode, I think that's the correct one
  6. printf 'GET http://www.example.com/ HTTP/1.0\r\n\r\n'

但是printfecho是一样的,有特殊的字符处理(比如\r\n)。因此,您必须复制结果并将其粘贴到telnet。
我更喜欢使用netcat(有时也叫nc)来管理tcp/ip套接字连接,而不是telnet,并通过管道直接将printf结果放入tcp/ip套接字(如果你需要https,你必须使用openssl_client而不是netcat)。那就是:

  1. printf 'GET www.example.com HTTP/1.0\r\n\r\n' | nc -q 3 127.0.0.1 80
  2. # or
  3. printf 'GET http://www.example.com/ HTTP/1.0\r\n\r\n' | nc -q 3 127.0.0.1 80

这就是你有你的低技术浏览器。它的优点是能够编写任何类型的错误查询。在第一个头中使用的位置的aboslute url是RFC中存在的东西,以处理与非常旧的HTTP 0.9的兼容性:

  1. # HTTP 0.9
  2. printf 'GET www.example.com/foo/bar \r\n' | nc -q 3 127.0.0.1 80

在此请求中,要使用的正确VirtualHost是来自位置的VirtualHost,而不是来自Host头的VirtualHost:

  1. # regular HTTP query
  2. printf 'GET http://www.vhost2.com/foo HTTP/1.0\r\nHost: www.vhost1.com\r\n\r\n' |\
  3. nc -q 3 127.0.0.1 80

这是James Kettle's Host header attacks back in 2013的基础。因此,我建议您有效地跟踪 * 次要事件 * 并修复它们。学习如何在服务器中注入任何特殊的URL总是很好的。
您也可以使用curl发送精心编制的请求,但根据定义,真实的浏览器和命令行浏览器倾向于避免发送精心编制的请求。
当您处理一个大型服务链时,跟踪HTTP服务器的真实的响应也非常有效。学习如何在tcp套接字中使用HTTP,而不使用curl,这很有用。

展开查看全部
htrmnn0y

htrmnn0y2#

首先安装安装。
然后将以下内容复制并粘贴到终端窗口中:

  1. telnet localhost 80
  2. GET www.example.com HTTP/1.0

按Enter键两次。
这是我的访问日志中的样子:

  1. ::1 - - [30/Oct/2020:23:37:28 -0700] "GET www.example.com HTTP/1.0" 400 310

你也可以用PHP来实现。下面是我创建的一个名为test.php的文件:

  1. <?php
  2. $fp = stream_socket_client("tcp://localhost:80", $errno, $errstr, 30) or die("$errstr ($errno)");
  3. $request = "GET www.example.com HTTP/1.0\r\n\r\n";
  4. $written = 0;
  5. do {
  6. $bytes = fwrite($fp, substr($request, $written)) or die('fwrite error');
  7. $written+= $bytes;
  8. }
  9. while ($written!==strlen($request));
  10. fclose($fp) or die('fclose error');
  11. echo 'Request sent successfully';
  12. exit;

上面的代码做了同样的事情,它只是使用PHP来做。用上面的文字创建一个PHP文件,把你的浏览器指向它,它应该说“请求发送成功”,然后检查你的访问日志。
编辑:
如果您需要使用TLS,请尝试以下操作。再次保存为test.php并将浏览器指向此文件:

  1. $fp = fsockopen("tls://localhost", 443, $errno, $errstr, 30) or die("$errstr ($errno)");
  2. $request = "GET www.example.com HTTP/1.0\r\n\r\n";
  3. $written = 0;
  4. do {
  5. $bytes = fwrite($fp, substr($request, $written)) or die('fwrite error');
  6. $written+= $bytes;
  7. }
  8. while ($written!==strlen($request));
  9. while (!feof($fp)) {
  10. echo fgets($fp, 128);
  11. }
  12. fclose($fp) or die('fclose error');
  13. echo 'Request sent successfully';
  14. exit;
展开查看全部
vvppvyoh

vvppvyoh3#

您可以使用curl发布精心制作的请求(在某种程度上)。Curl不验证方法(-X、--request或CURLOPT_CUSTOMREQUEST)。因此,您可以使用“newline-injection”。
下面是一个例子,我通过HTTP发送代理请求,我指示Apache作为反向代理,为我启动TLS(当我需要一些古老的服务器上的软件能够与只接受最新版本的TLS的服务器通信时,我使用这种技术)。
请注意,示例使用echo的bash变体,以正确插入CRLF字符。

  1. $ curl -v -X "$(echo -en 'GET https://target.domain/actual/path HTTP/1.1\r\nX-Ignore-Injection:' )" my.apache.proxy.example:8080/ignored/path
  2. * Trying 1.2.3.4:8080...
  3. * Connected to my.apache.proxy.example (1.2.3.4) port 8080 (#0)
  4. > GET https://target.domain/actual/path HTTP/1.1
  5. > X-Ignore-Injection: /ignored/path HTTP/1.1
  6. > Host: my.apache.proxy.example:8080
  7. > User-Agent: curl/7.83.0
  8. > Accept: */*
  9. ...

相关问题