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.
read moreBasic 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 …