-3

I am trying to demonstrate format strings vulnerability in C. I want to avoid strings command from revealing the ASCII string sin my binary.

Heres my simple code:

#include <stdio.h>    
static char secret[] = "mysecretstring";
  int main(int argc, char *argv[]) {
    char buf[64];
    strncpy(buf, argv[1], sizeof(buf));
    printf(buf);
  }
pizzaiolo
  • 13
  • 3
  • 1
    What exactly is the question? Also this doesn't look like c++ code so why the c++ tag? – pmaxim98 Aug 27 '17 at 08:32
  • If I compile this code and run strings against the compiled binary, it will reveal mysecretstring. I'm looking a technique to hide the variable. – pizzaiolo Aug 27 '17 at 08:35
  • @pmaxim98 It's perfectly legal C++ code, if you add the includes. Just like it is perfectly legal C code if you add those same includes. – Deduplicator Aug 27 '17 at 08:36
  • As far as a compiled binary is concerned, there are no longer such things like "variables". There are only registers and memory locations. Maybe the binary contains debug information that allows a debugger to translate between registers/memory locations and "variables", but that can be stripped away; and doesn't get included in the first place if not compiled with the "add debug information flag". – datenwolf Aug 27 '17 at 08:59
  • @PSkocik It is quite easy to understand - he wants to vale his string literals to make them "invisible" when someone is browsing the executable file or flash memory in the uC. IMO it is 100% clear. – 0___________ Aug 27 '17 at 09:57
  • If this is just about hiding string literals from the `strings` command, then the "demonstrate format strings vulnerability" part seems completely unrelated. – jamesdlin Sep 13 '17 at 06:24

1 Answers1

0

You can do some math with it for example:

static unsigned char secret[] = {'m' + 10, 'y' + 10, 's' + 10, 'e' + 10, 'c' + 10, 'r' + 10, 'e' + 10, 't' + 10, 's' + 10, 't' + 10, 'r' + 10, 'i' + 10, 'n' + 10, 'g' + 10};

as your secret string may be in the RO segment:

char *decode(const unsigned char *str, int c)
{
    int len = 0;
    char *ml, *cl;
    while(*str != abs(c))
        len++;
    ml = malloc(len + 1);
    if(ml != NULL)
    {
        cl = ml;
        while(*str != abs(c))
            *cl++ = *str++ + c;
        *cl = 0;
    }
    return ml;
}

of course it is easier to write the script which will code your string literals for you. The coding mechanism may be much more complicated - in the example I just is something trivial

Example coding function in C

#define VNAMEMAX 20
#define VVALUEMAX 200

typedef struct
{
    char vname[VNAMEMAX];
    char vvalue[VVALUEMAX];
}VDEF_T;


VDEF_T varialbles[] =
{
    {.vname = "mystring",.vvalue = "Something very secret"},
    {.vname = "secret_var",.vvalue = "Something even more secret" },
    {0,},
};

int code(VDEF_T *v, char *fname, int c)
{
    FILE *fp = fopen(fname, "wt");
    int result = (fp == NULL) * -1;

    if (!result)
    {
        fprintf(fp, "#ifndef _MYSECRET\n#define _MYSECRET\n\n\n");
        while (!result && v->vname[0])
        {
            fprintf(fp, "static unsigned char %s[] = {\n\t\t", v->vname);
            for (int i = 0; i <= strlen(v->vvalue); i++)
            {
                if (fprintf(fp, "0x%02x,", v->vvalue[i] + c) < 0)
                {
                    result = -1;
                    break;
                }
            }
            if (fprintf(fp, "};\n\n") < 0) result = -1;
            v++;
        }
        if(fprintf(fp, "#endif") < 0) result = -1;
        fclose(fp);
    }
    return result;
}

And the result .h file;

#ifndef _MYSECRET
#define _MYSECRET


static unsigned char mystring[] = {
        0x5d,0x79,0x77,0x6f,0x7e,0x72,0x73,0x78,0x71,0x2a,0x80,0x6f,0x7c,0x83,0x2a,0x7d,0x6f,0x6d,0x7c,0x6f,0x7e,0x0a,};

static unsigned char secret_var[] = {
        0x5d,0x79,0x77,0x6f,0x7e,0x72,0x73,0x78,0x71,0x2a,0x6f,0x80,0x6f,0x78,0x2a,0x77,0x79,0x7c,0x6f,0x2a,0x7d,0x6f,0x6d,0x7c,0x6f,0x7e,0x0a,};

#endif
0___________
  • 60,014
  • 4
  • 34
  • 74