
Implementing a web server in a single printf() call - pdq
http://tinyhack.com/2014/03/12/implementing-a-web-server-in-a-single-printf-call/
======
goldenkey
It's called Shellcode. These kids these days with their exclusive Ruby on
Rails knowledge. "Shell what? Oh you mean that new band that you probably
never heard of?"

~~~
joebo
I don't see ruby mentioned anywhere and the article mentions shellcode. I
thought it was informative and interesting and I am well aware of shellcode.
Your comment is unnecessarily condescending and may discourage posts like
this.

~~~
pessimizer
>may discourage posts like this.

That may be goldenkey's goal, and shouldn't be discouraged either. Someone's
opinion that something is awful and doesn't belong here is just as legitimate
as your opinion that something is informative and interesting.

Your comment is unnecessarily condescending and may discourage comments like
this.

~~~
scott_s
I disagree. Most opinions that state "I already knew this, and you should too"
are banal and do not lead to interesting discussion. And the moderation system
of this site is set up to promote interesting discussion.

~~~
goldenkey
True but my comment was more directed at the disenfranchising nature of 'using
printf.' Printf has nothing to do with shellcode, and is just a silent
mockdrop of BS to entice those who would probably click onto the next article
of a real explanation of shellcode were had. I prefer frankness to BS even if
the frank explanation intimidates most.

------
austinz
If you want to read more about shellcode/C vulnerabilities you can check out
the Phrack and other links at Stanford's CS155 web site:
[https://courseware.stanford.edu/pg/assignments/view/280907/b...](https://courseware.stanford.edu/pg/assignments/view/280907/buffer-
overflow-1)

The Buffer Overflow #1 and #2 projects might also be worth checking out. You
can download the project description, starter code, and VM image, and see if
you can write code to get the root shell.

~~~
voltagex_

      The requested URL /cs155/hw_and_proj/pp1/boxes-2.3.tar.bz2 was not found on this server.
    

From
[https://crypto.stanford.edu/cs155/hw_and_proj/pp1/boxes-2.3....](https://crypto.stanford.edu/cs155/hw_and_proj/pp1/boxes-2.3.tar.bz2)
which is the VM image link.

Anyone got any contacts at Stanford?

~~~
austinz
If you change https to http, it works for me (and I'm not logged in or
privileged in any way).

------
nostrademons
I did something like this in Haskell a few years ago, largely as an
entertaining practical joke:

[http://pastebin.com/6kfwTsB0](http://pastebin.com/6kfwTsB0)

~~~
sedev
I admire that feat at the same time as I have an overwhelming urge to take a
cheap shot about which Haskell projects are entertaining practical jokes.

------
userbinator
When I read the title I thought it was going to be a printf("HTTP/1.1 200
OK..."); sort of thing, but I was pleasantly surprised.

------
zobzu
if you're going to insert a shell code into printf, then well... you can
implement anything in printf... or in memcpy.. or in strcat.. or whatever
really.

~~~
yalue
Heck, why not just title it "a web server with no library function calls" and
call an array of bytes as a function? Then everybody would be able to see what
it really is, which is an unremarkable shellcode embedded directly in a C
program. I feel like the "printf" was only included so that people would have
something to recognize in the title.

~~~
anon4
By that logic you could just execve httpd with shellcode. Or ruby. Or a ruby
program that generates a perl script that compiles a Prolog program to
shellcode that looks like it prints hello world, but actually does execve
httpd.

------
kentuckyduck
I got segmentation fault trying out his hello world example (after changing
VMA address). Then again, isn't that the supposed behavior? Not every memory
page can be written to, if I remember correctly.

~~~
evandrix
Yes, segfault for me too after i changed ADDR preprocessor directive to the
VMA address from objdump, as the instruction says. I'm on Ubuntu Linux 13.10
x64.

~~~
yohanes
Ubuntu adds a security feature that provides a read-only relocation table area
in the final ELF. To be able to run the examples in ubuntu, add this in the
command line when compiling

-Wl,-z,norelro

e.g:

gcc -Wl,-z,norelro test.c

~~~
evandrix
ok, now it compiles, thanks for that. However, I'm getting an incomplete
response "<h1>hello world</h1" without the trailing closing angled bracket.
And when I try to run final.c after setting the FUNCTION_ADDR and ADDR as per
your tutorial, I get some stray HTTP/1.0 200 and Content-type text/html being
displayed on stdout as I start the program final.c (compiled to a.out by
default)

~~~
yohanes
Ah, you have found a bug in my code (I made an error in computing the string
length, and didn't notice it because it displayed fine on Chrome). I have
fixed my code in git and the blog post.

As for the stray output displayed on the stdout: it is to be expected. The %n
format outputs the numbers of character that is written by printf, so it must
have written something to the stdout.

~~~
evandrix
Ah! that explains so much (and also why i've wasted a whole hour figuring out
why what I observed was happening) I'm a CLI curl guy, rather than relying on
these browsers which randomly would add a 0x0d 0x0a to my form submissions,
for example. I also noticed that compiling (assembling-linking) the .S to
execute it would not print anything (just hang there like a normal webserver),
but I was getting stuff written to stdout with the final.c/webserver.c version
using its shellcode.

~~~
mvirkkunen
Did you also post this reply using curl?

------
Morgawr
Really nice, it's so weird that format strings support %n, it's such a massive
security vulnerability that I don't really know what was going on in the mind
of the guy that decided to implement this.

But alas, it's always fun to see. Here's an excellent article on format string
vulnerabilities, an amazing read:
[http://crypto.stanford.edu/cs155/papers/formatstring-1.2.pdf](http://crypto.stanford.edu/cs155/papers/formatstring-1.2.pdf)

~~~
psionski
C was designed way before security was a concern. If somebody exploited your
program, you could just slap them because they'd be sitting at a terminal in
the same room with you - no need for fancy ASLR or controlling how many
characters you write to a buffer when physical violence was a viable option :)

~~~
kjs3
This isn't even remotely true. Computer security was a concern and an area of
study long before C/Unix showed up. Unix (and by extension C) descended
directly from the Multics project, which from its start in 1964 made security
a central priority. Kernighan and Ritche were important members of the Multics
project. Further, the idea that everyone who used the computers of that era
were "in the same room" is also patently absurd.

~~~
psionski
I like my fantasy about how things were back then better, thankyouverymuch. At
least this way I can believe they didn't unleash the flood of pwnage on the
world while knowing better.

------
kang
I wish for a forum/site with links only like these! Pure code hacking.

~~~
kreeben
Seems to be available: purecodehacking.com. Do it!

------
DateK
maintenance nightmare

~~~
tonyarkles
Understatement of the year!

