all repos — site @ 6b66f5122d3818bdd3047a52520fbb6345e06de1

source for my site, found at icyphox.sh

build/blog/rop-on-arm/index.html (view raw)

  1<!DOCTYPE html>
  2<html lang=en>
  3<link rel="stylesheet" href="/static/style.css" type="text/css">
  4<link rel="stylesheet" href="/static/syntax.css" type="text/css">
  5<link rel="shortcut icon" type="images/x-icon" href="/static/favicon.ico">
  6<meta name="description" content="Making stack-based exploitation great again!">
  7<meta name="viewport" content="initial-scale=1">
  8<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  9<meta content="#021012" name="theme-color">
 10<meta name="HandheldFriendly" content="true">
 11<meta name="twitter:card" content="summary_large_image">
 12<meta name="twitter:site" content="@icyphox">
 13<meta name="twitter:title" content="Return Oriented Programming on ARM (32-bit)">
 14<meta name="twitter:description" content="Making stack-based exploitation great again!">
 15<meta name="twitter:image" content="/static/icyphox.png">
 16<meta property="og:title" content="Return Oriented Programming on ARM (32-bit)">
 17<meta property="og:type" content="website">
 18<meta property="og:description" content="Making stack-based exploitation great again!">
 19<meta property="og:url" content="https://icyphox.sh">
 20<meta property="og:image" content="/static/icyphox.png">
 21<html>
 22  <title>
 23    Return Oriented Programming on ARM (32-bit)
 24  </title>
 25<script src="//instant.page/1.1.0" type="module" integrity="sha384-EwBObn5QAxP8f09iemwAJljc+sU+eUXeL9vSBw1eNmVarwhKk2F9vBEpaN9rsrtp"></script>
 26<div class="container-text">
 27  <header class="header">
 28     <a href="../">‹ back</a>
 29  </header>
 30<body> 
 31   <div class="content">
 32    <div align="left">
 33      <p> 05 June, 2019 </p>
 34      <h1>Return Oriented Programming on ARM (32-bit)</h1>
 35
 36<h2>Making stack-based exploitation great again!</h2>
 37
 38<p>Before we start <em>anything</em>, you’re expected to know the basics of ARM
 39assembly to follow along. I highly recommend
 40<a href="https://twitter.com/fox0x01">Azeria’s</a> series on <a href="https://azeria-labs.com/writing-arm-assembly-part-1/">ARM Assembly
 41Basics</a>. Once you’re
 42comfortable with it, proceed with the next bit — environment setup.</p>
 43
 44<h3>Setup</h3>
 45
 46<p>Since we’re working with the ARM architecture, there are two options to go
 47forth with: </p>
 48
 49<ol>
 50<li>Emulate — head over to <a href="https://www.qemu.org/download/">qemu.org/download</a> and install QEMU. 
 51And then download and extract the ARMv6 Debian Stretch image from one of the links <a href="https://blahcat.github.io/qemu/">here</a>.
 52The scripts found inside should be self-explanatory.</li>
 53<li>Use actual ARM hardware, like an RPi.</li>
 54</ol>
 55
 56<p>For debugging and disassembling, we’ll be using plain old <code>gdb</code>, but you
 57may use <code>radare2</code>, IDA or anything else, really. All of which can be
 58trivially installed.</p>
 59
 60<p>Finally, the binary we’ll be using in this exercise is <a href="https://twitter.com/bellis1000">Billy Ellis’</a>
 61<a href="/static/files/roplevel2.c">roplevel2</a>. </p>
 62
 63<p>Compile it:</p>
 64
 65<div class="codehilite"><pre><span></span><code>$ gcc roplevel2.c -o rop2
 66</code></pre></div>
 67
 68<p>With that out of the way, here’s a quick run down of what ROP actually is.</p>
 69
 70<h3>A primer on ROP</h3>
 71
 72<p>ROP or Return Oriented Programming is a modern exploitation technique that’s
 73used to bypass protections like the <strong>NX bit</strong> (no-execute bit) and <strong>code sigining</strong>.
 74In essence, no code in the binary is actually modified and the entire exploit
 75is crafted out of pre-existing artifacts within the binary, known as <strong>gadgets</strong>.</p>
 76
 77<p>A gadget is essentially a small sequence of code (instructions), ending with
 78a <code>ret</code>, or a return instruction. In our case, since we’re dealing with ARM
 79code, there is no <code>ret</code> instruction but rather a <code>pop {pc}</code> or a <code>bx lr</code>.
 80These gadgets are <em>chained</em> together by jumping (returning) from one onto the other
 81to form what’s called as a <strong>ropchain</strong>. At the end of a ropchain,
 82there’s generally a call to <code>system()</code>, to acheive code execution.</p>
 83
 84<p>In practice, the process of executing a ropchain is something like this:</p>
 85
 86<ul>
 87<li>confirm the existence of a stack-based buffer overflow</li>
 88<li>identify the offset at which the instruction pointer gets overwritten</li>
 89<li>locate the addresses of the gadgets you wish to use</li>
 90<li>craft your input keeping in mind the stack’s layout, and chain the addresses
 91of your gadgets</li>
 92</ul>
 93
 94<p><a href="https://twitter.com/LiveOverflow">LiveOverflow</a> has a <a href="https://www.youtube.com/watch?v=zaQVNM3or7k&amp;list=PLhixgUqwRTjxglIswKp9mpkfPNfHkzyeN&amp;index=46&amp;t=0s">beautiful video</a> where he explains ROP using “weird machines”. 
 95Check it out, it might be just what you needed for that “aha!” moment :)</p>
 96
 97<p>Still don’t get it? Don’t fret, we’ll look at <em>actual</em> exploit code in a bit and hopefully
 98that should put things into perspective.</p>
 99
