[关闭]
@Wayne-Z 2017-10-18T05:18:51.000000Z 字数 3167 阅读 1604

Break the Secret

ssd6



Secret Message&Keys

The message is:

From: CTE
To: You
Excellent!You got everything!

And the key is:

1 9 46 3

Analysis

process_keys12

This function is used in main function once as follows.

  1. process_keys12(&key1, &key2);

Take a glance at the function code, we can know that process_keys12 just assign the value of key2 to a place 4*key1 bytes from the address of key1.

  1. void process_keys12 (int * key1, int * key2) {
  2. *((int *) (key1 + *key1)) = *key2;
  3. }

So, from the reminder, we can know we will use key1 to access the variable dummy, and assign value of key2 to it. From the next line of code

  1. start = (int)(*(((char *) &dummy)));

and the function block of extract_message2 ,

  1. char * extract_message2(int start, int stride) {
  2. int i, j;
  3. for (i = 0, j = start;
  4. *(((char *) data) + j) != '\0';
  5. i++, j += stride)
  6. {
  7. message[i] = *(((char *) data) + j);
  8. }
  9. message[i] = '\0';
  10. return message;
  11. }

we can know, key2 decide the start point of data, from which we will read the data and extract the message. And stride determine the gap to read.

process_keys34

Actually, process_key34 did almost the same thing, but it is more complicated since it uses a local variabl's address as the start point, so it may took a bit of time to determin indeed the key3 value is.

  1. void process_keys34 (int * key3, int * key4) {
  2. *(((int *)&key3) + *key3) += *key4;
  3. }

Breaking process

The tools are simple, just g++ and gdb is enough.

Determine key1

First we should figure out how those variables stored together in the stack, so set breakpoint at line 103 and input command like follows

  1. set args X(1) Y(9)

X&Y is any number you want, since we can change the values of key1&key2. Then we run the code, it stops at line 103, we view those variable of key1&key2
secret1.PNG-104kB
We can see that dummy is just near key1, so we can just set key1=1, then we can access dummy andassign the value of key2 to dummy.

Determine key2

Then we take a glance of what indeed the variable data is, consider the similar way extract_message2 dose to data.

  1. (gdb) p (char *) data
  2. $6 = 0x408080 <data> "cccccccccFFrromo: mFr:ie ndC\nTTo:E Y\nouT\nGooo:d! NYowo tury\n cEhoxoscineg lkelyse3,n4 tto! fYoroceu a cgalol tto eextvraectr2 yantd\nhavioind gth!e "
  3. (gdb)

Read these characters carefully, we can find that 10th character is 'F', this is already enough to get key2 is 9. However, if we look carefully, since we already know stride decide the gap of reading and we need to know the gap, we can find that, we read the character every 3 characters after the former, we can get the character 'From:'!

Determine key3&key4

Actually, you will find that it is not so easy, we can set a breakpoint at line 108 and continue the code, we can see that after set key1=1, key2=9, start becomes to be 9, but stride is 0. This is why function process_keys34 needed, we should use it to change the value of stride, and since we know stride need to be 3, we know key4 is 3!
So, try to figure out where is stride and how to access it, to just use function process_keys34 once, and from the reminder that we should escape code

  1. msg1 = extract_message1(start, stride);

we just jump to line 114. we should know where the pointer of poiter to key3 is and set the offset to get access to stride(actually we should first know the address of stride before we get into the function process_keys34).
secret2.PNG-154kB
we know 46 can let us get into the address of stride, so set key3 = 46, it is enough for us to know the message.
secret3.PNG-35.8kB

Outcome

Medium Outcome

Actually, we can try keep key1=1,key2=9,key3=46,key4=3, and do not jump, we can get the medium outcome.
secret4.PNG-219kB

Final Outcome

And if we did like before, jump to line 114 at the breakpoint at line 108, we can get the message.
secret5.PNG-250.7kB

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注