HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > БЕЗОПАСНОСТЬ И УЯЗВИМОСТИ > Этичный хакинг или пентестинг > Задания/Квесты/CTF/Конкурсы
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 13.04.2024, 15:53
xverizex
Новичок
Регистрация: 03.07.2017
Сообщений: 7
С нами: 4665206

Репутация: 2
По умолчанию

Задание должно было решиться легко, но я столкнулся с проблемой, которую долго не мог решить. Открыв приложение в гидре можно увидеть, что доступен флаг debug, если в меню указать пункт 'D'. После включения флага, переходим в check_pass. Декомпилятор гидры выдал вот такой код. Ниже приведен код функции check_pass, и я решил, написать свой генератор кода, но генерировался совсем не тот код, который бы подошел.

C++:


Код:
void
check_pass
(
void
)
{
int
iVar1
;
tm
*
__tp
;
char
local_118
[
88
]
;
time_t local_c0
;
char
our_password
[
65
]
;
char
generated_password
[
65
]
;
int
index
;
local_c0
=
time
(
(
time_t
*
)
0x0
)
;
srand
(
(
uint
)
local_c0
)
;
for
(
index
=
0
;
index

tm_hour
=
11
+
5
;
tm
->
tm_min
=
18
;
tm
->
tm_sec
=
51
;
t
=
mktime
(
tm
)
;
printf
(
"time: %s\n"
,
t
)
;
Почему я добавил к 11 ещё 5, это стало ясно далее, когда я попытался сгенерировать пароль. Уж пришлось так сделать, потому что время отставало на 5 часов. Запишем число, которое выдала утилита.
Что делаем дальше? Заходим с помощью отладчика с помощью radare2.

Bash:


Код:
r2 -d task.elf
Переходим в функцию main, затем переход в режим просмотра и переход в функцию check_pass.

Bash:


Код:
s main
V
листаем вниз и встречаем функцию check_pass.
Смотрим какое число справа от check_pass
(
у меня это было
2
)
Нажимаем
2
и мы переходим в код этой функции.
Я приведу пример простого дизассемблера, потому что так проще. Будет без картинок, но вы держитесь. Так тоже можно объяснить. Посмотрите на этот код.

Код:


Код:
;-- check_pass:
            0x0000121a  push rbp
            0x0000121b  mov rbp, rsp
            0x0000121e  sub rsp, 0x110
            0x00001225  mov edi, 0
            0x0000122a  call sym.imp.time
            0x0000122f   mov qword [rbp - 0xb8], rax
            0x00001236  mov rax, qword [rbp - 0xb8]
            0x0000123d  mov edi, eax
            0x0000123f   call sym.imp.srand
            0x00001244  mov dword [rbp - 4], 0
     ┌─<0x0000124b      eb38           jmp 0x1285
      │    0x0000124d      e88efeffff     call sym.imp.rand
Как мы видим, по адресу 0x122f мы записываем результат rax в локальную переменную. Тут то нам и нужно поменять значение rax. Но для начала переходим в режим просмотра отладчика.

Код:


Код:
V!!
нажимаем ':'
db 0x122f
Так мы поставили наш первый бряк на место в памяти. Осталось поставить бряк на место проверки пароля, чтобы посмотреть сгенерированный пароль.

Код:


Код:
0x00001363      488d9550ffff.  lea rdx, [rbp - 0xb0]
            0x0000136a      488d45a0       lea rax, [rbp - 0x60]
            0x0000136e      4889d6           mov rsi, rdx
            0x00001371      4889c7           mov rdi, rax
            0x00001374      e817fdffff        call sym.imp.strcmp
Опять нажимаем ':' и ставим бряк на адрес 0x1374.

Код:


Код:
db 0x1374
Далее пишем в отладчике

Код:


Код:
dc
и начинает выполняться программа. Включаем отладку, чтобы удостовериться, что время такое как на сервере (тот самый сервер, который на Antichat.games - мастер рандома). Затем переходим в вести пароль. бряк останавливает выполнение.
Записываем в rax новое значение. Если вы забыли, то в rax сейчас содержится время в секундах. Его мы меняем на то, что нам пишет утилита (та, которая генерирует число mktime из даты).

Код:


Код:
dr rax=0x.... <- здесь число в шестнадцатеричной системе счисления
Теперь можем продолжить выполнение программы.

Код:


Код:
dc
Далее он предлагает указать пароль. Пишем всякий вздор и нажимаем enter. Бряк останавливает нас на проверке. Отсюда мы достаем нашу строку.

Код:


Код:
ps @rdi
Эта строка и есть пароль к серверу, которая завязана на времени. Время генерируется при каждом новом вызове функции, поэтому важно не затупить, а то придется несколько операций заново производить.

Всем спасибо.
 
Ответить с цитированием

  #2  
Старый 01.05.2024, 19:01
nitrotek
Новичок
Регистрация: 01.05.2024
Сообщений: 0
С нами: 1072769

Репутация: 0
По умолчанию

Можно без отладчика, достаточно развернуть функцию генерации сида и на вход ей подать дату и в ремя, которые сервер в режиме D показывает

C:


Код:
#include 
using namespace std
;
const
int
SecondsPerMinute
=
60
;
const
int
SecondsPerHour
=
3600
;
const
int
SecondsPerDay
=
86400
;
const
int
DaysOfMonth
[
12
]
=
{
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
}
;
bool
IsLeapYear
(
short
year
)
{
if
(
year
%
4
!=
0
)
return
false
;
if
(
year
%
100
!=
0
)
return
true
;
return
(
year
%
400
)
==
0
;
}
time_t
mkgmtime
(
short
year
,
short
month
,
short
day
,
short
hour
,
short
minute
,
short
second
)
{
time_t secs
=
0
;
for
(
short
y
=
1970
;
y
<
year
;
++
y
)
secs
+=
(
IsLeapYear
(
y
)
?
366
:
365
)
*
SecondsPerDay
;
for
(
short
m
=
1
;
m
<
month
;
++
m
)
{
secs
+=
DaysOfMonth
[
m
-
1
]
*
SecondsPerDay
;
if
(
m
==
2
&&
IsLeapYear
(
year
)
)
secs
+=
SecondsPerDay
;
}
secs
+=
(
day
-
1
)
*
SecondsPerDay
;
secs
+=
hour
*
SecondsPerHour
;
secs
+=
minute
*
SecondsPerMinute
;
secs
+=
second
;
return
secs
;
}
int
main
(
)
{
time_t seed
=
mkgmtime
(
2024
,
5
,
1
,
5
,
41
,
7
)
;
unsigned
int
d
=
(
(
unsigned
int
*
)
&
seed
)
[
0
]
;
srand
(
d
)
;
char
bytes
[
65
]
;
for
(
int
x
=
0
;
x
<
64
;
x
++
)
{
bytes
[
x
]
=
rand
(
)
%
26
+
65
;
}
bytes
[
64
]
=
0
;
printf
(
"%s\n"
,
bytes
)
;
return
0
;
}
 
Ответить с цитированием
Ответ





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.