100<h3>Exploring our binary</h3>
101
102<p>Start by running it, and entering any arbitrary string. On entering a fairly
103large string, say, “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”, we
104see a segmentation fault occur.</p>
105
106<p><img src="/static/img/string_segfault.png" alt="string and segfault" /></p>
107
108<p>Now, open it up in <code>gdb</code> and look at the functions inside it.</p>
109
110<p><img src="/static/img/gdb_functions.png" alt="gdb functions" /></p>
111
112<p>There are three functions that are of importance here, <code>main</code>, <code>winner</code> and 
113<code>gadget</code>. Disassembling the <code>main</code> function:</p>
114
115<p><img src="/static/img/gdb_main_disas.png" alt="gdb main disassembly" /></p>
116
117<p>We see a buffer of 16 bytes being created (<code>sub sp, sp, #16</code>), and some calls
118to <code>puts()</code>/<code>printf()</code> and <code>scanf()</code>. Looks like <code>winner</code> and <code>gadget</code> are 
119never actually called.</p>
120
121<p>Disassembling the <code>gadget</code> function:</p>
122
123<p><img src="/static/img/gdb_gadget_disas.png" alt="gdb gadget disassembly" /></p>
124
125<p>This is fairly simple, the stack is being initialized by <code>push</code>ing <code>{r11}</code>,
126which is also the frame pointer (<code>fp</code>). What’s interesting is the <code>pop {r0, pc}</code>
127instruction in the middle. This is a <strong>gadget</strong>.</p>
128
129<p>We can use this to control what goes into <code>r0</code> and <code>pc</code>. Unlike in x86 where
130arguments to functions are passed on the stack, in ARM the registers <code>r0</code> to <code>r3</code>
131are used for this. So this gadget effectively allows us to pass arguments to
132functions using <code>r0</code>, and subsequently jumping to them by passing its address
133in <code>pc</code>. Neat.</p>
134
135<p>Moving on to the disassembly of the <code>winner</code> function:</p>
136
137<p><img src="/static/img/gdb_disas_winner.png" alt="gdb winner disassembly" /></p>
138 
139    </div>
140   </body>
141  </div>
142</html>