Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Top Posters

Who's Online (0)

Powered by Vanilla. Made with Bootstrap.
Examining memory in GDB
  • [------------------------]
    Paper name: Examining memory in GDB
    Author: Chroniccommand
    http://iexploit.org/
    Sources: Wikipedia, Hacking: The art of exploitation second edition
    [------------------------]
    Contents:
    0x01..What is gdb?
    0x02..What is memory?
    0x03..Examining memory


    0x01 - What is gdb?
    gdb stands for GNU Debugger. It is the standard debugger used in all GNU/Linux systems. So your system probably has it too. If not, just install it with your package manager(pacman, apt-get etc). GDB was written by Richard Stallman, the creator of UNIX. GDB is in my opinion the most powerful debugger out there. As with other debuggers you can inspect a program as much as you want. You may run, stop, examine the program. You may set breakpoints and step in and out of a program. You can backtrace the stack within a program etc. For more information about GDB please visit
    http://en.wikipedia.org/wiki/GNU_Debugger
    The wikipedia entry has quite a bit of info. Also:
    http://www.gnu.org/software/gdb/
    For the actual site. To learn more on how to use gdb, type
    man gdb
    into your terminal and RTFM ;)
    [align=center]---Break---[/align]

    0x02 - What is memory
    If you've read my other papers/guides you notice I go a lot into memory. This is because it's an important aspect of computer security. So in this paper I won't go too much into it. Don't wanna be tooredundant. Anyway, memory refers to devices that are used to store data or program. When we create a program and assign variables, we are assigning those variables to memory. For instance
    int int_var=5;
    Assigns the value 5 to int_var, which is then stored in temporary memory, called RAM(Random Access Memory). Anyway that's the basics of memory. The computers most basic form of communication is Machine Language. This is very hard for humans to understand. So high up in the "chain" or whatever you wanna call it is Assembly Language. This is slightly easier than Machine Language but is still hard(Not impossible to learn though). Next we have high level languages. These are what you may be familiar with. High level languages include:
    C
    Fortran
    LISP
    etc..
    Of course there are many many more high level languages. These are just some common // well known ones. Anybody familiar with programming in a higher level language such as C knows that a C program cannot be execute until it is compiled. When you compile a program, it is converted into Machine Language, so the computer can understand it. Then the program can be executed(as long as there are no errors). A programming language that requires compiling is different from a language such as, lets say perl or python. With these languages, you interpret them during run time. An advantage of compiled languages is you can catch errors early on. Now a regular programmer is concerned with source code, and making the program work. But a hacker will be concerned with much more than that. A hacker will be concerned HOW it works, WHY it works. WHAT makes it tick. HOW it can be exploited etc. This is why knowledge of memory and Machine Language can be valuable to the hacker. One more quick thing you MUST know about memory. Memory is generally stored little endian style. This means the least significant byte is first. Meaning it's backwards. For more information on little/big endian, please have a look at
    http://en.wikipedia.org/wiki/Endianness

    [align=center]---Break---[/align]

    0x03 - Examining memory
    Now onto actually examining memory in gdb. Let's first have a look at this source code. NOTE: You should follow along on your system, as it is a good learning practice.
    ---------first.c---------
    #include <stdio.h>

    int main()
    {
    int i;
    for(i=0;i<10;i++)
    {
    printf("Hello, world!\n");
    }
    return 0;
    }
    -------------------------
    This code is simple. I won't explain what it does, as you should know. But basically, it loops ten times until Hello, world! is printed ten times. Now lets compile this using gcc and examine some memory. I'll add comments along the way using two pound symbols(##)
    -------------------------

    chronic@vandal&#58;~ $ gcc -g -o first first&#46;c
    chronic@vandal&#58;~ $ &#46;/first
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    Hello, world!
    chronic@vandal&#58;~ $ gdb -q first ##We open &#46;/first with gdb
    Using host libthread_db library \"/lib/tls/i686/cmov/libthread_db&#46;so&#46;1\"&#46;
    (gdb) list ## View the source code(you can also use l)
    1 #include &lt;stdio&#46;h&gt;
    2
    3 int main()
    4 {
    5 int i;
    6 for(i=0;i&lt;10;i++)
    7 {
    8 printf(\"Hello, world!\n\");
    9 }
    10 return 0;
    (gdb) break 3 ## Set a breakpoint at line 3
    Breakpoint 1 at 0x8048374&#58; file first&#46;c, line 3&#46;
    (gdb) run
    Starting program&#58; /home/chronic/first

    Breakpoint 1, main () at first&#46;c&#58;4
    4 {
    (gdb) disass main ## Disassemble the function main()
    Dump of assembler code for function main&#58;
    0x08048374 &lt;main+0&gt;&#58; push %ebp
    0x08048375 &lt;main+1&gt;&#58; mov %esp,%ebp
    0x08048377 &lt;main+3&gt;&#58; sub $0x8,%esp
    0x0804837a &lt;main+6&gt;&#58; and $0xfffffff0,%esp
    0x0804837d &lt;main+9&gt;&#58; mov $0x0,%eax
    0x08048382 &lt;main+14&gt;&#58; sub %eax,%esp
    0x08048384 &lt;main+16&gt;&#58; movl $0x0,0xfffffffc(%ebp)
    0x0804838b &lt;main+23&gt;&#58; cmpl $0x9,0xfffffffc(%ebp)
    0x0804838f &lt;main+27&gt;&#58; jle 0x8048393 &lt;main+31&gt;
    0x08048391 &lt;main+29&gt;&#58; jmp 0x80483a6 &lt;main+50&gt;
    0x08048393 &lt;main+31&gt;&#58; movl $0x8048484,(%esp)
    0x0804839a &lt;main+38&gt;&#58; call 0x80482a0 &lt;printf@plt&gt;
    0x0804839f &lt;main+43&gt;&#58; lea 0xfffffffc(%ebp),%eax
    0x080483a2 &lt;main+46&gt;&#58; incl (%eax)
    0x080483a4 &lt;main+48&gt;&#58; jmp 0x804838b &lt;main+23&gt;
    0x080483a6 &lt;main+50&gt;&#58; mov $0x0,%eax
    0x080483ab &lt;main+55&gt;&#58; leave
    0x080483ac &lt;main+56&gt;&#58; ret
    End of assembler dump&#46;
    (gdb) i r ## Short for info registers
    eax 0xbffff8b4 -1073743692
    ecx 0x48e0fe81 1222704769
    edx 0x1 1
    ebx 0xb7fd6ff4 -1208127500
    esp 0xbffff82c 0xbffff82c
    ebp 0xbffff888 0xbffff888
    esi 0xb8000ce0 -1207956256
    edi 0x0 0
    eip 0x8048374 0x8048374 &lt;main&gt;
    eflags 0x246 &#91; PF ZF IF &#93;
    cs 0x73 115
    ss 0x7b 123
    ds 0x7b 123
    es 0x7b 123
    fs 0x0 0
    gs 0x33 51
    (gdb) quit
    The program is running&#46; Exit anyway? (y or n) y

    -------------------------
    Now if you see some of my comments you can see some of what is going on. Now I'll go a little bit more in depth. First of all, we are using AT&T syntax, not intel syntax. If you want to set syntax to intel, type set-dis intel(depending on your gdb version you may need to type set-disassembly-flavor intel). For now on I will use intel syntax. So at first we use the list command to view the source code. gdb provides us line numbers for easy use. After we view the source code we are setting a breakpoint on line 3(function main). A break point basically tells the debugger to stop after it reaches that line, address etc. So now we run it inside the debugger and as you can see the debugger stops at line 3. After stopping at the set breakpoint, we type disass main(short for disasemble main). This will(obviously) disassemble the function main. At the far left we get the memory address. On the middle we get things such as push(push into stack), sub(subtract), jmp(jump) etc. Then on the far right we get the actions, such as what to do with a register or value.

    After disassembling the main function we type i r(Short for info registers), we get the registers. This includes some key registers:
    esp
    eip

    The esp, or Stack Pointer, points to the memory location in the stack. The eip, or Instruction Pointer, points to the next instruction to be executed. These are key registers needed for exploitation(I wont really go into it here, maybe in another guide).

    Now it's time to examine the memory addresses. This can be done using the gdb command x, short for examine. We can examine the memory in different ways:
    x
    hexadecimal
    o
    octal
    t
    binary
    u
    unsigned

    These can be used in combination with the x command to view the memory in different ways. For example:
    -------------------------

    (gdb) i r
    eax 0xbffff8b4 -1073743692
    ecx 0x48e0fe81 1222704769
    edx 0x1 1
    ebx 0xb7fd6ff4 -1208127500
    esp 0xbffff82c 0xbffff82c
    ebp 0xbffff888 0xbffff888
    esi 0xb8000ce0 -1207956256
    edi 0x0 0
    eip 0x8048374 0x8048374 &lt;main&gt;
    eflags 0x246 &#91; PF ZF IF &#93;
    cs 0x73 115
    ss 0x7b 123
    ds 0x7b 123
    es 0x7b 123
    fs 0x0 0
    gs 0x33 51
    (gdb) x/x $eip
    0x8048374 &lt;main&gt;&#58; 0x83e58955
    (gdb) x/u $eip
    0x8048374 &lt;main&gt;&#58; 2212858197
    (gdb) x/t $eip
    0x8048374 &lt;main&gt;&#58; 10000011111001011000100101010101
    (gdb) x/o $eip
    0x8048374 &lt;main&gt;&#58; 020371304525

    -------------------------

    So first we get the registers. Then we use x/x $eip to get the hexadecimal value of EIP. Notice how we can use $ in front of eip. This can be used for other registers such as esp. Then we view it unsigned, then binary then finally octal. Hexadecimal is probably one of the most used out there when examining memory. We can also add a number before to specify how much memory to examine. For example:
    --------------------------

    (gdb) i r eip
    eip 0x8048374 0x8048374 &lt;main&gt;
    (gdb) x/5x $eip
    0x8048374 &lt;main&gt;&#58; 0x83e58955 0xe48308ec 0x0000b8f0 0xc4290000
    0x8048384 &lt;main+16&gt;&#58; 0x00fc45c7
    (gdb) x/5u $eip
    0x8048374 &lt;main&gt;&#58; 2212858197 3833792748 47344 3291021312
    0x8048384 &lt;main+16&gt;&#58; 16532935

    ---------------------------
    So first we view 5 addresses of eip using hexadecimal. Then 5 using unsigned.
    Now of course there are different sizes called words that can be viewed.
    b
    byte
    h
    halfword(2 bytes)
    w
    word(4 bytes)
    g
    giant(8 bytes)
    Now take a look at this example where I view the register eip using x/5xb etc:
    ---------------------------

    (gdb) x/5bx $eip
    0x8048374 &lt;main&gt;&#58; 0x55 0x89 0xe5 0x83 0xec
    (gdb) x/5hx $eip
    0x8048374 &lt;main&gt;&#58; 0x8955 0x83e5 0x08ec 0xe483 0xb8f0
    (gdb) x/5wx $eip
    0x8048374 &lt;main&gt;&#58; 0x83e58955 0xe48308ec 0x0000b8f0 0xc4290000
    0x8048384 &lt;main+16&gt;&#58; 0x00fc45c7
    (gdb) x/5gx $eip
    0x8048374 &lt;main&gt;&#58; 0xe48308ec83e58955 0xc42900000000b8f0
    0x8048384 &lt;main+16&gt;&#58; 0x8300000000fc45c7 0xc713eb027e09fc7d
    0x8048394 &lt;main+32&gt;&#58; 0x01e8080484842404

    ---------------------------
    So as you can see we first view bytes, then half words, then words then giants. Simple enough.

    Well, I don't want to go too into this paper. I just wanted to dive into the basics of memory examination with gdb, which I have. I hope this served useful to you and you can further your exploitation career with examining memory addresses. I'll include the ASCII table here for you as a reference(You can find the ascii table on the internet or by typing man ascii):
    ------------------------------------------------------

    Decimal Octal Hex Binary Value
    ------- ----- --- ------ -----
    000 000 000 00000000 NUL (Null char&#46;)
    001 001 001 00000001 SOH (Start of Header)
    002 002 002 00000010 STX (Start of Text)
    003 003 003 00000011 ETX (End of Text)
    004 004 004 00000100 EOT (End of Transmission)
    005 005 005 00000101 ENQ (Enquiry)
    006 006 006 00000110 ACK (Acknowledgment)
    007 007 007 00000111 BEL (Bell)
    008 010 008 00001000 BS (Backspace)
    009 011 009 00001001 HT (Horizontal Tab)
    010 012 00A 00001010 LF (Line Feed)
    011 013 00B 00001011 VT (Vertical Tab)
    012 014 00C 00001100 FF (Form Feed)
    013 015 00D 00001101 CR (Carriage Return)
    014 016 00E 00001110 SO (Shift Out)
    015 017 00F 00001111 SI (Shift In)
    016 020 010 00010000 DLE (Data Link Escape)
    017 021 011 00010001 DC1 (XON) (Device Control 1)
    018 022 012 00010010 DC2 (Device Control 2)
    019 023 013 00010011 DC3 (XOFF)(Device Control 3)
    020 024 014 00010100 DC4 (Device Control 4)
    021 025 015 00010101 NAK (Negativ Acknowledgemnt)
    022 026 016 00010110 SYN (Synchronous Idle)
    023 027 017 00010111 ETB (End of Trans&#46; Block)
    024 030 018 00011000 CAN (Cancel)
    025 031 019 00011001 EM (End of Medium)
    026 032 01A 00011010 SUB (Substitute)
    027 033 01B 00011011 ESC (Escape)
    028 034 01C 00011100 FS (File Separator)
    029 035 01D 00011101 GS (Group Separator)
    030 036 01E 00011110 RS (Reqst to Send)(Rec&#46; Sep&#46;)
    031 037 01F 00011111 US (Unit Separator)
    032 040 020 00100000 SP (Space)
    033 041 021 00100001 ! (exclamation mark)
    034 042 022 00100010 \" (double quote)
    035 043 023 00100011 # (number sign)
    036 044 024 00100100 $ (dollar sign)
    037 045 025 00100101 % (percent)
    038 046 026 00100110 & (ampersand)
    039 047 027 00100111 ' (single quote)
    040 050 028 00101000 ( (left/open parenthesis)
    041 051 029 00101001 ) (right/closing parenth&#46;)
    042 052 02A 00101010 * (asterisk)
    043 053 02B 00101011 + (plus)
    044 054 02C 00101100 , (comma)
    045 055 02D 00101101 - (minus or dash)
    046 056 02E 00101110 &#46; (dot)
    047 057 02F 00101111 / (forward slash)
    048 060 030 00110000 0
    049 061 031 00110001 1
    050 062 032 00110010 2
    051 063 033 00110011 3
    052 064 034 00110100 4
    053 065 035 00110101 5
    054 066 036 00110110 6
    055 067 037 00110111 7
    056 070 038 00111000 8
    057 071 039 00111001 9
    058 072 03A 00111010 &#58; (colon)
    059 073 03B 00111011 ; (semi-colon)
    060 074 03C 00111100 &lt; (less than)
    061 075 03D 00111101 = (equal sign)
    062 076 03E 00111110 &gt; (greater than)
    063 077 03F 00111111 ? (question mark)
    064 100 040 01000000 @ (AT symbol)
    065 101 041 01000001 A
    066 102 042 01000010 B
    067 103 043 01000011 C
    068 104 044 01000100 D
    069 105 045 01000101 E
    070 106 046 01000110 F
    071 107 047 01000111 G
    072 110 048 01001000 H
    073 111 049 01001001 I
    074 112 04A 01001010 J
    075 113 04B 01001011 K
    076 114 04C 01001100 L
    077 115 04D 01001101 M
    078 116 04E 01001110 N
    079 117 04F 01001111 O
    080 120 050 01010000 P
    081 121 051 01010001 Q
    082 122 052 01010010 R
    083 123 053 01010011 S
    084 124 054 01010100 T
    085 125 055 01010101 U
    086 126 056 01010110 V
    087 127 057 01010111 W
    088 130 058 01011000 X
    089 131 059 01011001 Y
    090 132 05A 01011010 Z
    091 133 05B 01011011 &#91; (left/opening bracket)
    092 134 05C 01011100 \ (back slash)
    093 135 05D 01011101 &#93; (right/closing bracket)
    094 136 05E 01011110 ^ (caret/circumflex)
    095 137 05F 01011111 _ (underscore)
    096 140 060 01100000 `
    097 141 061 01100001 a
    098 142 062 01100010 b
    099 143 063 01100011 c
    100 144 064 01100100 d
    101 145 065 01100101 e
    102 146 066 01100110 f
    103 147 067 01100111 g
    104 150 068 01101000 h
    105 151 069 01101001 i
    106 152 06A 01101010 j
    107 153 06B 01101011 k
    108 154 06C 01101100 l
    109 155 06D 01101101 m
    110 156 06E 01101110 n
    111 157 06F 01101111 o
    112 160 070 01110000 p
    113 161 071 01110001 q
    114 162 072 01110010 r
    115 163 073 01110011 s
    116 164 074 01110100 t
    117 165 075 01110101 u
    118 166 076 01110110 v
    119 167 077 01110111 w
    120 170 078 01111000 x
    121 171 079 01111001 y
    122 172 07A 01111010 z
    123 173 07B 01111011 { (left/opening brace)
    124 174 07C 01111100 | (vertical bar)
    125 175 07D 01111101 } (right/closing brace)
    126 176 07E 01111110 ~ (tilde)
    127 177 07F 01111111 DEL (delete)

    ------------------------------------------------------
    http://www.neurophys.wisc.edu/comp/docs/ascii/

    [align=center]---Break---[/align]

    --Chroniccommand
  • Well, nice guide chronic ; )
  • x3n0n
    Posts: 110
    So when you use this to exploit, you just overwrite the memory of the esp with shellcode and then you overwrite the eip with the address of your shellcode. Am I right?
  • Xin
    Posts: 3,251
    Nice guide :) i need to know how to use gdb off by heart really
    Xin
  • x3n0n
    Posts: 110
    just a quick question. what do I need to do to turn off stack protection?
  • said:


    just a quick question. what do I need to do to turn off stack protection?



    http://smashthestack.org/viewtopic.php?id=388
    Have a look at that guide, it explains quite well.
  • undead
    Posts: 822
    Nice guide chroniccommand.