Thursday, March 22, 2012

libusi++ comeback

Polished some old code of mine, libusi++.


The C++ UNIX Socket Interface allows for easy capture
and release of IP, IP6, ICMP, ICMP6, UDP, UDP6, TCP, TCP6,
and ARP packets. This can be extended of corse. You can
register your own Layer2 functions (RAW sockets and IP/eth dnet
interfaces are included) to support any kind of NIC or
layer you wish. The default capture layer is libpcap.


Writing a multi protocol traceroute like program is as easy
as this.
The whole online documentation is here.


I use this lib for my own tools, and I will even change
the API if I face shortcomings. I'll try to keep that stable,
but the preference is that my own stuff is working.
You have been warned, so do not blame me for potential
changes. I know that this might be a bit un-social
on a social platform like github, but I used to have
no friends in social networks anyway. :)


I tested libusi++ on Linux and FreeBSD. When I started the
project >10 years ago, it even worked on OpenBSD.





Tuesday, March 20, 2012

contribs

I'll put some of my smaller tools to the contrib github.


For now it contains ssh-sign, which allows to use your
existing SSH hostkeys to encrypt/decrypt (RSA)
or sign (RSA and DSA) files. You can verify the signed
files against your ~/.ssh/known_hosts after fetching.


This for instance allows to add integrity to pure HTTP
downloads if you have the SSH hostkey handy since you once
ssh'ed to that host.

Friday, March 9, 2012

removing #ifdef's where possible

I am tickling developers about unreadable code, even
if its secure, the whole day at work. So its just fair
that I try to write code as clean as possible myself.
While there are different views on what resembles clean
code (in my personal view its the possibility to
add concurrency and new features without a large re-write
and still keeping an easy overview, IOW you can
refactor your code fast), conditional compilation is
usually seen as one of the evils.


Conditional compilation, aka #ifdef's, are even mentioned
in Effective C++. For small code snippets it might be acceptable,
but traditionally #ifdef's are used to make programs compile
on various UNIX flavors.That makes code unreadable and potentially
buggy, in particular if the #ifdef's guard different
call semantics for the same function, just like sendfile().


I decided to remove the #ifdef's alltogether from lophttpd,
by introducing a flavor namespace, and implementing a generic
function for each flavor. That moves the conditional
compilation logic to the Makefile or configure script.
Thats one of the commits for it.


No praying without paying: We buy the easy reading and clean
code by a little bit of code duplication for similar
flavors (for example sendfile() on Linux and Android flavor)
but thats at the time of writing/maintaining, not at runtime.
The other price is that you buy another function call
for code that could have been inlined. But as a whole,
thats cheap today, compared to the hassle one can have.


I am not banning #ifdef's, there are good reasons
for some of them and if you write code at the Linux driver-
(or rootkit-) level with a lot of API changes between
kernel versions, its sometimes the best way to go.
Yet, sometimes if you look at the code, it just feels wrong
and thats the point where you should change it.



Thursday, March 8, 2012

github pwnage

After recent github pwnage, I checked the integrity of my
repositories, and its all OK. The SSH keys are also fine.
So go ahead and checkout. :)

Friday, March 2, 2012

systemd CVE-2012-0871 trickery

Systemd is the Dekstop replacement for /sbin/init, aiming
to faster boot Linux desktop systems and to better integrate
user session tracking etc.. Part of systemd is systemd-logind
which exactly does that by creating files (ore more
precisely hardlinks and symlinks) inside the /run/user
directory upon X11 desktop logins. Such work was commonly
done by desktop managers like gdm (CVE-2011-0727) or kdm
(CVE-2010-0436). Both failed to securely handle files
inside user owned directories, and so does systemd-logind.


The header shows you where the problem is. We actually need
to race two unlink() calls to end in a symlink() call
that is of use. A link() would just create a hardlink to
the $DISPLAY UNIX-socket which is useless, except you have another
file-remove exploit which you can use to replace
/tmp/.X11-unix/X0 before the link() is called.(This would also
remove the requirement for having console access to exploit
this bug and the need for a race.)


So far. By messing with files and directories inside /run/user
we can create a symlink called display inside arbitrary
system directories pointing to /tmp/.X11-unix/$DISPLAY.
/etc/pam.d is a good choice if you
have kcheckpass installed. /etc/cron.d is another, but
crond only accepts root cronjobs from files
owned and writable by root. So placing a display symlink
somewhere to /home/attacker/foo is of no use.
But wait; is not root's mailbox mode 0600, owned by root
and writable by users by sending him an email?
Yes it is. So lets just do that. crond will ignore leading
and trailing garbage until it finds attackers
cronjob. The symlink from /tmp/.X11-unix/$DISPLAY to
/var/mail/root is made during the restart of the X11
display. Thats why a Ctrl+Alt+Backspace is necessary.
As mentioned, this is not needed if you combine another
file unlink vulnerability.


I wrote the PoC for a core i5, x86_64 and run it successfully
on a FC16 and a openSUSE 12.1. Since we need to race two
times, there is no easy pattern to just brute-fork it,
as we would race to ourself then. Maybe the use of inotify
is an option to make the PoC more reliable (for me it takes
3 or 4 tries to succeed, so thats enough stability for a PoC).