1CAT CTF Write-ups (Մաս #3) — — SanityCheck, ReverseFlash, ShortCircuit, Lunchtimedoubly, ezDecode, DriverEnRoute

CyhubArmenia
8 min readFeb 2, 2022

Այս հրապարակմամբ կրկին անդրադառնում ենք 1CAT CTF-ի ընթացքում առաջարկված խնդիրներին և ձեզ ենք ներկայացնում SanityCheck, ReverseFlash, ShortCircuit, Lunchtimedoubly, ezDecode, DriverEnRoute խնդիրների լուծումները։

SanityCheck
# Team name: Krisp

When we look at the challenge we see a quote from Mr.Robot
*I remember when I was a kid, I got into web design by ripping off sites I liked. All you had to do was view the source on your browser and there it was, the code. You could copy-paste it, modify it a little, put your name on it, and like that, it was your site. View source. What if we had that for people? Would people really want to see?*

So we can guess that we should look at page sources. When we look at the page source of the CTF infranstruction we can not find anything there, but we can try the same thing in the main CTF webpage.
1. Go to ctf.cyhub.am
2. Open the console and look through the window variables
3. You’ll find variable my_mother_had_me_tested (“Y3lodWJjdGZ7MV9rbjB3X2gwd183MF9yMzRkX2g3bWx9Cg==”)
4. Decode it and get the flag cyhubctf{1_kn0w_h0w_70_r34d_h7ml}

SanityCheck
# Team name: Uxtankyun

The problem statement hints that the flag is hidden somewhere in the website sources. After manually looking through all the website resources, I found the following variable declaration in `https://ctf.cyhub.am/wp-content/themes/twentytwenty/assets/js/index.js`
```
var my_mother_had_me_tested = “Y3lodWJjdGZ7MV9rbjB3X2gwd183MF9yMzRkX2g3bWx9Cg==”
```
This looks like a base64-encoded string. After decoding, we get the flag `cyhubctf{1_kn0w_h0w_70_r34d_h7ml}`

ReverseFlash, ShortCircuit, Lunchtimedoubly
# Team name: Uxtankyun

ssh with the provided credentials. We have two text files named `rotterdam.txt` and `paris.txt`, and one executable file `time_is_an_illusion`. When we execute the program, it asks for a password. The first thing that comes to mind is looking for the password in the executable. We run `strings ./time_is_an_illusion` and look for things that could be a password or a flag. One of the produced strings is `EA&)bmS]62`. We then run `./time_is_an_illusion “EA&)bmS]62”` and get the first flag:
```
Ez right? Here’s the first flag. cyhubctf{EA&)bmS]62}
You’re on the right track, next up some encryption!
Please input the password for Stage2:
```

# ShortCircuit
After trying some random short passwords for Stage2, we can notice that it always prints the same thing:
```ERROR CODE: 014d40490e521617064240025b460b```
We then used `Hopper` to disassemble the program. After careful examination, we found that the error code is calculated by `xor`-ing the contents of `rotterdam.txt` and some secret. We identified the secret by trial-and-error from `strings ./time_is_an_illusion`, and just `xor`-ed the error code with it, obtaining the flag `cyhubctf{k95;f4opn69e32r}`

# Lunchtimedoubly
This one was arguably easier. From the disassembly, we just notice that the minutes result of a `localtime` function call is compared with `0x2a`. We then conclude that we have to wait until `HH:42` to execute the program and obtain the flag: `cyhubctf{t1me_is_m0n3y$$}`

ReverseFlash, ShortCircuit, Lunchtimedoubly
# Team name: Krisp

When we connect to the server we can see these files there.

-r — — — — 1 hrachuhi hrachuhi 17 Nov 26 19:25 paris.txt
-r — — — — 1 hrachuhi hrachuhi 16 Nov 26 19:25 rotterdam.txt
-rwsr-xr-x 1 hrachuhi hrachuhi 7528 Nov 27 15:18 time_is_an_illusion

As we can guess from the title it should be a reverse engineering challenge, so we will download the file and look through the source code.
But before that let’s run and see what it is doing.

valod@rt0:~ % ./time_is_an_illusion
Need exactly one argument. Please input the password.

We can see that it accepts an argument from input, let’s jump to our disassembler and see what we can get.

From the entrypoint we can see that after setting up the environment it is calling this function

0000000000201b7b call sub_201da0 ; sub_201da0

Let’s jump to that function

0000000000201de0 mov rax, qword [rbp+var_10] ; CODE XREF=sub_201da0+29
0000000000201de4 mov rax, qword [rax+8]
0000000000201de8 mov qword [rbp+var_18], rax
0000000000201dec mov rdi, qword [rbp+var_18] ; argument “__s1” for method j_strncmp
0000000000201df0 movabs rsi, aEabms62 ; argument “__s2” for method j_strncmp, “EA&)bmS]62”
0000000000201dfa mov edx, 0x9 ; argument “__n” for method j_strncmp
0000000000201dff call j_strncmp ; strncmp
0000000000201e04 cmp eax, 0x0
0000000000201e07 jne loc_201e2d
0000000000201e0d movabs rdi, aEzRightHeresTh ; argument “__format” for method j_printf, “Ez right? Here’s the first flag. cyhubctf{%s} \\nYou’re on the right track, next up some encryption!\\n”

