Months ago, I wrote hello world in X86 Assembly, and later that same day
I wrote hello world in Python. Python is fast, elegant, and powerful.
But unfortunately, it doesn’t really give you an understanding of what’s
going on inside your computer. And any good little hacker should know
precisely what’s going on inside their computer.
Every time I start teaching myself some complicated thing, I try to make
the learning process enjoyable because I know that I’ll retain more
information if I can apply it to something fun or useful. Being a
terribly precocious kid, I taught myself quantum mechanics when I was
fourteen. It was really difficult, and I probably wouldn’t have been
able to pull it off if I hadn’t made it fun. And, oh, did I make it fun:
FOIA’ed thermonuclear weapons manuals, ten years expired, from some
obscure and slightly sketchy web page. I didn’t mean any harm, and I
neither was nor am a proponent of nuclear weapons production,
maintenance, or warfare. I wasn’t planning on starting up an Uranium-238
enrichment program, or searching the black markets for hollow plutonium
cores. I wanted to learn physics, and what’s more fun than learning how
to destroy things?
Assembly languages are cumbersome and arcane. The learning curve is
steep, and progress is always slow compared to higher level programming
languages. Fortunately, however, Assembly can be used to destroy things!
Enter shellcode.
The best introduction I found to writing shellcode was in Gray Hat
hacking, so I’m going to quote the first few pages of the Linux
shellcoding chapter, and then leave you to somehow obtain your own
copy.
Basic Linux Shellcode
The term “shellcode” refers to self-contained binary code that
completes a task. The task may range from issuing a system command to
providing a shell back to the attacker, as was the original purpose of shellcode.
There are basically three ways to write shellcode:
- Directly write the hex opcodes.
- Write a program in a high level language like C, compile it, and
then disassemble it to obtain the assembly imstructions and hex opcodes.
- Write as assembly program, assemble the program, and then extract
the hex opcodes from the binary.
Writing the hex opcodes directly is a little extreme. We will start
with learning the C approach, but quickly move to writing assembly,
then to extraction of the opcodes. In any event, you will need to
understand low level (kernel) functions such as read, write, and
execute. Since these system functions are performed at the kernel
level, we will need to learn a little about how user processes
communicate with the kernel.
System Calls
The purpose of the operating system is to serve as a bridge between
the user (process) and the hardware. There are basically three ways to
communicate with the operating system kernel:
- Hardware interrupts For example, an asynchronous signal from
the keyboard
- Hardware traps For example, the result of an illegal “divide …
read more