SSH honeypot, deployed in the wild, collecting and sharing data

Jon Erickson 'Hacking: The Art of Exploitation' Book Review

14 Dec 2013 • 8 min read

Book coverI recently finished reading Jon Erickson's book Hacking: The art of Exploitation. Since the book relates to my project; building an SSH honeypot in C to research cyber-attack techniques, I thought writing a review of the book and how it relates to this project would be helpful.

The book consists of the following sections:

  • 0x100 Introduction
  • 0x200 Programming
  • 0x300 Exploitation
  • 0x400 Networking
  • 0x500 Shellcode
  • 0x600 Countermeasures
  • 0x700 Cryptology
  • 0x800 Conclusion

Erickson opens with an explanation of what the term hacking actually means, where the term came from and who a hacker is. Erickson also discusses the mainstream media's use of the word "hacker", how it's often portrayed in a negative light, and how the terms original meaning can be somewhat lost in modern references.

The section entitled "Programming" introduces the main programming concepts such as control structures, variables, arithmetic etc and also introduces the programming language C. This section also introduces assembly language and the x86 processor.

Having covered the basics of programming, assembly language and C, the book then moves onto Exploitations that exist in:

  • Stack based buffer overflows
  • Heap based overflows
  • Overflowing function pointers
  • Format strings

It was during this part of the book that I realised just how vulnerable some my code implementation for this project is.

The main objective of these exploits is to inject shellcode into the system's memory, therefore altering the program's flow and "hijacking" the CPU without the system being aware that the program flow has been hijacked.

Buffer Overflow

One of the main ways of injecting shellcode into a C program is in a buffer overflow vulnerability. A buffer overflow occurs when the contents of a variable, which has a fixed size (e.g. 8 bytes), overflows into the memory adjacent to the variable. This concept is explained further in the Wikipedia extract below:

In the following example, a program has two data items which are adjacent in memory: an 8-byte-long string buffer, A, and a two-byte big-endian integer, B.

char A[8] = {};
unsigned short B = 1979;

Initially, A contains nothing but zero bytes, and B contains the number 1979:

variable name A B
value [null string] 1979
hex value 00 00 00 00 00 00 00 00 07 BB

Now, the program attempts to store the null-terminated string "excessive" with ASCII encoding in the A buffer.

strcpy(A, "excessive");

The string "excessive" is 9 characters long and encodes to 10 bytes including the terminator ('\0'), but A can take only 8 bytes. By failing to check the length of the string, it also overwrites the value of B:

variable name A B
value 'e' 'x' 'c' 'e' 's' 's' 'i' 'v' 25856
hex 65 78 63 65 73 73 69 76 65 00

B's value has now been inadvertently replaced by a number formed from part of the character string. In this example "e" followed by a zero byte would become 25856.

Writing data past the end of allocated memory can sometimes be detected by the operating system to generate a segmentation fault error that terminates the process.

Stack Buffer Overflow

One way to achieve a buffer overflow is by using the stack. The stack is used to hold a program's local variables and grows upwards. Memory allocation on the stack is contiguous; i.e. variable A sits next to variable B. If the contents of variable A overflow, they will spill into the adjacent variable B's memory.

The stack buffer overflow is explained further in the Wikipedia extract below:

The canonical method for exploiting a stack based buffer overflow is to overwrite the function return address with a pointer to attacker-controlled data (usually on the stack itself). This is illustrated in the example below:

#include <string.h>
void foo (char *bar)
   char  c[12];
   strcpy(c, bar);  // no bounds checking
int main (int argc, char **argv)

This code takes an argument from the command line and copies it to a local stack variable c. This works fine for command line arguments smaller than 12 characters (as you can see in figure B below).