Okay here we can see that it’s taking the argument that is being provided by us and comparing with string `”EA&)bmS]62"`, so basically our flag is `cyhubctf{EA&)bmS]62}`

After getting the first flag we can see that it asks for a password input.
```
Ez right? Here’s the first flag. cyhubctf{EA&)bmS]62}
You’re on the right track, next up some encryption!
Please input the password for Stage2:
```
Let’s read the rest of the assembly code to see what’s happening there.

0000000000201e3c movabs rdi, aRotterdamtxt ; argument “__filename” for method j_fopen, “rotterdam.txt”, CODE XREF=sub_201da0+136
0000000000201e46 movabs rsi, aR ; argument “__modes” for method j_fopen, “r”
0000000000201e50 call j_fopen ; fopen
0000000000201e55 lea rdi, qword [rbp+var_30] ; argument “__s” for method j_fgets
0000000000201e59 mov qword [rbp+var_38], rax
0000000000201e5d mov rdx, qword [rbp+var_38] ; argument “__stream” for method j_fgets
0000000000201e61 mov esi, 0x10 ; argument “__n” for method j_fgets
0000000000201e66 call j_fgets ; fgets
0000000000201e6b mov rdi, qword [rbp+var_38] ; argument “__stream” for method j_fclose
0000000000201e6f mov qword [rbp+var_F0], rax
0000000000201e76 call j_fclose ; fclose
0000000000201e7b mov rcx, qword [aJturhfyghtyght] ; “jturhfyghtyghty”
0000000000201e83 mov qword [rbp+var_50], rcx
0000000000201e87 mov rcx, qword [aJturhfyghtyght+8] ; 0x2009e8
0000000000201e8f mov qword [rbp+var_48], rcx
0000000000201e93 mov dword [rbp+var_3C], 0x0
loc_201e9a:
0000000000201e9a lea rdi, qword [rbp+var_30] ; argument “__s” for method j_strlen, CODE XREF=sub_201e32+183
0000000000201e9e movsxd rax, dword [rbp+var_3C]
0000000000201ea2 mov qword [rbp+var_F8], rax
0000000000201ea9 call j_strlen ; strlen
0000000000201eae mov rcx, qword [rbp+var_F8]
0000000000201eb5 cmp rcx, rax
0000000000201eb8 jae loc_201eee
0000000000201ebe movsxd rax, dword [rbp+var_3C]
0000000000201ec2 movsx ecx, byte [rbp+rax+var_30]
0000000000201ec7 movsxd rax, dword [rbp+var_3C]
0000000000201ecb movsx edx, byte [rbp+rax+var_50]
0000000000201ed0 xor ecx, edx
0000000000201ed2 mov byte [rbp+var_61], cl
0000000000201ed5 mov cl, byte [rbp+var_61]
0000000000201ed8 movsxd rax, dword [rbp+var_3C]
0000000000201edc mov byte [rbp+rax+var_60], cl
0000000000201ee0 mov eax, dword [rbp+var_3C]
0000000000201ee3 add eax, 0x1
0000000000201ee6 mov dword [rbp+var_3C], eax
0000000000201ee9 jmp loc_201e9a
loc_201eee:
0000000000201eee movsxd rax, dword [rbp+var_3C] ; CODE XREF=sub_201e32+134
0000000000201ef2 mov byte [rbp+rax+var_60], 0x0
0000000000201ef7 movabs rdi, aPleaseInputThe ; argument “__format” for method j_printf, “Please input the password for Stage2: “
0000000000201f01 mov al, 0x0
0000000000201f03 call j_printf ; printf
0000000000201f08 lea rsi, qword [rbp+var_80]
0000000000201f0c movabs rdi, aS ; argument “__format” for method j_scanf, “%s”
0000000000201f16 mov dword [rbp+var_FC], eax
0000000000201f1c mov al, 0x0
0000000000201f1e call j_scanf ; scanf
0000000000201f23 mov dword [rbp+var_3C], 0x0
loc_201f2a:
0000000000201f2a lea rdi, qword [rbp+var_80] ; argument “__s” for method j_strlen, CODE XREF=sub_201e32+336
0000000000201f2e movsxd rax, dword [rbp+var_3C]
0000000000201f32 mov qword [rbp+var_108], rax
0000000000201f39 call j_strlen ; strlen
0000000000201f3e mov rcx, qword [rbp+var_108]
0000000000201f45 cmp rcx, rax
0000000000201f48 jae loc_201f87
0000000000201f4e movsxd rax, dword [rbp+var_3C]
0000000000201f52 movsx ecx, byte [rbp+rax+var_80]
0000000000201f57 movsxd rax, dword [rbp+var_3C]
0000000000201f5b movsx edx, byte [rbp+rax+var_50]
0000000000201f60 xor ecx, edx
0000000000201f62 mov byte [rbp+var_A1], cl
0000000000201f68 mov cl, byte [rbp+var_A1]
0000000000201f6e movsxd rax, dword [rbp+var_3C]
0000000000201f72 mov byte [rbp+rax+var_A0], cl
0000000000201f79 mov eax, dword [rbp+var_3C]
0000000000201f7c add eax, 0x1
0000000000201f7f mov dword [rbp+var_3C], eax
0000000000201f82 jmp loc_201f2a
loc_201f87:
0000000000201f87 lea rsi, qword [rbp+var_A0] ; argument “__s2” for method j_strcmp, CODE XREF=sub_201e32+278
0000000000201f8e lea rdi, qword [rbp+var_60] ; argument “__s1” for method j_strcmp
0000000000201f92 movsxd rax, dword [rbp+var_3C]
0000000000201f96 mov byte [rbp+rax+var_A0], 0x0
0000000000201f9e call j_strcmp ; strcmp
0000000000201fa3 cmp eax, 0x0
0000000000201fa6 jne loc_201fc6
0000000000201fac lea rsi, qword [rbp+var_80]
0000000000201fb0 movabs rdi, aNsometimesCryp ;
argument “__format” for method j_printf, “\\nSometimes Crypto is EZ. Use this as a flag. cyhubctf{%s}\\n”

