2

I have a 32bit elf program that I have to exploit remotely (for academic purposes). The final goal is to spawn a shell. I have a stack that I can fill with any data I want and I can abuse one of the printf format strings. The only problem is that system/execv/execvp is not imported. The .got.plt segment is full of not-very-useful functions and I want to replace atoi with system because of how similar their signature is and the flow of the code indicates that that is the right function to replace. For the following attempts, I used IDA remote debug, so bad stack alignment and not proper format string is out of question. I wanted to make sure it is doable and apparently for me it isn't yet.

At first I tried to replace atoi@.got.plt with the unrandomized address of system. Got SIGSEGV.

Alright, it's probably because of ASLR, so let's try something else. I loaded up gdb and looked up system@0xb7deeda0 and atoi@0xb7de1250. Then I calculated the diff, which is 0xDB50. So the next time when I changed the address of atoi to system in the .got.plt segment, I actually just added diff to that value to get the address of system. Got SIGSEGV again.

My logic:

0xb7deeda0 <__libc_system>
0xb7de1250 <atoi>
diff = 0xb7deeda0 - 0xb7de1250
system@.got.plt = atoi@.got.plt + diff
example: 0x08048726 + DB50 = 0x08056276

Can anyone tell me what I did wrong and how can I jump to a "valid system()" with the help of leaking a function address from .got.plt?

Bálint Juhász
  • 304
  • 1
  • 16
  • In general, what you are doing should work. Since it doesn't, you must be doing something wrong. But it's impossible to tell *what* that might be, because you expressed your question in meaningless terms: what is "static address of system"? What does it mean to "change atoi to system in the .plt segment"? – Employed Russian Nov 01 '17 at 02:01
  • You suggest that problem is related to lazy bindings, isn't? So it should work with `export LD_BIND_NOW=1`, no? – Jérôme Pouiller Nov 01 '17 at 06:18

1 Answers1

2

Answering to my own question. Measuring the distance between functions in your l̲o̲c̲a̲l̲ libc does not guarantee that the r̲e̲m̲o̲t̲e̲ libc will have the same alignment. You have to find the libc version somehow, then you can get the address difference like so:

readelf -s /lib32/libc-2.19.so | grep printf

Possible ways to find the libc version if you know two addresses:

Bálint Juhász
  • 304
  • 1
  • 16