[CTF][RiceTeaCatPanda] Whats the password?
Tags: cybersecurity, security, linux
Published: 2020-11-22 05:02:37

# Repo
[Repo](https://github.com/wireless90/Writeups/tree/main/Reversing/CTF/RiceTeaCatPanda)
# Run the program and see how it behaves
![Download Files](https://dev-to-uploads.s3.amazonaws.com/i/lyhv0b9d6vketkuodhfd.PNG)

# Open the program in IDA

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3fobyfq4v29bargl4uja.PNG)

We will notice that there is some kind of loop. I have highlighted the section in Pink, which I want to avoid.



![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fr8xmurgi961wlegltcy.PNG)

There is also some kind of a counter check to see if it reached 0x14, which is 20 in base 10. Hence, the loop will loop for a max of 20 characters.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9ldvftmv67w5uhu2jshc.PNG)

Looking at the circled algorithm, we can see that the counter is always retrieved from `edx`.
1. Updated counter is always retrieved from `edx`
2. Index = (counter + counter*4) * 16
3. Get byte from binary pointed to by RSI[Index]
4. Get byte from user input pointed to by Input[counter]
5. Transfer the user input byte such that `input_byte = ((input_byte XOR 0x32)+1) XOR 0x32`
6. Ensure the new input byte amd the byte from the memory are equal, and proceed to check the remaining bytes.

What we know so far are that there are a total of 20 iterations. We know our user input is being check to a value from memory at a location determined by Step 2 above. 
By calculating the Index for possible values if Counter in range 0 to 19 inclusive, we can compute our Index values to be 0, 80, 160, 240 and so on. So basically we are accessing the memory in increment of 80 bytes.

# Look at the memory where the values are stored.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/kbpgb8669lwjd8cztxkm.PNG)

We can see that the values are from a .data section in memory. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ypmwrcvfn9h71oq6ixwk.PNG)
By looking at the memory, the starting byte is 0x3A. The next byte would be 80 positions from that.

# I used gdb to go to the location and retrieve all the 20 values.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1p1tchv06kv5o8gksq5m.PNG)
I decided to set the breakpoint at that location.
After loading gdb, I ran the file once, then I proceeded to do the command `info files`, to get the location of the current `.text` section.

I set a breakpoint.
`b * 0x000055555555483b` 
Then I ran the application again,  `run`.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/nd6edpoq6o3rtagcb8e6.PNG)
Once hitting the breakpoint, I proceeded to print out the 20 characters from memory.

The bytes collated was `[0x3a, 0x31, 0x52, 0x30, 0x34, 0x36, 0x52, 0x30, 0x33, 0x5c, 0x3a, 0x51, 0x73, 0x30, 0x35, 0x45, 0x5c, 0x31, 0x5a, 0x34]`.

Then I proceeded to use python to reverse the algorithm as such.
```python
a =[0x3a, 0x31, 0x52, 0x30, 0x34, 0x36, 0x52, 0x30, 0x33, 0x5c, 0x3a, 0x51, 0x73, 0x30, 0x35, 0x45, 0x5c, 0x31, 0x5a, 0x34]
def f(input):
...     for i in input:
...             dec = ((i^0x32)-1)^0x32
...             print(chr(dec))
...
f(a)
5
0
m
3
7
1
m
3
2
_
5
P
r
3
4
D
_
0
U
7
```

# There we have the flag!
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/mgv2r9p2d8xp1ayjgsad.PNG)