18 comments

[ 2.9 ms ] story [ 49.2 ms ] thread
Which distros don't have the openbsd package?
OpenBSD is a type of UNIX operating system. The OpenBSD project focuses on security. Www.openbsd.org
Sorry, I misunderstood the question. Please disregard.
Some of them allow you to choose, I don't think many distros have the openbsd-netcat installed as default choice though.

I run Manjaro on my laptop and we have gnu-netcat as default with the choice of installing openbsd-netcat instead. On my Debian servers I have just "nc" which, if I'm not wrong, is the standard netcat (non-gnu/non-bsd).

Lots of network devices will not have nc, wget, curl, etc. Which makes exploiting cmd injection annoying, you often have to drop a bin in chunks using hex-formatted echo.
Good writeup, not enough people go in depth like this on shellcode!

Metasploit has some decent shellcode. What you wrote here is essentially a specialized execve payload. Some of metasploit's execve payloads support passing arguments to execve, by building the args array on the fly:

https://github.com/rapid7/metasploit-framework/blob/master/m...

There are also lots of reverse shells like this, and reverse stagers too. Additionally, there are other solutions to bind shells being noisy:

See https://github.com/rapid7/metasploit-framework/pull/3017

Which causes the port to show as "closed" in a scan, and

https://github.com/rapid7/metasploit-framework/pull/2981

Which prevents other IPs from jacking your shells.

EDIT: also I think you need a null byte at the end of everything, otherwise the last arg string might not terminate correctly depending on what's in memory.

>also I think you need a null byte at the end of everything, otherwise the last arg string might not terminate correctly depending on what's in memory.

That is what mov long [esi+64],eax does at line 19, it puts a NULL on top of FFFF to properly terminate the array of parameters. It is also reused as last argument of execve() at line 23.

I know I have tested this shellcode against a vulnerable machine (as a CTF, nothing illegal) and it worked well enough.

"I know I have tested this shellcode against a vulnerable machine..."

In your article you say arguments to syscalls via interrupt 0x80 are passed in registers. That sounds like Linux and Microsoft.

Have you tested this against a vulnerable machine that passes arguments on the stack?

I think I read somewhere that this is how UNIX handles arguments.

Maybe I should've dug a bit deeper in the details with the syscalls stuff, but I didn't want to make it become a tedious read.

System calls on Linux (I'm no windows or BSD/OSX expert so I can't talk about those systems) used to be handled with int 0x80 instructions and even today this has become a common myth/misconception. Since Pentium 4 the architecture has changed in favor of better performance with the linux-gate/linux-vdso virtual system call bridge[0]and modern system calls in actual applications/libc use sysenter/sysexit. There's still compatibility for "legacy" int 0x80 though so this is not a problem.

This said, int 0x80 expects system calls arguments to be passed on the registers on Linux, again I don't know about Windows and BSD/OSX. Keep in mind that this article is very "naive" in writing and expectations, most of these buffer overflow exploits don't even work anymore in most servers, most distributions provide memory protection, ASLR, stack guards, canaries, read-only GOT, etc etc. There are still interesting ways to skip these security measures[1][2] but this is unrelated.

Bottom line is, take this article with a grain of salt, it's purely educational/informative, not aimed towards actually exploiting modern vulnerable systems :)

[0] http://www.trilithium.com/johan/2005/08/linux-gate/

[1] https://en.wikipedia.org/wiki/Return-oriented_programming

[2] http://www.cs.vu.nl/~herbertb/papers/srop_sp14.pdf

Most BSDs kernels have an emulator mode when they accept int 0x80 syscalls. Some parameters are different than Linux though.
Ah cool I see that now, thanks :) It would have been the kind of bug that only bothers you once in a while, that's why I pointed it out.
Now lets see you find kernel32.dll and do it on windows when you can't make syscalls however you want =].

Good write-up it was well written and very understandable.

This reminds me I need to go back to microcorruption.com :)
This article assumes -e working in netcat, that is not the case since many years ago.

For -e to work, you have to compile netcat.c defining GAPING_SECURITY_HOLE, one of the best self-documenting options there are.

Needless to say, most distros do not activate it.

You're actually wrong. If you read the article I mention both -e and -c. As of today, most of my Debian servers support -c and -e out of the box, Manjaro/Arch runs -e without problems, the other Debian/Ubuntu servers I have also run -e out of the box.

Of course, this is just an educational post, there are better ways to take over a victim's machine. And there are a million ways this shellcode could go wrong, the availability of -e/-c is really the least of your problems in 2014.

Which version of debian? it does not work in latest Ubuntu, the most popular distro.