Skip to content

Commit

Permalink
Update PostgreSQL modules to use correct IP and port & explicitly che…
Browse files Browse the repository at this point in the history
…ck for session
  • Loading branch information
sjanusz-r7 committed Feb 1, 2024
1 parent 0686a97 commit ef9d6b5
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 67 deletions.
27 changes: 18 additions & 9 deletions modules/auxiliary/admin/postgres/postgres_readfile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,30 @@ def initialize(info = {})
deregister_options( 'SQL', 'RETURN_ROWSET' )
end

def rhost
datastore['RHOST']
end

def rport
datastore['RPORT']
end

def run
self.postgres_conn = session.client if session
ret = postgres_read_textfile(datastore['RFILE'])
case ret.keys[0]
when :conn_error
print_error "#{rhost}:#{rport} Postgres - Authentication failure, could not connect."
when :sql_error
case ret[:sql_error]
when /^C58P01/
print_error "#{rhost}:#{rport} Postgres - No such file or directory."
vprint_status "#{rhost}:#{rport} Postgres - #{ret[:sql_error]}"
print_error "#{postgres_conn.address}:#{postgres_conn.port} Postgres - No such file or directory."
vprint_status "#{postgres_conn.address}:#{postgres_conn.port} Postgres - #{ret[:sql_error]}"
when /^C42501/
print_error "#{rhost}:#{rport} Postgres - Insufficient file permissions."
vprint_status "#{rhost}:#{rport} Postgres - #{ret[:sql_error]}"
print_error "#{postgres_conn.address}:#{postgres_conn.port} Postgres - Insufficient file permissions."
vprint_status "#{postgres_conn.address}:#{postgres_conn.port} Postgres - #{ret[:sql_error]}"
else
print_error "#{rhost}:#{rport} Postgres - #{ret[:sql_error]}"
print_error "#{postgres_conn.address}:#{postgres_conn.port} Postgres - #{ret[:sql_error]}"
end
when :complete
loot = ''
Expand All @@ -54,10 +63,10 @@ def run
loot << row.first
}
# No idea what the actual ctype will be, text/plain is just a guess
path = store_loot('postgres.file', 'text/plain', rhost, loot, datastore['RFILE'])
print_good("#{rhost}:#{rport} Postgres - #{datastore['RFILE']} saved in #{path}")
vprint_good "#{rhost}:#{rport} Postgres - Command complete."
path = store_loot('postgres.file', 'text/plain', postgres_conn.address, loot, datastore['RFILE'])
print_good("#{postgres_conn.address}:#{postgres_conn.port} Postgres - #{datastore['RFILE']} saved in #{path}")
vprint_good "#{postgres_conn.address}:#{postgres_conn.port} Postgres - Command complete."
end
postgres_logout if self.postgres_conn
postgres_logout if self.postgres_conn && session.blank?
end
end
15 changes: 12 additions & 3 deletions modules/auxiliary/admin/postgres/postgres_sql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ def initialize(info = {})
))
end

def rhost
datastore['RHOST']
end

def rport
datastore['RPORT']
end

def auxiliary_commands
{ "select" => "Run a select query (a LIMIT clause is probably a really good idea)" }
end
Expand All @@ -34,15 +42,16 @@ def cmd_select(*args)
end

def run
self.postgres_conn = session.client if session
ret = postgres_query(datastore['SQL'],datastore['RETURN_ROWSET'])
case ret.keys[0]
when :conn_error
print_error "#{rhost}:#{rport} Postgres - Authentication failure, could not connect."
when :sql_error
print_error "#{rhost}:#{rport} Postgres - #{ret[:sql_error]}"
print_error "#{postgres_conn.address}:#{postgres_conn.port} Postgres - #{ret[:sql_error]}"
when :complete
vprint_good "#{rhost}:#{rport} Postgres - Command complete."
vprint_good "#{postgres_conn.address}:#{postgres_conn.port} Postgres - Command complete."
end
postgres_logout if self.postgres_conn
postgres_logout if self.postgres_conn && session.blank?
end
end
14 changes: 8 additions & 6 deletions modules/auxiliary/scanner/postgres/postgres_hashdump.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ def password
end

def run_host(ip)
self.postgres_conn = session.client if session
# Query the Postgres Shadow table for username and password hashes and report them
res = postgres_query('SELECT usename, passwd FROM pg_shadow',false)

service_data = {
address: rhost,
port: rport,
address: postgres_conn.address,
port: postgres_conn.port,
service_name: 'postgres',
protocol: 'tcp',
workspace_id: myworkspace_id
Expand Down Expand Up @@ -79,10 +80,10 @@ def run_host(ip)

case res[:sql_error]
when /^C42501/
print_error "#{rhost}:#{rport} Postgres - Insufficient permissions."
print_error "#{postgres_conn.address}:#{postgres_conn.port} Postgres - Insufficient permissions."
return
else
print_error "#{rhost}:#{rport} Postgres - #{res[:sql_error]}"
print_error "#{postgres_conn.address}:#{postgres_conn.port} Postgres - #{res[:sql_error]}"
return
end
when :complete
Expand All @@ -107,8 +108,8 @@ def run_host(ip)
)