Actually this was a lot of assembly code, but thanks to Hopper decompiler that converted this code to an stripped C code we could recognize that it is doing XOR with the string `jturhfyghtyghty` and the content of `rotterdam.txt` and printing it out.
So when we run the code with any argument we can see the XOR result

Please input the password for Stage2: asd
ERROR CODE: 014d40490e521617064240025b460b
nope.

Basically now we can just take our secret key XOR convert it to HEX, XOR it with the output HEX then convert the result back to ASCII which will be our flag.
`HEX(jturhfyghtyghty)=6a7475726866796768747967687479`
`XOR(014d40490e521617064240025b460b, 6a7475726866796768747967687479)=6b39353b66346f706e363965333272`
`ASCII(6b39353b66346f706e363965333272)=k95;f4opn69e32r`
Now we can submit this flag as well wrapping it in `cyhubctf{}` format.

After this we can read in the code that it is creating a time instance and localtime struct pointer. Then taking the property at offset `0x4` from our struct and comparing it with hex `0x2a` which is `42` in decimal.
Here’s the C code for that part

rdi = &var_B8;
time(rdi);
if (*(int32_t *)__error(rdi, rsi, rdx) == 0x0) goto loc_20208f;
loc_202063:
printf(“ERROR: Could not get time: %s”, strerror(*(int32_t *)__error(rdi, rsi, rdx)));
goto loc_20218b;
loc_20208f:
rdi = &var_B8;
var_C0 = localtime(rdi);
if (*(int32_t *)__error(rdi, rsi, rdx) == 0x0) goto loc_2020dc;
loc_2020b0:
printf(“ERROR: Could not get time: %s”, strerror(*(int32_t *)__error(rdi, rsi, rdx)));
goto loc_20218b;
loc_2020dc:
if (*(int32_t *)(var_C0 + 0x4) == 0x2a) {
var_E8 = fopen(“paris.txt”, “r”);
fgets(&var_E0, 0x10, var_E8);
fclose(var_E8);
printf(“Congradulations, here’s the last flag → cyhubctf{%s}\n”, &var_E0);
rax = exit(0x0);
}
else {
printf(“Nope you aint getting the last one… … …”);
rax = sub_201d70();
}
return rax;

