AIS3 2019 Pre-exam
Contents
MISC
KcufsJ
We got a file called “kcufsj.dms”.
If we reverse its name, it will be “jsfuck”, which is an esoteric subset of JavaScript, where code is written in only six characters [
, ]
, (
, )
, !
, and +
.
For more information: JSFuck wiki
Now we can implement code to get the information of the file.
|
|
And we get a very long string written in JSFuck.
Past that string into the console of a web developer in your web browser, and we can get the flag AIS3{R33v33rs33_JSFUCKKKKKK}
.
Crystal Maze
When you connect to the server, it is a maze-like program.
We are at the entrance of the maze, the prompt will ask for whether to go up, down, left, or right.
Whenever we send our decision, it will send the feedback to us. There are three kinds of feedback:
- OK, and ask your next move
- Hit the wall, and connection will be cut down
- Get the flag
My idea to deal with this problem is that whenever I go to a point, I will try all four directions, and store those serializations of the footwork in a two-dimensional list about what I need to check next.
Such as
[[up, left, left],
[up, left, right],
[up, left down]]
This is how I implemented
|
|
And we get the flag AIS3{4R3_Y0U_RUNN1NG_45_F45T_45_CRY5T4L?}
.
Are you admin?
We got a source code main.rb
.
|
|
It seems like we need to make is_admin
to yes
to get the flag.
Type bc", "is_admin":"yes","report":[{"subject":"Math
for Your name, and type 23"}], “00":"01
for your age.
In this way, the whole string will become {"name"=>"bc", "is_admin"=>"yes", "report"=>[{"subject"=>"Math", "is_admin"=>"no", "age"=>"23"}], "00"=>"01"}
, which makes is_admin
to yes
.
Reverse
Trivial
It is a relatively easy one.
We get a file Trivial.dms
. After looking at its strings, we can get the flag AIS3{This_is_a_reallllllllllly_boariiing_challenge}
.
TsaiBro
In this question, we get a file TsaiBro.dms
, which is the main program on the connection. And we get a file flag.txt
, which contains the context of the encoded flag.
The program takes the argument as input, and output its encoded form.
I input characters to the program to make a dictionary. With this dictionary, I can read flag.txt and transfer the code back to its original character.
|
|
And we can get the flag AIS3{y0u_4re_a_b1g_f4n_0f_tsaibro_n0w}
.
HolyGrenade
We get files HolyGrenade.pyc
and output.txt
, which contains encoded message.
If we decompile the .pyc file directly with pycdc
, we can only get part of the code because pycdc does not do a modification for python version 3.7.
So we should modify the .pyc file before decompile.
Address | Before Modification | After Modification | Meaning |
---|---|---|---|
0x14E and 0x8E | a0 | 6a | LOAD_METHOD -> LOAD_ATTR |
0x152 and 0x90 | a1 | 83 | CALL_METHOD -> CALL_FUNCTION |
After modification, we can decompile successfully.
This is the code after rename.
|
|
It cut the flag into pieces and do md5 hash, switch the position in each block with func(arg).
This is how I reverse this process. I get the flag by reversing func(arg) and make a dictionary with md5 hash value from a combination of 4 characters. Finally, make the collision.
|
|
And we can get the flag AIS3{7here_15_the_k1ll3r_ra661t}
.
Note: Instead of pycdc
, using uncompyle6
can be a better solution because there is no need to revise the binary code.
Crypto
TCash
We get a file task.py
.
|
|
It takes each character in the flag, encodes with md5, transfers hex to int, and modulo 64. Besides md5, it operates sha256 as well.
To solve this problem, I implement two lists containing md5 and sha256 of each character. We can get the flag back by comparing the encoded parts with these two lists.
|
|
And we can get the flag AIS3{0N_May_16th @Sead00g said Heeeee ReMEMBerEd tH4t heee UseD thE SAME set 0f On1iNe to01s to S01Ve Rsa AeS RCA DE5 at T-cat-cup, AnD 7he kEys aRE AlWAys TCat2019Key}
.
RSA101
In this challenge, the connection provides public key (N, e) and encrypted flag.
Then, it will provide a Phi oracle. In this oracle, user can input a number n, and the program will output ((n % phi) % 64). If we can get phi, we are able to get the flag.
In the observation, if n <= phi, it will output 0. So we can keep trying from the top. For instance, 2^2048 output non-zero, then try 2^2047, and output zero, then keep 2^2047, try 2^2047 + 2^2046 …
After we get phi, we can get d by doing modular multiplicative inverse. With d, we can decrypt the flag.
|
|
And we can get the flag AIS3{RSA_L0L_01100110011101010110001101101011}
.
RSA202
In this challenge, we get lots of information after connection:
- e
- n1 : r * next_prime(r)
- n2 : p * q
- enc : pow(FLAG1, e, n1)
- enc : pow(FLAG2, e, n2)
And two hints:
- p, q, r are prime numbers.
- ((p - 1) % r)^2 + ((r^5 - 1) % p)^2 == 0
For n1:
I use the tool yafu
to bruteforce to get r and next_prime(r), which is p and q.
For n2:
- Since ((p - 1) % r)^2 + ((r^5 - 1) % p)^2 == 0, (p - 1) % r = 0 and (r^5 - 1) % p = 0.
- Since r^5 - 1 = (r - 1) * (r^4 + r^3 + r^2 + r + 1), either (r - 1) % p = 0 or (r^4 + r^3 + r^2 + r + 1) % p = 0.
- Since p and r are prime numbers, (r - 1) % p = 0 cannot be true.
- That is, (r^4 + r^3 + r^2 + r + 1) = kp.
- We already know r, we can calculate (r^4 + r^3 + r^2 + r + 1) and find out that it is a prime.
- Regarding (r^4 + r^3 + r^2 + r + 1) = kp, k needs to be 1, and we get p. n2 / p = q.
With p and q, we can get phi = (p - 1) * (q - 1), and we can get d by doing the modular multiplicative inverse. And we get the flag.
However, it is a decimal number. We need to transfer the flag to hex and later transfer to ASCII code.
Finally, we get the flag AIS3{S0me7im3s_I_h4tE_factorDB}
.
Author L3o
LastMod 2019-08-04