service_data = {
address: rhost,
port: rport,
address: postgres_conn.address,
port: postgres_conn.port,
service_name: 'postgres',
protocol: 'tcp',
workspace_id: myworkspace_id
Expand Down Expand Up @@ -144,6 +145,7 @@ def run_host(ip)
end
print_good("#{tbl.to_s}")

postgres_logout if self.postgres_conn && session.blank?
end

end
13 changes: 7 additions & 6 deletions modules/exploits/linux/postgres/postgres_payload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,14 @@ def check
end

def exploit
self.postgres_conn = session.client if session

version = do_login(username,password,database)
case version
when :noauth; print_error "Authentication failed"; return
when :noconn; print_error "Connection failed"; return
else
print_status("#{rhost}:#{rport} - #{version}")
print_status("#{postgres_conn.address}:#{postgres_conn.port} - #{version}")
end

fname = "/tmp/#{Rex::Text.rand_text_alpha(8)}.so"
Expand All @@ -112,7 +114,7 @@ def exploit
rescue RuntimeError => e
print_error "Failed to create UDF function: #{e.class}: #{e}"
end
postgres_logout if @postgres_conn
postgres_logout if @postgres_conn && session.blank?

end

Expand All @@ -121,18 +123,17 @@ def exploit
# Returns the version from #postgres_fingerprint
def do_login(user=nil,pass=nil,database=nil)
begin
require 'pry-byebug'; binding.pry;
password = pass || postgres_password
vprint_status("Trying #{user}:#{password}@#{rhost}:#{rport}/#{database}")
vprint_status("Trying #{user}:#{password}@#{rhost}:#{rport}/#{database}") unless self.postgres_conn
result = postgres_fingerprint(
:db => database,
:username => user,
:password => password
)
if result[:auth]
report_service(
:host => rhost,
:port => rport,
:host => postgres_conn.address,
:port => postgres_conn.port,
:name => "postgres",
:info => result.values.first
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,15 +124,15 @@ def execute_payload
drop_query = postgres_query(query)
case drop_query.keys[0]
when :conn_error
print_error "#{peer} - Connection error"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Connection error"
return false
when :sql_error
print_warning "#{peer} - Unable to execute query: #{query}"
print_warning "#{postgres_conn.address}:#{postgres_conn.port} - Unable to execute query: #{query}"
return false
when :complete
print_good "#{peer} - #{tablename} dropped successfully"
print_good "#{postgres_conn.address}:#{postgres_conn.port} - #{tablename} dropped successfully"
else
print_error "#{peer} - Unknown"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Unknown"
return false
end

Expand All @@ -141,15 +141,15 @@ def execute_payload
create_query = postgres_query(query)
case create_query.keys[0]
when :conn_error
print_error "#{peer} - Connection error"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Connection error"
return false
when :sql_error
print_warning "#{peer} - Unable to execute query: #{query}"
print_warning "#{postgres_conn.address}:#{postgres_conn.port} - Unable to execute query: #{query}"
return false
when :complete
print_good "#{peer} - #{tablename} created successfully"
print_good "#{postgres_conn.address}:#{postgres_conn.port} - #{tablename} created successfully"
else
print_error "#{peer} - Unknown"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Unknown"
return false
end

Expand All @@ -159,24 +159,24 @@ def execute_payload
copy_query = postgres_query(query)
case copy_query.keys[0]
when :conn_error
print_error "#{peer} - Connection error"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Connection error"
return false
when :sql_error
if copy_query[:sql_error].match? 'execution expired'
print_warning 'Timed out. The function was potentially executed.'
return true
end
print_warning "#{peer} - Unable to execute query: #{query}"
print_warning "#{postgres_conn.address}:#{postgres_conn.port} - Unable to execute query: #{query}"
if copy_query[:sql_error] =~ /must be superuser to COPY to or from an external program/
print_error 'Insufficient permissions, User must be superuser or in pg_read_server_files group'
return false
end
print_warning "#{peer} - Unable to execute query: #{query}"
print_warning "#{postgres_conn.address}:#{postgres_conn.port} - Unable to execute query: #{query}"
return false
when :complete
print_good "#{peer} - #{tablename} copied successfully(valid syntax/command)"
print_good "#{postgres_conn.address}:#{postgres_conn.port} - #{tablename} copied successfully(valid syntax/command)"
else
print_error "#{peer} - Unknown"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Unknown"
return false
end

Expand All @@ -186,16 +186,16 @@ def execute_payload
select_query = postgres_query(query)
case select_query.keys[0]
when :conn_error
print_error "#{peer} - Connection error"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Connection error"
return false
when :sql_error
print_warning "#{peer} - Unable to execute query: #{query}"
print_warning "#{postgres_conn.address}:#{postgres_conn.port} - Unable to execute query: #{query}"
return false
when :complete
print_good "#{peer} - #{tablename} contents:\n#{select_query}"
print_good "#{postgres_conn.address}:#{postgres_conn.port} - #{tablename} contents:\n#{select_query}"
return true
else
print_error "#{peer} - Unknown"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Unknown"
return false
end
end
Expand All @@ -204,15 +204,15 @@ def execute_payload
drop_query = postgres_query(query)
case drop_query.keys[0]
when :conn_error
print_error "#{peer} - Connection error"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Connection error"
return false
when :sql_error
print_warning "#{peer} - Unable to execute query: #{query}"
print_warning "#{postgres_conn.address}:#{postgres_conn.port} - Unable to execute query: #{query}"
return false
when :complete
print_good "#{peer} - #{tablename} dropped successfully(Cleaned)"
print_good "#{postgres_conn.address}:#{postgres_conn.port} - #{tablename} dropped successfully(Cleaned)"
else
print_error "#{peer} - Unknown"
print_error "#{postgres_conn.address}:#{postgres_conn.port} - Unknown"
return false
end
end
Expand All @@ -236,6 +236,7 @@ def do_login(user, pass, database)
end

def exploit
self.postgres_conn = session.client if session
return unless vuln_version?
return unless login_success?
print_status("Exploiting...")
Expand All @@ -244,6 +245,6 @@ def exploit
else
print_error("Exploit Failed")
end
postgres_logout if @postgres_conn
postgres_logout if @postgres_conn && session.blank?
end
end
Loading

0 comments on commit ef9d6b5

Please sign in to comment.