Add Them Sneaky Polynomials

In this challenge, we are given three big polynomials p,q and r.

p = x^406 + x^405 + x^402 + x^399 + x^397 + x^391 + x^390 + x^387 + x^386 + x^378 + x^374 + x^372 + x^371 + x^369 + x^367 + x^364 + x^360 + x^358 + x^357 + x^352 + x^350 + x^345 + x^344 + x^341 + x^336 + x^335 + x^334 + x^333 + x^331 + x^330 + x^329 + x^328 + x^327 + x^324 + x^322 + x^320 + x^314 + x^311 + x^308 + x^307 + x^303 + x^300 + x^299 + x^296 + x^295 + x^290 + x^289 + x^287 + x^279 + x^271 + x^266 + x^264 + x^262 + x^260 + x^257 + x^256 + x^252 + x^249 + x^248 + x^246 + x^243 + x^239 + x^238 + x^236 + x^233 + x^230 + x^227 + x^225 + x^223 + x^222 + x^220 + x^218 + x^216 + x^215 + x^209 + x^208 + x^207 + x^204 + x^202 + x^199 + x^190 + x^189 + x^185 + x^184 + x^180 + x^177 + x^176 + x^175 + x^172 + x^167 + x^166 + x^162 + x^160 + x^159 + x^155 + x^154 + x^149 + x^147 + x^143 + x^137 + x^135 + x^131 + x^129 + x^126 + x^124 + x^122 + x^116 + x^110 + x^108 + x^105 + x^104 + x^100 + x^99 + x^97 + x^94 + x^93 + x^90 + x^88 + x^87 + x^86 + x^85 + x^83 + x^75 + x^73 + x^69 + x^63 + x^62 + x^57 + x^54 + x^51 + x^44 + x^41 + x^38 + x^37 + x^36 + x^34 + x^29 + x^28 + x^26 + x^25 + x^21 + x^20 + x^19 + x^16 + x^15 + x^14 + x^13 + x^6 + x^5 + x^2

q = x^399 + x^398 + x^396 + x^393 + x^392 + x^391 + x^388 + x^386 + x^384 + x^381 + x^377 + x^376 + x^368 + x^364 + x^360 + x^355 + x^354 + x^353 + x^352 + x^348 + x^346 + x^345 + x^344 + x^343 + x^335 + x^334 + x^329 + x^326 + x^325 + x^321 + x^318 + x^317 + x^315 + x^314 + x^311 + x^307 + x^306 + x^304 + x^300 + x^296 + x^293 + x^291 + x^282 + x^277 + x^270 + x^263 + x^261 + x^260 + x^256 + x^254 + x^253 + x^252 + x^251 + x^248 + x^245 + x^242 + x^241 + x^239 + x^238 + x^236 + x^232 + x^226 + x^225 + x^222 + x^220 + x^219 + x^214 + x^209 + x^208 + x^207 + x^206 + x^202 + x^200 + x^196 + x^191 + x^190 + x^186 + x^181 + x^180 + x^178 + x^177 + x^169 + x^168 + x^165 + x^164 + x^163 + x^162 + x^161 + x^159 + x^157 + x^156 + x^151 + x^149 + x^148 + x^147 + x^146 + x^144 + x^141 + x^140 + x^138 + x^137 + x^136 + x^134 + x^133 + x^132 + x^130 + x^129 + x^128 + x^126 + x^123 + x^121 + x^113 + x^109 + x^103 + x^101 + x^100 + x^95 + x^93 + x^91 + x^85 + x^84 + x^81 + x^74 + x^73 + x^71 + x^68 + x^67 + x^54 + x^52 + x^51 + x^50 + x^48 + x^46 + x^45 + x^43 + x^39 + x^35 + x^32 + x^31 + x^30 + x^29 + x^21 + x^15 + x^14 + x^9 + x^8 + x^5 + x^4 + x^2 + 1