Any arguments larger than 11 characters long will result in corruption of the stack. (The maximum number of characters that is safe is one less than the size of the buffer here because in the C programming language strings are terminated by a zero byte character ('\0').

A twelve-character input thus requires thirteen bytes to store, the input followed by the sentinel zero byte. The zero byte then ends up overwriting a memory location that's one byte beyond the end of the buffer.)

stack buffer overflow diagram stack buffer overflow diagram stack buffer overflow diagram
A: Before data is copied. B: "hello" is the first command line argument. C: "A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​\x08​\x35​\xC0​\x80" is the first command line argument.

How these vulnerabilities relate to my project

One of the main examples of a vulnerability in my code is when reading input from the client via the libssh method ssh_channel_read:

int rc;
char c, buffer[1024];

if ( (rc = ssh_channel_read(chan, &c, 1, 0)) == 1 ) {
    *buffer++ = c;
    if ( c == '\n' )

This code copies one byte at a time from the SSH input channel into the string buffer which is a fixed size string of 1024 bytes.

The major problem here is that there is no bound checking when copying into the string buffer. An attacker could have easily sent a message which was longer than 1024 characters long, with shellcode overflowing into the proceeding memory locations.

This problem was overcome by encasing the code into a for loop:

int rc, n;
char c, buffer[1024];

for ( n = 1; n < 1024; n++ ) {
    if ( (rc = ssh_channel_read(chan, &c, 1, 0)) == 1 ) {
        *buffer++ = c;
        if ( c == '\n' )

This for loop ensures that the process of copying bytes into the buffer string is never repeated more than 1024 times which is the length of the string buffer.

I personally found the exploitation section of the book to be most useful because it analysed some of the major vulnerabilities in C. Since reading this section I've been a lot more careful about how I implement C code.

Network Exploitations

In this section of the book Erickson begins with an explanation of sockets and how they are used to allow the operating system to access physical networking interfaces on the computer.

The book then introduces the concept of layers in networking and introduces the main three layers: data-link, network and transport.

With an introduction to networks concluded; Erickson goes on to explain packet sniffing, denial of service attacks, TCP/IP hijacking and port scanning. The chapter ends with a detailed explanation of a network attack using port-binding shellcode.

It's interesting to understand how attacks such as denial of service (or DoS) actually work. There has been a lot of attention in the media in recent years of how hactivist groups such as Anonymous have been DDoSing organisations such as Mastercard, PayPal and Government websites. This section explains how these attacks are carried out and what's actually going on inside the machine that's being attacked.


By this point; the book has mentioned several shellcode examples and provided copy-and-paste examples to carry out shellcode attacks.

This section explains exactly what shellcode is along with the comparisons between assembly language and C. Erickson really does go into thorough detail about composing shellcode to achieve specific attacks.

At present, my experience of using assembly language is quite limited. So although I understood this section of the book, I wouldn't feel confident actually writing shellcode from scratch just yet.


The countermeasures section of the book discusses the various ways in which attackers might get caught by various logs etc on a system. Erickson discusses a number of techniques and ways of thinking to avoid sticking out in log files to a system admin.

This section also discusses some "tools of the trade" which can be used to make hacking easier. However, Erickson explains how a good hacker will create her own tools to "automate tedious tasks" and "extend the skill of the user". I particularly like Erickson's metaphorical use of a gun as a singular utility:

"The fine line between an exploit program and an exploit tool is a matter of finalization and recon- figurability. Exploit programs are more like guns than tools. Like a gun, an exploit program has a singular utility and the user interface is as simple as pulling a trigger. Both guns and exploit programs are finalized products that can be used by unskilled people with dangerous results. In contrast, exploit tools usually arenít finished products, nor are they meant for others to use. With an understanding of programming, itís only natural that a hacker would begin to write his own scripts and tools to aid exploitation. These personalized tools automate tedious tasks and facilitate experimentation. Like conventional tools, they can be used for many purposes, extending the skill of the user."


This section is fairly brief but provides a good overview of how everything we do in computers is secured using cryptography.

Erickson explains what the umbrella term cryptology means along with an explanation of the difference between cryptography and cryptanalysis.

The mathematical process of cryptography is explained well and the two main types of encryption: symmetric and asymmetric are covered within this explanation. The concept of quantum cryptography is also introduced in this section.


This book has really helped me to understand some of the fundamental areas of Linux and C vulnerabilities. The underpinning message of the book is to think like a hacker; which mainly involves thinking outside the box and coming up with new ways of exploiting a system.

I particularly like Erickson's comprehensive code examples, throughout the book, where the reader is walked through an entire exploitation, step-by-step. The reader is encouraged to try these exploitations on the provided bootable CD and I like this hands on approach to learning which the book adopts.

If you just want to learn how to use "off-the-shelf" tools to hack into systems then this book definitely isn't for you. However, this book will provide a knowledge hungry reader, with an interest in computer security, with detailed information on how to investigate a system for vulnerabilities and then write their own exploitation code.

After reading this book; the reader should be on their way to carrying out custom attacks on specific, targeted systems. In my opinion this is far more powerful than being able to use generic tools to attack generic systems. However, learning exploitation techniques and developing a hacking mindset does require a significant investment of time and plenty of practice.

I'm currently in my final year of a computer science degree and it definitely helped to have this prior knowledge when reading the book. Erickson does a fantastic job of explaining all the subjects well, but a reader without some prior knowledge of computer science might struggle with parts of this book.

Overall: an insightful book and definitely well worth a read if you're interested in learning the basic concepts of hacking and, specifically, how to exploit a Linux system using C and shellcode.

About the author

Simon BellSimon Bell is an award-winning Cyber Security Researcher, Software Engineer, and Web Security Specialist. Simon's research papers have been published internationally, and his findings have featured in Ars Technica, The Hacker News, PC World, among others. He founded Secure Honey, an open-source honeypot and threat intelligence project, in 2013. He has a PhD in Cyber Security from Royal Holloway's world-leading Information Security Group.

Follow Simon on Twitter: @SimonByte