Author: [email protected] 404 Team
Chinese version: https://paper.seebug.org/2087/
GeoServer is an open source software server written in Java that allows users to share and edit geospatial data. GeoServer is primarily built on the Spring Framework and uses the GeoTools libraries.
GeoTools is an open-source Java library that provides tools for geospatial data. GeoServer uses GeoTools for many of its core functionalities, such as data reading, writing, and transformation.
GeoServer and GeoTools have released CVE-2023-25157 and CVE-2023-25158vulnerabilities, which contain SQL injection vulnerabilities in OGC query function. GeoServer includes support for the OGC Filter expression language and the OGC Common Query Language (CQL) as part of the Web Feature Service (WFS) and Web Map Service (WMS) protocols. CQL is also supported through the Web Coverage Service (WCS) protocol for ImageMosaic coverages. Here are known conditions:
SQL injection vulnerabilities for GeoTools when executing OGC filters using the JDBCDataStore implementation:
GeoServer <2.21.4,<2.22.2
GeoTools <28.2、<27.4、<26.7、<25.7、<24.7
The official patches have been released. Please update it in time.
This article uses GeoServer 2.21.3, which is downloaded and decompressed:
unzip geoserver-2.21.3-bin.zip
Then go to the geoserver-2.21.3-bin/bin
directory and execute the startup program
sh startup.sh
When startup succeed, visit HTTP / / X.X.X.X [:] : 8080 / geoserver/web/
Build PostgreSQL with Docker
docker run -e POSTGRES_PASSWORD=password -d -p 5433:5432 postgres:latest
Enter the container and install the postgis
extension
apt search postgis
apt install postgis postgresql-14-postgis-3-scripts
postgresql-14-postgis-3-scripts
The installing is based on your PostgreSQL version.PostgreSQL 14.1
is used here.
Relevant data here can be found in official documents:https://docs.geoserver.org/latest/en/user/gettingstarted/postgis-quickstart/index.html
Edit startup.sh
startup script to add remote debugging parameters:
exec "${_RUNJAVA}" ${JAVA_OPTS:--DNoJavaOpts -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005} "${MARLIN_ENABLER:--DMarlinDisabled}" "${RENDERER:--DDefaultrenderer}" "-Djetty.base=${GEOSERVER_HOME}" "-DGEOSERVER_DATA_DIR=${GEOSERVER_DATA_DIR}" -Djava.awt.headless=true -DSTOP.PORT=8079 -DSTOP.KEY=geoserver -jar "${GEOSERVER_HOME}/start.jar"
The environment setup is complete.
Since there are multiple injection points,strStartsWith
is taken as an example for analysis here. Import the project into IDEA, enable debugging, and locate the breakpoint to getReaderInternal
function underogr.geotools.jdbc
select now()
will be executed to determine whether the database can be connected properly before querying this.getDataStore().getConnection(this.getState());
Follow up to selectSQL
In the selectSQL
function, selectColumns
traverses the columns in the database and concatenates SQL statements
The concatenation correlation function is as follows:
The SQL statement after concatenation is as follows:
SELECT "gid","bin",encode(ST_AsEWKB("the_geom"), 'base64') as "the_geom" FROM "public"."nyc_buildings" WHERE
Next comes the handling of filter
Convert the previously entered CQL_FILTER
into an SQL statement and concatenate it after WHERE
in filter
Therefore, the final concatenated SQL statement is as follows:
SELECT "gid","bin",encode(ST_AsEWKB("the_geom"), 'base64') as "the_geom" FROM "public"."nyc_buildings" WHERE ("bin"::text LIKE 'x') = true and 1=(SELECT CAST ((SELECT version()) AS INTEGER)) -- %') = true
Execute SQL statements in the JDBCFeatureReader
by executeQuery
To sum up: the getReaderInternal()
function under org.geotools.jdbc
processes the query input by the user, and further calls selectSQL
to generate SQL query statements corresponding to the database. After the query statement of the database is generated, the function determines whether the CQL_FILTER
query condition exists. If it exists, the CQL_FILTER
condition entered by the user is processed, and the CQL_FILTER
is converted to an SQL statement by encodeToString(Filter filter)
. It is then concatenated after WHERE
by the FilterToSQL filter
. Finally, the JDBCFeatureReader
's this.runQuery
executes the SQL statement with the injection to complete the injection.
The final call stack for the entire vulnerability is as follows:
<init>:153, JDBCFeatureReader (org.geotools.jdbc)
getReaderInternal:607, JDBCFeatureSource (org.geotools.jdbc)
getReaderInternal:218, JDBCFeatureStore (org.geotools.jdbc)
getReader:636, ContentFeatureSource (org.geotools.data.store)
features:173, ContentFeatureCollection (org.geotools.data.store)
features:52, ContentFeatureCollection (org.geotools.data.store)
features:40, SecuredFeatureCollection (org.geoserver.security.decorators)
features:75, SecuredSimpleFeatureCollection (org.geoserver.security.decorators)
features:93, DecoratingSimpleFeatureCollection (org.geotools.feature.collection)
encode:572, FeatureTransformer$FeatureTranslator (org.geotools.gml.producer)
parse:1054, TransformerBase$XMLReaderSupport (org.geotools.xml.transform)
transform:485, TransformerIdentityImpl (org.apache.xalan.transformer)
run:287, TransformerBase$Task (org.geotools.xml.transform)
transform:121, TransformerBase (org.geotools.xml.transform)
transform:103, TransformerBase (org.geotools.xml.transform)
encode:247, GML2OutputFormat (org.geoserver.wfs.xml)
write:261, GML2OutputFormat (org.geoserver.wfs.xml)
write:199, WFSGetFeatureOutputFormat (org.geoserver.wfs)
response:1018, Dispatcher (org.geoserver.ows)
handleRequestInternal:272, Dispatcher (org.geoserver.ows)
So far, GeoServer and Geotools have officially released repaired versions. The patches submitted by GeoServer add the moduleorg. Geoserver. Jdbcloader. JDBCLoaderProperties
in thesrc/community/jdbcconfig/SRC/main/Java/org/geoserver/jdbcconfig/internal/ConfigDatabase.java
The module is used for the configuration of jdbcconfig module property field under file jdbcconfig/jdbcconfig.properties
, and change the constructor to include this attribute field.
Moreover, official also changed the insertion syntax insrc/community/jdbcconfig/src/main/java/org/geoserver/jdbcconfig/internal/OracleDialect.java
In the patch submitted by GeoTools, the official modifiedmodules/library/jdbc/src/main/java/org/geotools/data/jdbc/FilterToSQL.java
added theEscapeSql
module and escapeBackslash
field to defend against SQL injection.
https://github.com/murataydemir/CVE-2023-25157-and-CVE-2023-25158
https://docs.geoserver.org/latest/en/user/introduction/overview.html
本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/2088/