Send input pipe to GDB at a breakpoint rather than initially

I researched this question and the closest answer I could find is this. gdb - debug with input stream (no arguments)

I need to do exactly what this person asked, however I need to be able to send input AFTER I have already viewed a part of my program.

This is the code I am looking at in GDB

#define SECRET1 0x44
#define SECRET2 0x55

int main(int argc, char *argv[])
{
char user_input[100];

int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/

/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));

/* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2;

printf("The variable secret’s address is 0x%8x (on stack)\n", &secret);
printf("The variable secret’s value is 0x%8x (on heap)\n", secret);
printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]);
printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]);

printf("Please enter a decimal integer\n");
scanf("%d", &int_input);  /* getting an input from user */

printf("Please enter a string\n");
scanf("%s", user_input); /* getting a string from user */

/* Vulnerable place */
printf(user_input);
printf("\n");

/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%x\n", SECRET1, SECRET2);
printf("The new secrets:      0x%x -- 0x%x\n", secret[0], secret[1]);

return 0;
}

      

I am trying to perform a format string attack on my virtual machine. To do this, I need to know which address is kept secret. The program tells me this through the output with these lines

  printf("The variable secret’s address is 0x%8x (on stack)\n", &secret);
  printf("The variable secret’s value is 0x%8x (on heap)\n", secret);
  printf("secret[0]’s address is 0x%8x (on heap)\n", &secret[0]);
  printf("secret[1]’s address is 0x%8x (on heap)\n", &secret[1]);

      

The nature of the attack requires me to send non-ASCII hex values ​​as input for the second scanf, so I can't just type the input myself. I have done my input setup using perl here,

ramtest@ramtest-VirtualBox:/tmp$ perl -e 'print "5\x0a"; print "\x08\xb0\x04\x08%x.%x.%x.%x.%x.%x.%x";' > /tmp/input

      

Then I ran

$gdb ./vul_prog < /tmp/input

      

I got my method to work in an environment where memory randomization is disabled, since I can run the program once, look at the memory addresses, then change the perl script and just run it again. However, with memory randomization, I cannot know where the addresses will be before running it, so I will need to see the part of the program that tells me the addresses are being run before I create and submit my input.

I tried to do it in the way that seemed the most intuitive, but I just get a syntax error.

Starting program: /home/ramtest/Downloads/vulprog 
The variable secret’s address is 0xbfffefd8 (on stack)
The variable secret’s value is 0x 804b008 (on heap)
secret[0]’s address is 0x 804b008 (on heap)
secret[1]’s address is 0x 804b00c (on heap)
Please enter a decimal integer
1
Please enter a string

Breakpoint 2, 0x0804858f in main ()
(gdb) c > /tmp/input
A syntax error in expression, near `> /tmp/input'.
(gdb) c < /tmp/input
A syntax error in expression, near `< /tmp/input'.

      

Is it possible to set a breakpoint in GDB before I am prompted for input and then send the / tmp / input information as input?

If so, how can I do this?

Any help would be appreciated.

+3


source to share


1 answer


Just use the command run

. I'll demonstrate by feeding /bin/cat

to gdb and breaking it main()

, with the standard input being redirected:

Example:

$ gdb /bin/cat
GNU gdb (GDB) Fedora 7.12.1-47.fc25
[ ... ]
(gdb) b main
Breakpoint 1 at 0x1bc0
(gdb) run </etc/issue
Starting program: /usr/bin/cat </etc/issue

Breakpoint 1, 0x0000555555555bc0 in main ()
(gdb) c
Continuing.
\S
Kernel \r on an \m (\l)

[Inferior 1 (process 18190) exited normally]
(gdb) 

      

You can run your program under gdb

, set a breakpoint just before scanf, then run

with standard input redirected from an empty file. I don't expect your program to try to read from its stdin until then, so it won't see an end-of-file condition on its redirected stdin.



When you hit a breakpoint, you should have your memory addresses, then prepare your payload and just add it to a zero length file, then

c

      

execution, which should then continue and try to read the payload, which is now available on its standard input.

A variation on this technique, which doesn't even require a debugger, would be to use a named pipe, which will be open for writing, beforehand, and then run that program with standard input redirected from the named pipe. The expected result would be a program that prints memory addresses and then locks while reading from the pipe. At this point, you can prepare your payload and write it to the pipe.

+2


source







All Articles