r = x^404 + x^402 + x^396 + x^389 + x^387 + x^386 + x^384 + x^382 + x^376 + x^373 + x^367 + x^366 + x^365 + x^362 + x^361 + x^358 + x^356 + x^355 + x^354 + x^353 + x^352 + x^349 + x^348 + x^347 + x^345 + x^343 + x^340 + x^334 + x^332 + x^331 + x^328 + x^327 + x^326 + x^322 + x^317 + x^316 + x^314 + x^313 + x^312 + x^310 + x^309 + x^308 + x^305 + x^304 + x^303 + x^301 + x^300 + x^299 + x^296 + x^295 + x^292 + x^291 + x^290 + x^288 + x^287 + x^286 + x^285 + x^283 + x^279 + x^278 + x^274 + x^271 + x^269 + x^268 + x^266 + x^265 + x^263 + x^261 + x^260 + x^259 + x^258 + x^256 + x^254 + x^252 + x^251 + x^250 + x^249 + x^244 + x^243 + x^242 + x^237 + x^236 + x^228 + x^225 + x^224 + x^223 + x^222 + x^221 + x^215 + x^214 + x^213 + x^212 + x^205 + x^201 + x^200 + x^199 + x^197 + x^193 + x^192 + x^191 + x^190 + x^189 + x^188 + x^187 + x^182 + x^180 + x^175 + x^174 + x^173 + x^167 + x^166 + x^163 + x^158 + x^156 + x^155 + x^153 + x^151 + x^150 + x^149 + x^143 + x^142 + x^140 + x^139 + x^136 + x^135 + x^133 + x^129 + x^126 + x^125 + x^123 + x^121 + x^118 + x^117 + x^116 + x^115 + x^113 + x^110 + x^106 + x^105 + x^104 + x^103 + x^102 + x^98 + x^95 + x^92 + x^89 + x^87 + x^85 + x^81 + x^80 + x^77 + x^76 + x^75 + x^74 + x^71 + x^70 + x^67 + x^66 + x^64 + x^63 + x^60 + x^59 + x^58 + x^56 + x^54 + x^53 + x^48 + x^44 + x^41 + x^39 + x^38 + x^35 + x^34 + x^31 + x^29 + x^28 + x^27 + x^22 + x^21 + x^20 + x^17 + x^14 + x^12 + x^11 + x^10 + x^9 + x^6 + x^4 + x^3 + x + 1

 

The given three polynomials can be viewed as a binary number with a bit equal to ‘1‘ if the co-efficient of x^a is ‘1‘ else the bit as ‘0‘ where 0<=a<=406

The resulting binary number of p,q,r contains 407 bits each.

p_bits = “11001001010000011001100000001000101101010010001011000010100001100100001111011111001010100000100100110001001100110000110100000001000000010000101010100110001001101001000110100100100101011010101100000111001010010000000011000110001001110010000110001011000110000101000100000101000101001010100000100000101001100011010011001011110100000001010001000001100001001001000000100100111010000110110001110011110000001100100”

q_bits = “00000001101001110010101001000110000000100010001000011110001011110000000110000100110001001101100100011010001000100101000000001000010000001000000101100010111100100100110110100010000011001011000010000111100010100010000110001000011011000000011001111101011000010111101001101110111011101001010000000100010000010110000101010000011001000000110100110000000000001011101011010001000100111100000001000001100001100110101”

r_bits = “00101000001000000101101010000010010000011100110010111110011101010010000010110011100010000110111011100111011100110011101111010001100010010110110101111010101111000011100001100000001001111100000111100000010001110100011111110000101000011100000110010000101101011100000110110011010001001101010011110100100011111000100100100101010001100111100110011011001110101100001000100101100110010111000011100100101111001011011”

Now, we have the binary representation of the given polynomials.

A hint was given for the problem : “Xor is your best friend”

So, the first thought that striked my mind was XORing all the three polynomials and check for the flag.

