标签归档:socket

由request.getRemoteAddr()所想到的ip欺骗

跟一同事讨论,使用request.getRemoteAddr()来作为权限判断的安全程度,于是想知道是否可以通过ip欺骗来绕过。开始的时候先查找在http请求头部会不会出现ip的信息,结果证实是不会出现的。然后又再再看一下request.getRemoteAddr()方法是如何实现的,结果是j2ee只提供了接口,具体实现是由相应的容器来完成的。那我就推断这个ip地址是从ip包的source来的。

那我在传送http请求的时候,是否可以来更新source ip 来完成欺骗呢?如果你不在意对方的响应,是可以这样做的。黑客进行的DoS攻击就是这样来完成的。但我们模拟请求,当然想得到一些数据,但你把source ip给修改了,返回的信息是不会到你这台服务器上的,所以具体实现也是很难的。

那么这样说来这种方法做作权限验证是安全的?也不全对,如果是独立ip地址的服务器,中间不经过任何的反向代理,是安全的。如果你使用了一些框架,又没有反向代理,这种就不太安全了。经过反向代理服务器的时候由于转发时候会把source ip改成代理服务器的ip地址,所以你直接获取request.getRemoteAddr()是不一定能获得客户端的地址,于是代理服务器会在头部加上X-Forward-For的信息,来标识原始服务器的ip信息,框架会先判断是否有X-Forward-For,如果有则以X-Forward-For为准。如果这时你没有使用代理服务器,而框架又做了如此判断,就可以在header中增加X-Forward-For来作ip欺骗,完成从非法到合法的转变

使用php fsockopen 调用 .NET的WebService接口

实现代码如下所示,我们知道了可以使用Telnet模拟http访问,也想试着使用socket来调用webservice接口,原因是默认的php Soap不起作用,可能需要繁琐的配置才能实现。但在使用fsockopen调用的时候也现出了一些问题:

    1. php中,单引号中是没有转义字符的,即\r\n是原始显示的
    2. http头部使用1.1的时候,可能会出现keep-alive模式,这种情况下需要使用Content-Length来判断body的长度,取出数据结束,而不应使用feof
    3. fgets()是一次读取一行;fread()是一次读取一个字符,后面可加数量
$content = '<?xml version="1.0" encoding="utf-8"?>'."\r\n";
$content. = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'."\r\n";
$content. = '  <soap:Body>'."\r\n";
$content. = '    <QueryBalance  xmlns="http://tempuri.org/">'."\r\n";
$content. = '      <userId>sg128</userId>'."\r\n";
$content. = '    </QueryBalance >'."\r\n";
$content. = '  </soap:Body>'."\r\n";
$content. = '</soap:Envelope>'."\r\n";

$fp = fsockopen('example.com', 80);
fwrite($fp, "POST /Service/UserService.asmx HTTP/1.0\r\n");
fwrite($fp, "Host: example.com\r\n");
fwrite($fp, "Content-Type: text/xml; charset=utf-8\r\n");
fwrite($fp, "Content-Length: ".strlen($content)."\r\n");
fwrite($fp, "SOAPAction: \"http://tempuri.org/QueryBalance\"\r\n");
fwrite($fp, "\r\n");

fwrite($fp, $content);

header('Content-type: text/plain');

// $length = 0;
// $line = '';
// while($line !== "\r\n") {
//     $line = fgets($fp);
//     if(substr($line, 0, 15) === 'Content-Length:') {
//         $length = intval(substr($line, 16));
//     }
// }
// echo fread($fp, $length);
while (!feof($fp)) {
    echo fgets($fp);
}
fclose($fp);

由XMLRPC想到的

一直使用Windows Live Writer来写博客,但对于其使用的xmlrpc协议一点都还不知道。本来是想找一个基于xmlrpc协议的软件来Windows Live Writer的功能,因为微软自己产的软件除了Office体验还行以为,其余用户体验基本处于最低端

于是查询相关的软件,但好像不多,也许应该叫没有,但xmlrpc有点意思,不同的语言都有基于其协议的实现,如果自己有时间的话,开发一款自己用起来还算顺手的工具应该不是一件难事,但基于我目前困于温饱问题还没有解决的现状,这个基本也属于自己想象的一款软件吧(其实我自己想象的软件已经很多了,自己动手做的真是少之又少)。由于博客的没落,我也相信这样的软件也不会受到更多人的欢迎,大家使用一下Windows的产品就可以了。

接着又看到了jsonrpc的信息,他们都属于SOAP的一部分,而SOAP的实现方式是http请求与响应,只不过中间传递的数据根据协议的不同而不同罢了。于是我又在问自己,http请求究竟是怎样实现的?其数据组织格式是什么?我们怎么通过更低一级的socket编程来模拟http请求?于是查找了相关信息,大概了解了socket怎么样组织请求,怎么样来伪装自己,比起语言本身封装的http请求,这些内容让我更进一步了解了http协议的原理

普通form和文件form有什么不同?其组织形式是怎样的?普通的from可以以文本的形式获取到,而文件form则是以流(java)来读入的,根据php经验,http头和内容的区分只是根据两个“\r\n”来完成的。http协议可以设定文件的读取起始位置,这样可以来做断点续传

socket是基于tcp协议的,所以比http更低一层,其实现https的方式是使用SSL进行加密。客户端实现实时通信是通过相互监听来实现的,即,一款软件会在你的机器打开一个tcp端口来监听服务器的回应。但这种情况在NAT下面会遇到问题,因为NAT服务器不允许主动访问内网机器,只能被动的方法。这其实就把双方监听的优势给磨灭了;但好在客户端的软件也是我们写的,这样我们就可以主动发起请求,穿透NAT;

NanoHTTPD.java

在使用jquery.validationEngine的时候,看到其github上有相关java测试的代码,包括了一个NanoHTTPD.java来模拟http响应,虽然里面的原来还不是太清楚,但无疑,如果弄明白他可以让我们更进一步了解http和socket程序的关系,能够看清http的原理

github地址:https://github.com/posabsolute/jQuery-Validation-Engine

(待续)