
Laboratório local GeoServer/PostGIS que reproduz a injeção SQL do OGC Filter (CVE-2023-25157/25158) com modos de teste A/B vulnerável, corrigido e mitigado.
Este lab usa GeoServer/PostGIS para pesquisar OGC Filter SQL injection em ambiente local, com separação clara entre modo operator/setup e modo attacker.
GeoServer 2.22.0 incorpora GeoTools vulnerável. GeoServer 2.22.2 incorpora GeoTools corrigido. O lab mantém o mesmo schema/request para teste A/B de versão, mitigação e limite de privilégios.
| Modo | Superfície | Propósito |
|---|
| Setup/operator REST | container interno cve-operator | Setup REST, validação e revisão de log do backend |
| Gateway único | 127.0.0.1:8889 | Uma única porta para UI do operator e rotas OWS |
| Operator Web UI | 127.0.0.1:8889/geoserver/web/ | UI do GeoServer para o operador; com proxy Basic Auth |
| Attacker vulnerable | 127.0.0.1:8889/vuln/geoserver/ows | WFS/OWS vulnerável, erro de DB aparece na resposta |
| Attacker patched | 127.0.0.1:8889/patched/geoserver/ows | GeoServer 2.22.2 / GeoTools 28.2 |
| Attacker realistic | 127.0.0.1:8889/realistic/geoserver/ows | WFS/OWS vulnerável mas gateway remove detalhes de erro |
| Mitigation function | 127.0.0.1:8889/mit-functions/geoserver/ows | GeoServer 2.22.0, encode functions=false |
| Mitigation FeatureId | 127.0.0.1:8889/mit-featureid/geoserver/ows | GeoServer 2.22.0, preparedStatements=true |
PostgreSQL/PostGIS não publica porta para o host. GeoServer não publica diretamente a porta 8080 para o host; o host só vê cve-gateway em 127.0.0.1:8889. O container cve-attacker está apenas em attacker-net; ele não tem rota para PostgreSQL ou serviço interno do GeoServer. O setup REST passa pelo container interno cve-operator em geoserver-net.
Abra no navegador:
http://127.0.0.1:8889/geoserver/web/
Login em 2 camadas:
operator / operator_labadmin / geoserverTudo passa pelo mesmo gateway 8889, sem precisar memorizar várias portas. O Burp pode manter o proxy padrão 127.0.0.1:8080.
.\lab.ps1 reset all
.\lab.ps1 validate
powershell -ExecutionPolicy Bypass -File .\verify-lab.ps1
powershell -ExecutionPolicy Bypass -File .\negative-controls.ps1
powershell -ExecutionPolicy Bypass -File .\attack-chain.ps1
Comandos de gerenciamento:
.\lab.ps1 start vulnerable
.\lab.ps1 start patched
.\lab.ps1 start mitigated
.\lab.ps1 start worstcase
.\lab.ps1 reset all
.\lab.ps1 stop
.\lab.ps1 status
Tabelas de seed:
cities: chave primária integer, coluna name text, usada para strStartsWith/strEndsWith.sensors_text: chave primária text, usada para FeatureId injection.sensors_int: chave primária integer, negative control para FeatureId.events: camada de pesquisa JSONB.internal_assets: não publicada, contém LAB-CANARY-<UUID> novo após cada reset.local_points: shapefile non-JDBC negative control.Roles:
geoserver_readonly: CONNECT, USAGE schema, SELECT apenas nas tabelas publicadas.geoserver_impact: SELECT adicional em internal_assets para ilustrar usuário de DB da aplicação com privilégios amplos.geoserver_worstcase: perfil separado, com pg_read_server_files para ler arquivo canary falso /lab/flag.txt.attack-chain.ps1 executa:
GetCapabilities.DescribeFeatureType.encode functions=false.preparedStatements=true.internal_assets, impact branch vaza canary, patched/realistic não divulgam canary.As evidências são salvas em evidence/attack-chain-*. A pasta atual mantém apenas a evidência de pass mais recente para evitar acúmulo.
Este perfil não faz parte do cenário principal:
.\lab.ps1 start worstcase
powershell -ExecutionPolicy Bypass -File .\worstcase-demo.ps1
Ele apenas lê o arquivo canary falso /lab/flag.txt, não lê /etc/passwd, não faz dump de hash, não quebra senha.