p_bits XOR q_bits XOR r_bits = “11100000110001101110100011001100111101101100110001100010110111000110001011101000011001101011111011001100011000100110011011011000110010001110011010111110011010001110010001100110101111101101101001100000111001000110011010111110111010101110011001100110110011001110101011011000101111101110100011010000011010001101110010111110111100100110000011101010101111101110100011010000011000101101110011010110111110100001010”

The XORed value when represented in ASCII contained the flag for this challenge:):)

Flag is,   pctf{f1n1t3_f13lds_4r3_m0r3_us3ful_th4n_y0u_th1nk}

Happiness finding the flag:):)

Logo

Logo:

  • This is a question based on forensics.
  • We are given a png file.

c9a03d15f235087145579bd06f3f736a5546539254fbde100b8bf4d990bb8d8f_logo

Approach:

  • I analyzed the metadata of the image to see if the flag is hidden there using exiftool.
  • I saw the binary data of the image to check if the flag is there (using hexeditor)
  • Both the above steps were failures and there was no flag obtained in both the procedures.

Color, Brightness and Contrast:

  • A clue was given in the question that talked about the contrast of the given image.
  • So, I googled to see the relationship between color, brightness and contrast.
  • These three parameters are inter-related such that changing any of the two parameters will change the other parameter.
  • I guessed that if the brightness or contrast of the given image is changed, I can find the flag.
  • So, I used online tools to change the brightness and contrast of the image.
  • For a particular value of brightness and contrast, the flag appeared just above the ‘B’ in the image.

image

If you see carefully you can read the flag just above ‘B’ :):)

tjctf{in_plain_sight}


 

Python Reversing

Python Reversing:

Here, we are given a python file which has done some operations on the flag text and resulting binary data is given as,

“1001100001011110110100001100001010000011110101001100100011101111110100011111010101010000000110000011101101110000101111101010111011100101000011011010110010100001100010001010101001100001110110100110011101”

So the task is simple…. We have take to this binary output, reverse engineer the python file which takes this as input and run the file to get back the flag.

The screen shot of the given python file is,

Python_Reversing_1

Here the flag variable has the dummy string.

Here are the details that you find when you skim the file:

  • numpy is used to deal with multidimensional arrays in python.
  • Here setting the seed value (reference value) as 12345 will generate the same random numbers whenever the program runs and therefore other[] list will have a fixed set of numbers in it.
  • Here the unknown factors are arr[] and b[].
  • lmao is nothing but ‘ligma_sugma_sugondese_’ repeated 5 times.
  • The final xor’ed value is printed in the binary format with 8 bits for each character.

Reversing the python file:

  • The other[] list can be easily generated since the seed value is fixed.
  • Now the problem is how to divide the binary string to get the individual characters.
  • Observe the lower limit and upper limit of the random number is 1 and 4 respectively. So, multiplying the upper limit 4 with the ascii max value (127) will result values upto 512. So, we should know whether to divide the string into 8,9 or 10 bits for a particular character (0 – 512 needs 10 bits at the max). Once we find that , divide the ascii value with the corresponding value in the other[] list to get the original flag character.
  • The approach I followed for finding the characters was simple. First take the current 8 bits and see if the corresponding i’th random number in other[] list divides the 8 bits ascii value. If it divides, it is the corresponding i’th character and break. If it does not divide, repeat the above steps for 9 bits and 10 bits.
  • The above approach will get you all the characters in the flag string.
  • The reverse engineered python file is,

Python_Reversing_2

Happiness finding the flag:):)

tjctf{pYth0n_1s_tr1v14l}


 

macsh (Cryptography)

‘macsh’ ( Cryptography from Plaid-CTF )

Here we are given two python scripts, macsh.py and fmac.py

This is the snapshot from the macsh.py file

