Sete dias da anual Hack Quest - sete missões que você precisa resolver para obter ingressos grátis para a Zeronights. Neste artigo, sugerimos que você se familiarize com as decisões de alguns deles, bem como descubra os nomes dos vencedores. Por conveniência, dividiremos a publicação em duas partes.

Conteúdo

Dia1. Galois
Para obter ajuda na preparação desta tarefa, agradeça a
REhints .
"O desafio é tão fácil quanto o seguinte: baixe o binário (passe: infectado), faça engenharia reversa e recupere dois segredos que o binário aceitará. Cada segredo é uma sequência ASCII. Você precisaria resolver o primeiro estágio antes de atacar o segundo. Boa sorte e que Galois esteja com você!Para obter o sinalizador, dois valores secretos devem ser inseridos sequencialmente:

Pelas linhas das mensagens, entramos na função:
DialogFuncBOOL __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4) { HWND v5; // eax HWND v6; // eax HWND v7; // eax HWND v8; // eax HWND v9; // eax HWND v10; // eax CHAR v11; // [esp+0h] [ebp-5Ch] CHAR String[20]; // [esp+2Ch] [ebp-30h] struct tagRECT Rect; // [esp+40h] [ebp-1Ch] UINT v14; // [esp+50h] [ebp-Ch] HDC hdc; // [esp+54h] [ebp-8h] unsigned int i; // [esp+58h] [ebp-4h] v14 = a2; if ( a2 == 20 ) { hdc = (HDC)a3; GetClientRect(hWnd, &Rect); SetMapMode(hdc, 8); SetWindowExtEx(hdc, 100, 100, 0); SetViewportExtEx(hdc, Rect.right, Rect.bottom, 0); FillRect(hdc, &Rect, hbr); return 1; } if ( v14 == 272 ) return 1; if ( v14 != 273 || HIWORD(a3) ) return 0; if ( (unsigned __int16)a3 == 1 ) { EndDialog(hWnd, (unsigned __int16)a3); return 1; } if ( (unsigned __int16)a3 != 1002 ) { if ( (unsigned __int16)a3 == 1004 ) { sub_42E7C0(&v11, 0, 42); if ( GetDlgItemTextA(hWnd, 1005, &v11, 42) <= 0x27 && (unsigned __int8)sub_42CEF0(&v11) ) { v9 = GetDlgItem(hWnd, 1004); EnableWindow(v9, 0); v10 = GetDlgItem(hWnd, 1005); EnableWindow(v10, 0); MessageBoxW(hWnd, L"Good job!", L"Success", 0); return 1; } MessageBoxW(hWnd, L"Keep trying!", L"Rejected", 0); } return 1; } if ( GetDlgItemTextA(hWnd, 1001, String, 18) != 16 || !(unsigned __int8)sub_4014E0(String) ) { MessageBoxW(hWnd, L"Keep trying!", L"Rejected", 0); return 1; } v5 = GetDlgItem(hWnd, 1002); EnableWindow(v5, 0); v6 = GetDlgItem(hWnd, 1001); EnableWindow(v6, 0); v7 = GetDlgItem(hWnd, 1005); EnableWindow(v7, 1); v8 = GetDlgItem(hWnd, 1004); EnableWindow(v8, 1); for ( i = 0; i < 0x28; ++i ) *((_BYTE *)&dword_442780 + i) ^= String[(signed int)i % 16]; MessageBoxW(hWnd, L"Stage #2 unlocked!", L"Accepted", 0); return 1; }
Para chegar ao
"Estágio # 2 desbloqueado!" , você deve passar no teste na função
sub_4014E0
(comprimento da cadeia - 16 caracteres). E antes do
"Bom trabalho!" - mais uma verificação em
sub_42CEF0
(o comprimento da segunda linha é inferior a 40 caracteres).
Etapa 1
char __cdecl sub_4014E0(char *a1) { int v1; // ecx unsigned __int128 var_1018[256]; // [esp+0h] [ebp-1018h] unsigned __int128 var_18; // [esp+1000h] [ebp-18h] int v5; // [esp+1010h] [ebp-8h] char v6; // [esp+1017h] [ebp-1h] sub_438740(0x1018u, v1); sub_43A460(var_1018, xmmword_4427A8, 0x1000u); sub_4010E0(a1, var_1018); sub_401250(var_1018, &var_18); v5 = sub_438845(var_18, &xmmword_442770, 0x10u); if ( !v5 ) v6 = 1; return v6; }
Sob o depurador, você pode verificar se
sub_43A460
copia dados de:

E
sub_438845
compara o valor com:
.data:00442770 xmmword_442770 9698CA91EE29902C60D377C981589205h
Os dados são apresentados na forma de números de 128 bits, porque se mostraram mais convenientes no decorrer de análises posteriores.
Função Sub_4010E0 void __cdecl sub_4010E0(unsigned __int128 *a1, unsigned __int128 *a2) { signed int i; // [esp+4h] [ebp-8h] signed int j; // [esp+8h] [ebp-4h] for ( i = 0; i < 128; ++i ) { for ( j = 0; j < 128; ++j ) { if ( (*((_DWORD *)a1 + (j >> 5)) >> (j & 0x1F)) & 1 ) { if ( !((*((_DWORD *)a1 + ((j + 1) % 128 >> 5)) >> ((j + 1) % 128 & 0x1F)) & 1) ) *((_DWORD *)&a2[2 * i] + ((j + 128) >> 5)) &= ~(1 << ((j + -128) & 0x1F)); } else { *((_DWORD *)&a2[2 * i] + (j >> 5)) &= ~(1 << (j & 0x1F)); *((_DWORD *)&a2[2 * i] + ((j + 128) >> 5)) &= ~(1 << ((j + -128) & 0x1F)); } } } }
A mesma função de forma um pouco simplificada void __cdecl sub_4010E0(unsigned __int128 *a1, unsigned __int128 *a2) { signed int i; // [esp+4h] [ebp-8h] signed int j; // [esp+8h] [ebp-4h] signed int j_1; for ( i = 0; i < 128; ++i ) { for ( j = 0; j < 128; ++j ) { j_1 = (j + 1) % 128; if ( (*((_DWORD *)a1 + j / 32) >> (j % 32)) & 1 ) { if ( !((*((_DWORD *)a1 + j_1 / 32) >> (j_1 % 32)) & 1) ) *((_DWORD *)&a2[2 * i] + 4 + j / 32) &= ~(1 << (j % 32)); } else { *((_DWORD *)&a2[2 * i] + j / 32) &= ~(1 << (j % 32)); *((_DWORD *)&a2[2 * i] + 4 + j / 32) &= ~(1 << (j % 32)); } } } }
Para cada par de números de 128 bits endereçados pelo segundo argumento, o ciclo percorre 128 bits da sequência de entrada (o primeiro argumento) e, se o bit for 0, redefine os bits correspondentes (essencialmente executa a operação AND). Para o segundo número de um par de bits, ele também será redefinido se o próximo bit na sequência for 0.
No python, é algo parecido com isto:
def sub_4010E0(a1, a2): for i in range(128): a2[2 * i] &= a1 a2[2 * i + 1] &= a1 & (a1 >> 1)
Função sub_401250 void __cdecl sub_401250(unsigned __int128 *a1, unsigned __int128 *a2) { signed int k; // [esp+4h] [ebp-Ch] signed int j; // [esp+8h] [ebp-8h] signed int i; // [esp+Ch] [ebp-4h] *(_QWORD *)a2 = 0i64; *((_QWORD *)a2 + 1) = 0i64; for ( i = 0; i < 128; ++i ) { for ( j = 0; j < 4; ++j ) *((_DWORD *)&a1[2 * i] + j) ^= *((_DWORD *)&a1[2 * i + 1] + j); for ( k = 0; k < 2; ++k ) *((_DWORD *)&a1[2 * i] + k) ^= *((_DWORD *)&a1[2 * i] + k + 2); LODWORD(a1[2 * i]) ^= DWORD1(a1[2 * i]); LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 16; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 8; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 4; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 2; LODWORD(a1[2 * i]) ^= LODWORD(a1[2 * i]) >> 1; if ( a1[2 * i] & 1 ) *((_DWORD *)a2 + (i >> 5)) |= 1 << (i & 0x1F); } }
A função dobra cada par resultante em um bit, executando um XOR entre todos os bits. Recebeu 128 bits e forma um número comparado com o dado.
Para encontrar uma solução, usamos o solver z3.
Com substituições simples em um notebook, transformamos o array xmmword_4427A8 em um sistema (zeros e os à esquerda são o número xmmword_442770) from z3 import * init('../') def xor_bits(x): x = Extract(63, 0, x) ^ Extract(127, 64 ,x) x = Extract(31, 0, x) ^ Extract(63, 32, x) x = Extract(15, 0, x) ^ Extract(31, 16, x) x = Extract(7, 0, x) ^ Extract(15, 8, x) x = Extract(3, 0, x) ^ Extract(7, 4, x) x = Extract(1, 0, x) ^ Extract(3, 2, x) return Extract(0, 0, x) ^ Extract(1, 1, x) x = BitVec('x', 128) s = Solver()
Convertendo os bits encontrados em uma string, obtemos a primeira chave:
ItWasJustAWarmUp .
Etapa 2
bool __cdecl sub_42CEF0(char *a1) { bool result; // al __int64 v2; // [esp+0h] [ebp-3Ch] __int64 v3; // [esp+8h] [ebp-34h] __int64 v4; // [esp+10h] [ebp-2Ch] __int64 v5; // [esp+18h] [ebp-24h] __int64 v6; // [esp+20h] [ebp-1Ch] int v7; // [esp+28h] [ebp-14h] int v8; // [esp+2Ch] [ebp-10h] int v9; // [esp+30h] [ebp-Ch] int v10; // [esp+34h] [ebp-8h] int v11; // [esp+38h] [ebp-4h] v6 = *(_QWORD *)a1; v5 = *((_QWORD *)a1 + 1); v4 = *((_QWORD *)a1 + 2); v3 = *((_QWORD *)a1 + 3); v2 = *((_QWORD *)a1 + 4); (**off_444360)(off_444360, &v6, 0, off_44435C); (**off_444360)(off_444360, &v5, 0, off_44435C); (**off_444360)(off_444360, &v4, 0, off_44435C); (**off_444360)(off_444360, &v3, 0, off_44435C); (**off_444360)(off_444360, &v2, 0, off_44435C); v11 = 0; result = 0; if ( v6 == qword_442780 ) { v10 = 8; if ( v5 == __PAIR__(*((_DWORD *)&qword_442780 + 3), *((_DWORD *)&qword_442780 + 2)) ) { v9 = 16; if ( v4 == __PAIR__(*((_DWORD *)&qword_442780 + 5), *((_DWORD *)&qword_442780 + 4)) ) { v8 = 24; if ( v3 == __PAIR__(*((_DWORD *)&qword_442780 + 7), *((_DWORD *)&qword_442780 + 6)) ) { v7 = 32; if ( v2 == __PAIR__(*((_DWORD *)&qword_442780 + 9), *((_DWORD *)&qword_442780 + 8)) ) result = 1; } } } } return result; }
A sequência inserida é representada como cinco números de 64 bits, cujo resultado da conversão é comparado com a matriz.

Caminhando sob o depurador, vemos a seguinte sequência de chamadas de função:

Até agora, está claro que o terceiro argumento é passado ao longo da cadeia de chamadas, às vezes o módulo 2 dobrando com uma, às vezes com o próximo bit da sequência de entrada (embora alguns bits, por exemplo, o primeiro, sejam ignorados).
Vamos ver onde ocorre a conversão do número convertido, colocando um ponto de interrupção no registro nos bytes correspondentes da memória:

I.e. o bit do número é substituído pelo valor do terceiro argumento, seu valor anterior é passado (às vezes invertido). Pode-se supor que ocorra a seguinte conversão:
a3 = xor_all_bits(input & x) ^ y; output = ((input << 1) ^ z) | a3;
- x define bits que não foram ignorados na primeira etapa;
- y depende de quantas vezes uma unidade foi adicionada (módulo 2);
- z corresponde aos bits invertidos no segundo passo.
Para determinar as constantes desconhecidas, obtemos os valores convertidos para zero e números com um bit definido. Para fazer isso, defina um contador
extern i; i = 0;
e na função
sub_428FD0
antes da próxima rodada, colocamos um ponto de interrupção com uma condição que imprimirá o valor do número após a chamada da função, defina seu próximo valor e repita a chamada da função.
print(Qword(Qword(ebp+8))), i=i+1, (i<64)?patch_qword(Qword(ebp+8), __int64(1) << i)^(eip=0x428FE0):0,0
Os seguintes valores foram obtidos:

De:
- x = 0x11CE9E8E6CF2B888
- y = 1
- z = 0x8E2B550A6AEDD63A
Portanto, no Python, a função de conversão é assim:
def xor_bits(x): a = 0 while x != 0: a ^= x & 1 x >>= 1 return a def round(x): x = ((x << 1) & 0xFFFFFFFFFFFFFFFF) | xor_bits(x & 0x8e2b550a6aedd63a) ^ 1 return x ^ 0x11CE9E8E6CF2B888 def encrypt(x): for _ in range(64): x = round(x) return x
E o inverso para ele:
def rev_round(x): x ^= 0x11CE9E8E6CF2B888 a = x & 1 x >>= 1 if xor_bits(x & 0x8e2b550a6aedd63a) ^ 1 != a: x |= 1 << 63 return x def decrypt(x): for _ in range(64): x = rev_round(x) return x
Aplicando a conversão em números da matriz
qword_442780
, obtemos a sequência desejada:
YourReversingSkillsAreImpressive_zN2018 .

Dia2. Blackanwyte
Para obter ajuda na preparação desta tarefa, agradeça a Vlad Roskov de
@leetmore
Ao
clicar no
link, vemos o seguinte:

Somos solicitados a inserir um código promocional. Vamos ver quais arquivos carregam quando a página é aberta.

Depois de examinar o whitebox.js, encontramos uma função que verifica o código promocional: Na variável
c
, o texto inserido é lido; verifica se corresponde à expressão regular "/ \ d + - \ w + /", portanto o código promocional deve estar no formato "1234-ABCD". Em seguida, o número é convertido em binário, zeros correspondem a "N" e unidades - "Z". Após reorganizar os números da matriz
f
, em um ciclo de 4 letras da sequência resultante, o hash md5 é obtido e seus quatro primeiros caracteres são verificados com os caracteres correspondentes da sequência "7177a294cfa7b53371776be5cfa74ddf".
Para obter o número correto, escreva um pequeno script. Como resultado, obtemos o número necessário, a primeira parte do nosso código promocional: 234082018.

Passamos a primeira parte do teste. Vamos para o segundo:

Pode-se observar que o valor retornado da função
blackbox_check
está marcado e, se nenhum erro ocorrer, e for igual a "elee757bc7fd00d5", ele será enviado ao servidor. No entanto, no arquivo whitebox.js não há menção a
blackbox_check
, portanto é hora de abrir o blackbox.js.
Depois que o editor de texto conseguiu abrir um arquivo longo, vemos a função blackbox_check que precisamos nele, e nela uma linha interessante (22). Pesquisando no Google, descobrimos que somos confrontados com um emulador escrito em Javascript.
O byte do arquivo executável é armazenado no
code
da variável, a linha 32 registra o código promocional na memória e a linha 33 define o endereço da pilha. Da linha 41, pode-se ver que o arquivo inicia, começando com o endereço "0x080485E0".
Salve o arquivo executável e veja o que está nele usando o IDA. Vamos para blackbox_check. Aqui vemos algum tipo de função hash. Após várias tentativas malsucedidas de encontrar oportunidades para brute rápido ou outras vulnerabilidades no algoritmo, observamos que o buffer no qual a parte da linha após a copia do traço é copiada é limitado a apenas 256 caracteres.
Verificamos com checksec e vemos que a pilha é executável:
Nota - na captura de tela e no texto do autor do vraytap, existem discrepâncias sobre se a pilha é executável. De fato, o código pode ser executado.
Considerando que já sabemos o endereço na pilha onde nossa linha será gravada, cabe a você anotar os bytes da linha "e1ee757bc7fd00d5" para o endereço desejado.

Enviamos a linha resultante pelo console e pegamos a bandeira:
Linha
pesquisada :
Bl4CK_0r_wYT3_It5_z3r0Ni6hT
Dia3. Pad me
Ei, esse grupo ainda usa um sistema de mensagens antigo. Assumimos que os membros estão na casa dos trinta e essa é a sua criptografia. Tente encontrar falhas lá. O sistema de mensagens deles é 51.15.79.170 E você sabe o que? Poderíamos interceptar uma parte da solicitação de autenticação.
Você pode usar ytW81KkHaGOnaqiG7Gr4AA ==: XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =1. Recebi o erro 403 após a postagem “ytW81KkHaGOnaqiG7Gr4AA ==: XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8 + XlL7Co5oHg =”. Se alterar algumas letras - ainda recebe o erro 403, ele altera a contagem de letras - recebe 500 erros. Após algumas investigações, percebi que a primeira parte deveria ter 16 bytes de comprimento na forma decodificada em base64 e a segunda parte deve conter alguns blocos de 16 bytes cada.
Parece que a primeira parte são os dados codificados por IV e a segunda parte no modo CBC e, de acordo com o nome da tarefa "pad", está preenchendo o ataque do oráculo.2. Permite alterar o último byte na forma decodificada base64 da segunda parte (script 01.php, total de 256 possibilidades). Para um caso, em vez do erro "403", recebi a mensagem "Senhor, sua mensagem está incorreta ou não tem 48 bytes"01.php script <?php $s = "7177a294cfa7b53371776be5cfa74ddf"; $r = ""; for($i=0;$i<32;$i+=4) { for($j=0;$j<16;$j++) { $a = sprintf("%04b", $j); $a = str_replace("0", "Z", $a); $a = str_replace("1", "N", $a); if (substr(md5($a), 0, 4) == substr($s, $i, 4)) break; } if ($j == 16) die("Error 1: {$i}"); $r .= $a; echo md5($r).": ".$r."\r\n"; } $p = array(22,30,25,23,2,20,0,11,24,6,31,3,16,12,9,15,27,28,18,1,21,4,8,13,17,7,19,29,5,26,14,10); $s = str_repeat("_", 32); for($i=0;$i<32;$i++) $s[$p[$i]] = $r[$i]; echo $s."\r\n"; $a = 0; for($i=0;$i<32;$i++) { if ($s[$i] == 'Z') $a += (1<<$i); } echo $a."\r\n";
3. Permite descriptografar a mensagem da tarefa usando ataque de preenchimento oracle (scripts 02.php e 02b.php) - Recebi a string "Nunca vou desistir de você \ nNunca vá".Script 02.php<?php
$a = „ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg=“;
$a = explode(»:", $a);
$a[0] = base64_decode($a[0]);
$a[1] = base64_decode($a[1]);
file_put_contents(«01.bin», $a[0].$a[1]);
$s = $a[1];
$known = "";
for($i=1;$i<=16;$i++)
{
for($j=0;$j<256;$j++)
{
$iv = str_repeat(«A», 16-$i).((chr($j).$known) ^ str_repeat(chr($i), $i));
if (($r = send($iv, substr($s, 0, 16))) !== false)
{
echo $r."\r\n";
$known = chr($j).$known;
echo bin2hex($known)." ".($known ^ substr($a[0], -$i))."\r\n";
quebrar;
}
}
if ($j == 256) die(«Error 1: {$i}»);
}
function send($a, $b)
{
$data = base64_encode($a).":".base64_encode($b);
$s = «POST / HTTP/1.0\r\n»;
$s.= «Host: 51.15.79.170\r\n»;
$s.= «Content-Length: ».strlen($data)."\r\n";
$s.= «User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n»;
$s.= "\r\n";
$s.= $data;
$r = "";
do {$socket =
fsockopen («51.15.79.170», 80);} while(!$socket);
fwrite($socket, $s);
while(!@feof($socket)) $r .= fread($socket, 4096);
fclose($socket);
if (strpos($r, «500 INTERNAL SERVER ERROR»)) die(«Error 2: {$data}»);
return (strpos($r, «403 FORBIDDEN») !== false)?false:$r;
}
Nunca vou desistir de vocêHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:49:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
0f0cc904c9a68b038e65 gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:49:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
270f0cc904c9a68b038e65 gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:50:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
db270f0cc904c9a68b038e65 r gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:51:11 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b1db270f0cc904c9a68b038e65 er gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:52:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
cab1db270f0cc904c9a68b038e65 ver gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:53:19 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b0cab1db270f0cc904c9a68b038e65 ever gonna give
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:54:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
84b0cab1db270f0cc904c9a68b038e65 Never gonna give
Script 02b.php <?php $a = "ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg="; $a = explode(":", $a); $a[0] = base64_decode($a[0]); $a[1] = base64_decode($a[1]); file_put_contents("01.bin", $a[0].$a[1]); $s = substr($a[1], 16); $iv2 = substr($a[1], 0, 16); $known = ""; for($i=1;$i<=16;$i++) { for($j=0;$j<256;$j++) { $iv = str_repeat("A", 16-$i).((chr($j).$known) ^ str_repeat(chr($i), $i)); if (($r = send($iv, substr($s, 0, 16))) !== false) { echo $r."\r\n"; $known = chr($j).$known; echo bin2hex($known)." ".($known ^ substr($iv2, -$i))."\r\n"; break; } } if ($j == 256) die("Error 1: {$i}"); } function send($a, $b) { $data = base64_encode($a).":".base64_encode($b); $s = "POST / HTTP/1.0\r\n"; $s.= "Host: 51.15.79.170\r\n"; $s.= "Content-Length: ".strlen($data)."\r\n"; $s.= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n"; $s.= "\r\n"; $s.= $data; $r = ""; do {$socket = @fsockopen("51.15.79.170", 80);} while(!$socket); fwrite($socket, $s); while(!@feof($socket)) $r .= fread($socket, 4096); fclose($socket); if (strpos($r, "500 INTERNAL SERVER ERROR")) die("Error 2: {$data}"); return (strpos($r, "403 FORBIDDEN") !== false)?false:$r; }
Nunca váHTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:50:12 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
67 o
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:51:11 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
a167 go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:51:14 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
15a167 go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:52:30 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c715a167 r go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:53:57 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
d6c715a167 er go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:54:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
1bd6c715a167 ver go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:54:28 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
631bd6c715a167 ever go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
d1631bd6c715a167 Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:43 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
21d1631bd6c715a167
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:47 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
2021d1631bd6c715a167 p
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:55:51 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
1d2021d1631bd6c715a167 up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:07 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
821d2021d1631bd6c715a167 up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
09821d2021d1631bd6c715a167 u up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:52 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
8609821d2021d1631bd6c715a167 ou up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:56:52 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
008609821d2021d1631bd6c715a167 you up
Never go
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 21:57:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
7d008609821d2021d1631bd6c715a167 you up
Never go
4. Ok, parece que a mensagem foi truncada (deve ter 48 bytes). Usando o google, encontrei uma música com a fase completa " Nunca vou desistir de você \ nNunca vou decepcioná-lo ." Permite criptografá-la usando o ataque de oracle padding do último bloco até o primeiro bloco e iv (scripts 05.php e 04_brute.php).Script 04_brute.php <?php $a = "ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg="; $a = explode(":", $a); $a[0] = base64_decode($a[0]); $a[1] = base64_decode($a[1]); file_put_contents("01.bin", $a[0].$a[1]); $s = hex2bin("ff4fba7f36536f04bd0a3f77b8b06dde"); $known = ""; for($i=1;$i<=16;$i++) { for($j=0;$j<256;$j++) { $iv = str_repeat("A", 16-$i).((chr($j).$known) ^ str_repeat(chr($i), $i)); if (($r = send($iv, substr($s, 0, 16))) !== false) { echo $r."\r\n"; $known = chr($j).$known; echo bin2hex($known)."\r\n"; break; } } if ($j == 256) die("Error 1: {$i}"); } function send($a, $b) { $data = base64_encode($a).":".base64_encode($b); $s = "POST / HTTP/1.0\r\n"; $s.= "Host: 51.15.79.170\r\n"; $s.= "Content-Length: ".strlen($data)."\r\n"; $s.= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n"; $s.= "\r\n"; $s.= $data; $r = ""; do {$socket = @fsockopen("51.15.79.170", 80);} while(!$socket); fwrite($socket, $s); while(!@feof($socket)) $r .= fread($socket, 4096); fclose($socket); if (strpos($r, "500 INTERNAL SERVER ERROR")) die("Error 2: {$data}"); return (strpos($r, "403 FORBIDDEN") !== false)?false:$r; }
05.php <?php $a = "ytW81KkHaGOnaqiG7Gr4AA==:XXnpfKJoUCufBm2ztTXGCN6wgqLeScU8+XlL7Co5oHg="; $a = explode(":", $a); $a[0] = base64_decode($a[0]); $a[1] = base64_decode($a[1]); $Q = "Never gonna give you up\nNever gonna let you down".str_repeat("\x10", 0x10); echo strlen($Q)."\r\n"; $e1 = substr($a[1], 0, 16); $d1 = $a[0] ^ "Never gonna give"; $e2 = $d1 ^ substr($Q, 48, 16); echo bin2hex($e2)."\r\n"; $d2 = hex2bin("9e3d4885d3be30498069cfc4992e73df"); $e3 = $d2 ^ substr($Q, 32, 16); echo bin2hex($e3)."\r\n"; $d3 = hex2bin("df36d50a16261f0ef36f4912ca900ab1"); $e4 = $d3 ^ substr($Q, 16, 16); echo bin2hex($e4)."\r\n"; $d4 = hex2bin("20c3540ec72fa0b486b5f0c868218360"); $e5 = $d4 ^ substr($Q, 0, 16); echo bin2hex($e5)."\r\n"; $a[0] = $e5; $a[1] = $e4.$e3.$e2.$e1; $data = base64_encode($a[0]).":".base64_encode($a[1]); $s = "POST / HTTP/1.0\r\n"; $s.= "Host: 51.15.79.170\r\n"; $s.= "Content-Length: ".strlen($data)."\r\n"; $s.= "User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0\r\n";
20c3540ec72fa0b486b5f0c868218360HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:51:49 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
60
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:52:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
8360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:52:15 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:52:52 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
68218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:53:56 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:55:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:56:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:57:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
86b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:58:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:58:59 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
a0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Tue, 23 Oct 2018 23:59:05 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
2fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:00:08 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:00:10 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
0ec72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:00:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
540ec72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:01:21 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
c3540ec72fa0b486b5f0c868218360
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:01:34 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 57
Connection: close
Sir, your message is incorrect or it is not 48 bytes long
20c3540ec72fa0b486b5f0c868218360
String pesquisada64
94a0daa1cb371f1cd914d9b69b139e75
f05329a5bfdb4469f906bae4fd4104b1
ff4fba7f36536f04bd0a3f77b8b06dde
6ea6226bb50fc7dbe8db91e80f48f505
HTTP/1.1 200 OK
Server: nginx/1.10.3 (Ubuntu)
Date: Wed, 24 Oct 2018 00:01:51 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 73
Connection: close
Okey, I see you're from 80's, get in
< Wh4t_1f_R1ck_A3tl3y_Sm0ke_Cannab1s >