111,120
社区成员
发帖
与我相关
我的任务
分享
64的IP 是我的一台vps 开放10086端口
218的IP是我 连接到vps上面的IP得到的IP 24295 是端口号码
vps上面那个 Form1 的代码大概如下:
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(new IPEndPoint(IPAddress.Any, 10086));//监听vps 10086端口
sock.Listen(5);
while (true) {
try {
Socket sock_client = sock.Accept();
textBox1.BeginInvoke(new MethodInvoker(() => {
textBox1.Text += sock_client.RemoteEndPoint.ToString() + " -> in\r\n";
}));
sock_client.Send(Encoding.UTF8.GetBytes("welcome"));//回应连接好了
}
然后 上图黑框我是 telnet到 vps 的 10086 端口的 可以看到上面有 welcome字样 说明我连接过去了
然后下面是我用原始套接字发送的数据包
Socket sock_raw = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
sock_raw.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
//TcpDefine 自己定义的一个类
//获取IP报文数据包 64 那个ip 差不多就是(服务器上 sock.RemoteEndPoint.IP的值)这里可乱填 因为不需要服务器来回应我
TcpDefine.IP_HEADER ipHeader = TcpDefine.GetIPHeader("64.xxx.xxx.xxx", "218.xxx.xxx.xxx");
//获取tcp报文数据包
TcpDefine.TCP_HEADER tcpHeader = TcpDefine.GetTcpHeader(
10086, //对方能获取到的远程主机的端口 差不多就是(服务器上 sock.RemoteEndPoint.Port的值) 这里可乱填不需要回应
24295, //到达端口
BitConverter.ToInt32(new byte[] { 0xc6, 0x2a, 0x35, 0x73 }, 0), //seq验证序列号 抓包抓出来的 这个不能错
BitConverter.ToInt32(new byte[] { 0x4e, 0x78, 0x28, 0x7a }, 0), //ack回应序列号(服务器回应时候 seq = ack + 1)
TcpDefine.Flag.ACK | TcpDefine.Flag.PSH //标志
);
//构造数据包
byte[] bySend = TcpDefine.GetPacketHeader(ipHeader, tcpHeader, Encoding.UTF8.GetBytes("this is a test hahaha "));
sock_raw.SendTo(bySend, new IPEndPoint(IPAddress.Parse("218.xxx.xxx.xxx"), 24295));//发送数据包
可见我执行这个程序后 在我上面 telnet 的框中出现了 test 字样 说明我的数据包正确的被接收了
下面是抓包数据
172.16.8.152那个是我win7所在的局域网IP 前三个数据包 是 三步握手 数据包
接下 psh,ack 那个是服务器回应的 welcome
然后再下去那个ack是我 win7 telnet 收到welcome消息的确认回应
最后一个数据包 就是我上面的那段代码发送出来的 运行上面的代码后 telnet窗口出现了我的 test 的那条消息 不过不知道怎么回事 被welcome挡住了
实践说明 我的YY不是不可能
[/quote]
我在三台电脑上完成了数据的对接
vps上放在一个服务程序 用于接收客户端连接的
win7上是telnet 连接过去 服务端上 打印出对应的IP和端口
然后我在虚拟机2003里面 直接发送TCP IP 数据包 由于TCP和IP的包头都是我自己构造的数据包 所以我想要让这个数据到里就到哪里 我Telnet到vps得到的端口好和IP是 自动做了映射的 所以我可以直接利用这个IP和端口号直接发送数据包 而不用去建立连接 因为 连接本来就是建立好了的 所以我虚拟机里面的 程序直接用我win7连接到vps上的端口和ip 构造数据包直接发送出去 而消息也确实被发送到了我win7的电脑上
还有我之所以在虚拟的2003上面 发送数据包 是因为。。。。。貌似从xp开始 就限制了 原始套接字的使用 而2003可以使用。。要在win7发原始套接字是发送不了的 没研究过 winpcap 估计他可以。。
好了 我装逼完了。。
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(new IPEndPoint(IPAddress.Any, 10086));//监听vps 10086端口
sock.Listen(5);
while (true) {
try {
Socket sock_client = sock.Accept();
textBox1.BeginInvoke(new MethodInvoker(() => {
textBox1.Text += sock_client.RemoteEndPoint.ToString() + " -> in\r\n";
}));
sock_client.Send(Encoding.UTF8.GetBytes("welcome"));//回应连接好了
}
Socket sock_raw = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
sock_raw.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
//TcpDefine 自己定义的一个类
//获取IP报文数据包 64 那个ip 差不多就是(服务器上 sock.RemoteEndPoint.IP的值)这里可乱填 因为不需要服务器来回应我
TcpDefine.IP_HEADER ipHeader = TcpDefine.GetIPHeader("64.xxx.xxx.xxx", "218.xxx.xxx.xxx");
//获取tcp报文数据包
TcpDefine.TCP_HEADER tcpHeader = TcpDefine.GetTcpHeader(
10086, //对方能获取到的远程主机的端口 差不多就是(服务器上 sock.RemoteEndPoint.Port的值) 这里可乱填不需要回应
24295, //到达端口
BitConverter.ToInt32(new byte[] { 0xc6, 0x2a, 0x35, 0x73 }, 0), //seq验证序列号 抓包抓出来的 这个不能错
BitConverter.ToInt32(new byte[] { 0x4e, 0x78, 0x28, 0x7a }, 0), //ack回应序列号(服务器回应时候 seq = ack + 1)
TcpDefine.Flag.ACK | TcpDefine.Flag.PSH //标志
);
//构造数据包
byte[] bySend = TcpDefine.GetPacketHeader(ipHeader, tcpHeader, Encoding.UTF8.GetBytes("this is a test hahaha "));
sock_raw.SendTo(bySend, new IPEndPoint(IPAddress.Parse("218.xxx.xxx.xxx"), 24295));//发送数据包


我可以YY一下么
一台服务器S
两台客户端C1,C2
若要C1 -> C2
两个C分别连接到S
S必然会得到一个C2的 临时通讯接口 IP:PORT 而这个个 ip和端口 已经被映射了 可以通过这个ip和端口 直接访问到C2
下面就是见证奇迹的时刻了
C1直接发送TCPIP数据包
将IP包头改为C1的ip 回应IP改为连接到S的自己的外网ip
将TCP包头中目标端口改为C2端口 回应端口改为自己连接到S的自己的端口 然后发送数据包出去 欺骗C2客户端 让他以为是在和S通讯
然后你要做的 就是自己模拟tcp通信发送原始数据包。。
YY完毕。。。
的确不是一个复杂问题。