When we look at C’s localtime struct we can see that in that offset the property is minutes, so the program is basically checking if the minutes are equal to 42 and prints the flag.
For this I’ve just setted up an alarm for the next hour at 42 minute run the program with our 2 keys that we did find previously and get the third flag :)

ezDecode
# Team name: Uxtankyun

The problem statements says the following; “I like to encode my messages for the robots!”. We checked ‘.robots.txt’ of the website and found an entry for ‘secretMessage.txt’. The file contains a string of 1s and 0s. After binary decoding the string you get another string that ends with ‘=’ which suggests it might be a base64 encoded data. After base64 decoding we got a string that was suspiciously similar to a hex code. Decoding that to ascii gives us a string of random characters which contain } at the beginning and { somewhere at the end. Reversing the string brings brackets to the correct order, and we noticed that the word ‘pluhopgs’ which is just before the opening bracket has the same number of letters as ‘cyhubctf’. Trying Caesar cipher with key 13 gave us the final result.

DriverEnRoute
# Team name: Uxtankyun

We quickly figure out that task was asking to find distance traveled of a car with given license plates. Given the plate number 55GC155 we started searching for online listings of a car with those license numbers. Several listings, different distance traveled. One on auto.am stated that the distance traveled of the car was 63000 km. Another one on facebook said that the car had traveled 81000 km. None of 63000, 63000000, 81000, or 81000000 worked. After thinking about it a bit, we thought that the car was imported and we needed to find out pre-import numbers. In one of the photos on auto.am there was a VIN code of the car. Looking up the VIN code we found a listing with miles traveled equal to 48110 miles. That turned out to be the correct answer.

--

--

CyhubArmenia

CyHub Armenia is the main cybersecurity hub in Armenia. We are setting the stage for the next technological breakthroughs in Armenia’s cybersecurity.