2021 RaRCTF - Writeup
題目:verybabyrev
, Dotty
, RaRPG
, Infinite Free Trial
, Very TriVial ReVersing
, Jammy's Old Infra
, boring flag checker
, Down The Rabbit Hole
Score:NCtfU - 3rd
verybabyrev
Challenge Info
fun fact: verybabyrev backwards is verybabyrev
file:
verybabyrev - ad2b44
Solution
|
|
Flag
rarctf{3v3ry_s1ngl3_b4by-r3v_ch4ll3ng3_u535_x0r-f0r_s0m3_r34s0n_4nd_1-d0nt_kn0w_why_dc37158365}
Dotty
Challenge Info
My new program will keep your secrets safe using military grade encryption!
file:
Dotty.exe - 81a733
Solution
It’s a .Net assembly, so simply decode with DNSpy.
A morse code string can be found in Check()
.
|
|
Decode the string with |
as letter and /
as word delimeter, and get
THE FLAG IS OJQXEY3UMZ5WIMLEL54TA5K7OAZTG227GBZF6NLQPE7T6PZ7L5TGCNDBMM3DANL5 BASE32
Decode from Base32 and get the flag.
Flag
rarctf{d1d_y0u_p33k_0r_5py????_fa4ac605}
RaRPG
Challenge Info
Challenge instance ready at
193.57.159.27:60415
I’ve been building a brand new Massively(?) Multiplayer(?) Online Role-Playing(?) Game(?) - try it out! Just don’t try and visit the secret dev room…If you do not have the linked libraries, download rarpg-libs.zip and extract the libraries into your working directory. Then use
LD_LIBRARY_PATH=$(pwd) ./client <ip> <port>
file:
client - edcfd5
,rarpg-libs.zip - e89a64
,rarpg-libs.zip - e89a64
Solution
It’s a simple game. We can control *
to go into portals (X
), and any other characters are refrred to as the wall.
Apparently, the goal is to go into the portal in the east.
I found the code which can modify character’s corodinate by pressing arrow keys, so I patched the moving distance from 1 to 2 when the up arrow key is pressed.
Then just play the game and get the flag.
Flag
rarctf{g4m3_h4ck1ng_f0r_n00b5!-75f8b0}
Infinite Free Trial
Challenge Info
We’ve decided to make an app specially for flag hoarding, can you make sure no one can crack it?
NOTE: The flag is a valid registration key
file:
ift.zip - 12b533
Solution
It’s a serial key checker. Analyze statically in IDA.
In func()
, there is a 2-step verification (do_crc_check()
and do_xor_check()
).
However, the crc check is useless as it is simple to reverse the xor check and get flag.
|
|
Flag
rarctf{welc0m3_t0_y0ur_new_tr14l_281099b9}
Very TriVial ReVersing
Challenge Info
Hey, at least it’s not Haskell!
file:
vtr-alternate - ade66a
,vtr - 71cb11
Solution
A flag checker. In main__check()
shows that it encode user input and check if it’s the same as the encoded flag.
Below is how the encoding mechanism works.
|
|
Flag
rarctf{See,ThatWasn'tSoHard-1eb519ed}
Jammy’s Old Infra
Challenge Info
Jammy asked me to build some login infrastructure for his website. Well, here it is.
file:
jammys_old_infra.apk - 7d03b5
,jammys_old_infra_4_4.apk - 8f56dd
Solution
After playing app in Android Studio and statically reverse the apk file with apktool and dex2jar (APKLab is also useful)
It came out that the app is to open a login webpage (http://ec2-18-130-135-40.eu-west-2.compute.amazonaws.com:8090
).
After pressing the login button, both username and password are checked locally by the function checkCreds()
which is inside libnative-lib.so
.
checkUsername()
simply check if the input username is the same as "SQ]X9]A>" ^ "bc79T08j"
, so the username is 12jammyT
.
checkPasswords()
check if the input password is the same as the real password decrypted by AES-CBC. The part that decrypt AES key is quite complicate, so dynamically fetch the real password in memory is a better choice.
Setting the debug environment is the hardest part of the challenge though. Here is my steps in short😢:
- Install one rootable VM in Android Studio.
- Root the VM with the help of SuperSU.
- Enter the shell (
adb -e shell
) - Open the app and find its pid. (
ps | grep jammy
) - Setup port forwarding (
adb forward tcp:23946 tcp:23946
) - Start the gdbserver (
gdbserver localhost:23946 --attach <pid>
) - Open IDA and remote attach to the gdbserver.
After the catastrophic suffering, just set a breakpoint right after AES decryption is over, and the password in on the stack. (stove:spill2:drivable:1
)
Lastly, input the right username and password to get flag.
Flag
rarctf{pl34s3_d0nt_s0lv3_st4tic4lly_3829103890}
boring flag checker
Challenge Info
Why do all rev challenges have to be boring flag checkers these days?
Note: This challenge has the same binary as
boring-flag-runner
file:
boring-flag-checker.zip - 4dc9bc
Solution
It’s a brainfuck vm challenge.
My script is not good enough, so I will add the writeup in the future days.
Flag
rarctf{1_h0p3_y0u-3njoy3d_my-Br41nF$&k_r3v!_d387171751}
Down The Rabbit Hole
Challenge Info
Good luck
file:
loader - ef0b0a
Solution
The program will call sub_401196(i)
to load 0x8000 bytes shellcode into a RWX space 0xabcdef000
, then execute the shellcode.
This is how the decoding works:
|
|
In short, there are two options, and both options will fork()
. The parent process will call the child process to do something and get the result back.
red pill
- input at most 16 bytes as password
- parent passes the input to the child process to calculate hash (
md5(md5(input()) + md5('https://i.imgur.com/gub160B.png\x00'))
) - parent receives the hash
- if the hash is the same as
'cbbefea802bf596615e073d3419262f0'
, print out half the flag
So I attached to the parent process and modify the receiving hash sotred in the memory, and got the 1/2 flag.
blue pill
- come up with a very simple shell
- if the cat command is used, pass the argument (file path) to the child process
- the child process will first add
X
padding to the end of the argument till string length is the multiply of 4 - then xor each 4 bytes to get a 4 bytes hash value
- again, if the hash value is matched, print out another half of the flag.
Similarly to the red pill, I just dynamically changed the zero flag to pass the check, and got the last part of the flag.
Flag
rarctf{D1d-y0u-t4k3-th3-r3d-p1ll-0r-m4yb3-th3-blu3-p177-539c8a}