2

Code is here:

#include <stdio.h>

#define NUM 0x11a

int data = NUM;

int main(int argc, char * argv[])
{
    struct{
        unsigned long memoryAddress;
       char array[50];
    } locals;

    locals.memoryAddress= 2;

    scanf("%lx", &locals.memoryAddress);

    scanf("%49s", locals.array);
    printf(locals.array);

    data += 5;
    printf("\n%d\n", data);

    if(data != NUM + 0x5){
        printf("Print me!\n");
    }

    return 0;
}

I should get "Print me!". It's format string attack and I use %n and gdb.

So how can I get memory address of data to overwrite it?

Gardas462
  • 21
  • 2
  • 1
    Maybe it is too much for me, but I don't understand why after assigning `NUM` to `data` and adding 5 to `data` you expect `data` to be different from `NUM+5`. – Roberto Caboni Apr 29 '20 at 12:01
  • Related: https://stackoverflow.com/questions/31290850/why-is-printf-with-a-single-argument-without-conversion-specifiers-deprecated – RobertS supports Monica Cellio Apr 29 '20 at 12:03
  • You can't get the address of `data`. Either you already know it or you don't. If your program was compiled with `-fno-pie -no-pie`, then you can check with `objdump` or `gdb` (if you compile with symbols) before running the program. – Marco Bonelli Apr 29 '20 at 12:04
  • @RobertSsupportsMonicaCellio OP already knows this and that's exactly what they are trying to do, it's not an error. – Marco Bonelli Apr 29 '20 at 12:05
  • @MarcoBonelli But why is the insertion of a "%n" string supposed to change the contents of an unrelated variable? – Roberto Caboni Apr 29 '20 at 12:07
  • 2
    @RobertoCaboni `%n` allows to write the number of characters written so far to a variable. If there is no variable, or if you use the accurate displacement (e.g. `%5$n`) you can select an arbitrary address to write to from the stack (in this case OP wants to write to `data`). Since you have control over the format string you can "pack" the arbitrary address into the format string itself and then find the appropriate displacement to make `%n` use that address and write what you want where you want (combining it with `%NNNc` to write `NNN` characters before the `%n` is hit). – Marco Bonelli Apr 29 '20 at 12:15
  • 1
    @RobertoCaboni [here's a more detailed explanation](https://medium.com/swlh/binary-exploitation-format-string-vulnerabilities-70edd501c5be) (first one that comes up googling). – Marco Bonelli Apr 29 '20 at 12:17
  • Should we assume that there is some special purpose for the line `locals.memoryAddress= 2;`. I ask because it is immediately followed by `scanf("%lx", &locals.memoryAddress);` which will overwrite the previous value `2` stored in `locals.memoryAddress`. – ryyker Apr 29 '20 at 12:37
  • @MarcoBonelli Nonetheless it is plain UB: C18, 7.21.6.1/8 "*n - The argument shall be a pointer to signed integer into which is written the number of characters written to the output stream so far by this call to `fprintf`. No argument is converted, but one is consumed.*" – RobertS supports Monica Cellio Apr 29 '20 at 12:46
  • 1
    @RobertSsupportsMonicaCellio UB is just a concept defined by the standard. Once you pinpoint an exact compiler and version, and more than that, once you have a program that is compiled, the behavior of the program is 100% well defined. – Marco Bonelli Apr 29 '20 at 12:47
  • @MarcoBonelli Really clever! It makes clear that I am a naive soul. – Roberto Caboni Apr 29 '20 at 12:48
  • @MarcoBonelli - _ just a concept defined by the standard_ , or rather _ just a concept_ `that is not` _defined by the standard_. :) – ryyker Apr 29 '20 at 12:49
  • @ryyker I see what you did there LOL. – Marco Bonelli Apr 29 '20 at 12:50
  • Please add more information to the question. What commands did you use exactly to compile the code? This is **very important** to answer your question. What platform/OS are you on? And finally, what did you try that did not work? Show an example. – Marco Bonelli Apr 29 '20 at 12:54
  • @MarcoBonelli But that actually requires that a specific implementation defines the behavior happening of that case. Is that provided for example in gcc/Linux according to the use of `%n` without argument in the call to `printf()`? – RobertS supports Monica Cellio Apr 29 '20 at 12:56
  • @RobertSsupportsMonicaCellio In Linux x86 32bit, glibc's `printf()` makes the assumption that the parameters are passed on the stack, therefore using `%n` takes an address from the stack. It's a safe assumption to make and the behavior is 100% deterministic since you can look at the compiled library code. The function is called correctly and as far as the compiler is concerned there is no undefined behavior. Undefined behavior *could happen* at runtime, but as I said, it's hardly undefined. – Marco Bonelli Apr 29 '20 at 12:59
  • I should be tired but where is the `%n` into the code posted ? – Ôrel Apr 29 '20 at 13:10
  • @Ôrel it's supposed to be entered by the user in `scanf("%49s", locals.array);` – Marco Bonelli Apr 29 '20 at 16:37

0 Answers0