Article Index

View Memo

First step is always to play around with it:

 

1. Leave message on memo
2. Edit message last memo
3. View memo
4. Delete memo
5. Change password
6. Quit.
>> 1
Index: 0
Length: 32
Message: test

1. Leave message on memo
2. Edit message last memo
3. View memo
4. Delete memo
5. Change password
6. Quit.
>> 3
Index: 0
View Message: test

 

Ok, that seems good. As before, let's try a large number and a negative number.

 

>> 3
Index: 65536
Segmentation fault (core dumped)

 

Oops. How about negative?

 

>> 3
Index: -1
Segmentation fault (core dumped)

 

So that's interesting. Before when we entered a negative number it complained. This time it segfaults. This means it might not be validating negative numbers correctly. Let's peek at the code now.

 

 

 

By now, you all can probably see what's going on at the beginning. It's prompting for an integer and using that as an index into memo pointers array. There's a little trickery when you're reading this assembly. I missed it the first few times reading and wondering why the negative number was causing a segfault. The key is in the first block. Can you find it?

 

The key is actually what isn't in this function. After prompting for an integer, this time the code does not perform the cdqe. This one instruction changes the exploitability for this function. cdqe performs a conversion from double to quad word sign extended. Thus, the integer was read in to a double word size. When converting it to a quad word (64-bits or a "long long"), there's a question of if to assume the source integer is signed or not. Thus, skipping cdqe causes a negative integer to just be treated as a rather large positive 32-bit integer. This is why the negative number crashes the same way as the large positive number. It actually is a large positive integer in this case.

 

One implication of this is that we can really only use view indexes forward, not backwards (bummer). The second step locks us in to only being able to view integers 0-4. Finally, the last block does as you would expect and dereferences your memo pointer and prints it.

 

Now is as good a time as any to point out yet another strangeness of this binary. Take a peek at the global memory layout...

 

 

Can you see what's wrong? If you've been following along you should know that this binary is basically telling the user that they have 5 slots available to use to store memos. Pointers to those slots go into the aMemoPointers global. However, aMemoPointers doesn't appears to have enough space. It looks to be able to handle a single pointer, as if the source code was written something like "char *aMemoPointers[1];". The memory runs into the externs section so it doesn't really cause problems. But... strange.