plaid_ctf_writeup1

  • This python script is the main file which has to be analysed first.
  • As we can see there, this file allows us to perform the basic operations in a unix based machine like ls, cat, pwd, cd.
  • So, the obvious answer would be is to navigate through all the directories present in the server through cd, and use ls to see the contents of the directory and after finding the ‘flag.txt’ file use cat to display the flag.
  • This is the first step analyzation that can be made as soon as you skim through the python script.

This is the snapshot from fmac.py file

Selection_001

  • This is the python file that does the AES Encryption part
  • The underlined parts of the file are the key note for solving the challenge
  • Here ‘N’ is the block size of the AES encryption which is 16. Here, the given input message is appended with length of the message and padding is done to make it a multiple of 16.
  • The final message is divided into blocks of 16 bytes and each block is encrypted using the Initialization vector ‘k0’ and key ‘k1’.
  • Since i (mod (8 * N)) is taken for the initialization vector, there are only 128 initialization vectors from 0 to 127.
  • reduce function is another clue to solving the problem, which xors all the encrypted blocks of the given message. So the final text remaining after all xoring is just a 16 bytes of data (irrespective of the size of the input message).
  • This is the first analyzation that comes to the mind as soon as skim through the given script.

So, let us get into solving the problem…..

Once again we will jump to the macsh.py file.

Selection_002

  • Let us get through the initializations done in the program. k0 and k1 are the keys used for the AES encryption part and they are same for all the encryptions in the current session.
  • Only 6 commands are allowed in the program among them 4 are in the privileged zone :):)

This is the main part of the program and also the key part in solving the problem.

Selection_003

  • The format of giving the input to the program is,  |$|> [mac] <|> [cmd] [args]
  • mac can be anything but cmd must be only from the 6 commands we have seen before.
  • Here, eval(cmd)(*args) is used to call the user-defined functions where ‘cmd’ is the function name and ‘*args’ is the arguments to the function.
  • So, if we give cmd = tag, we can call the function ‘tag’. Remember tag() returns the AES encrypted text for the input arguments passed to the function.
  • Underlined portion of the ‘if’ statement must be invoked for us solve the problem.
  • To invoke the ls() and cat() functions, our input to the program must be, |$| > [Encrypted_text(“ls ././././././.”)] <|> [ls] [././././././.] and |$| > [Encrypted_text(“cat ././flag.txt”)] <|> [cat] [././flag.txt], respectively.
  • But the problem is to get encrypted text for the ls and cat commands which is not possible because they are in privileged zone of the tag() function.
  • So, we have to find a way to get the encrypted text. Let us go back to the fmac.py file and get the flag already.

Let us see the loophole in the encryption process, more precisely in the initialization vectors and the reduce function.

Selection_004

  • First, the input message is appended with the length of the message and padding is done to make it a multiple of 128.
  • Let us make it clear that the key k1 for the encryption is same for all the message blocks and only the initialization vector k0 differs for the blocks.
  • 0th block, 128th block, 256th block, …… all have the same initialization vectors as 0.
  • 1st block, 129th block, 257th block, ……. all have the same initialization vectors as 1.
  • Since reduce function is used to xor the encrypted blocks, we will use the property of xor to cancel out the similar encrypted texts (a ^ a = 0, 0 ^ a = a)
  • So, our exploit looks like this for the ls command,

Selection_005

  • Here, first block uses the initialization vectors from 0 to 127, the second block uses the same initialization vectors from 0 to 127, and the last block uses the 0th initialization vector.
  • Here, 4112 is added because this is the length of the exploit that we are using and it will also be automatically added at the end of our message during the encryption process. Since both of them are present in the 1st initialization vector they get canceled out.
  • All the similar encrypted texts get canceled out leaving out only the “ls ././././././.” which is the required value for the variable mac in the macsh.py file.
  • So, after doing this with the ls, we can replace it with the cat command to get the flag printed from the server.
  • The final answer snapshot is,Selection_006

Happiness finding the flag :):)

PCTF{fmac_is_busted_use_PMAC_instead}