GDB: Change string in memory on stack

4

I'm attempting to make my way through a Capture-the-Flag live VM, and getting stuck when trying to use gdb to alter a value passed on the stack (last item to be pushed):

system("date");

To

system("ash");

So far, my gdb efforts have been as follows:

stack

The address I'm interested in is the last item on the stack (first in the stack list below)

(gdb) p $esp
$1 = (void *) 0xbf902690

(gdb) x/32w 0xbf902690
0xbf902690: 0x080485ff  0x0000044c  0xb7783ff4  0xbf9026b8
0xbf9026a0: 0xb76a8fa9  0xb7797356  0x08048529  0x0000044c
0xbf9026b0: 0x08048520  0x08048410  0xbf902728  0xb7695cf7
0xbf9026c0: 0x00000001  0xbf902754  0xbf90275c  0xbf9026e4
....
(gdb) x/s 0x080485ff
0x80485ff:   "date"
(gdb) x/s *0x080485ff
0x65746164:  <Address 0x65746164 out of bounds>
(gdb)

Attempt to change memory 1

(gdb) set {const char [4] *}0x080485ff = "ash "
(gdb) x/s 0x080485ff
0x80485ff:   "\b`\354\b"
(gdb)

As you can see, I mangle the pointer.

Attempt to change memory 2

(gdb) set *((const char *)0x080485ff) = "ash "
(gdb) x/s 0x080485ff
0x80485ff:   "\bate"
(gdb)

More mangling - something to do with wrongly dereferencing?

Attempt to change memory 3

(gdb) set {int}0x080485ff = 68736100
(gdb) x/s 0x080485ff
0x80485ff:   "d\324\030\004"
(gdb)

Trying to use the ASCII values instead - doesn't work out as planned.

Any help appreciated - been scratching my (bald) head for a while now...

Thanks

sc.

gdb
exploit
internals
asked on Stack Overflow Feb 11, 2017 by swisscheese

1 Answer

5

set *((const char *)0x080485ff) = "ash "

This is wrong: the type of object at address 0x080485ff is char[5], not a char*. While the former can be cast to the latter, they are not at all the same.

set {const char [4] *}0x080485ff = "ash "

This is wrong for the same reason: there is no pointer at address 0x080485ff.

set {int}0x080485ff = 68736100

This one makes no sense, since 68736100 is 0x418d464 in hex, and garbage in ASCII. You probably meant 0x68736100.

That's actually very close:

  (gdb) x/s 0x080485ff
  0x80485ff:    ""
  (gdb) x/s 0x080485ff+1
  0x08048600:   "ash"

The problem is that 0x68736100 is "hsa\0" -- you've correctly swapped the characters, but you've put the terminating NUL at the front instead of the back. The right invocation then is:

 (gdb) set {int}0x080485ff = 0x687361
 (gdb) c
 Continuing.
 sh: ash: command not found

It worked!

answered on Stack Overflow Feb 11, 2017 by Employed Russian

User contributions licensed under CC BY-SA 3.0