123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- package de.tudarmstadt.informatik.hostage.protocol;
- import java.nio.ByteBuffer;
- import java.util.ArrayList;
- import java.util.List;
- import de.tudarmstadt.informatik.hostage.wrapper.ByteArray;
- public class MySQL implements Protocol<ByteArray>{
- private enum STATE {
- NONE, CONNECTED, LOGIN_INFO, AUTHENTICATE, LOGGED_IN, CLOSED
- }
-
- private STATE state = STATE.NONE;
-
- private byte[] request;
-
- @Override
- public List<ByteArray> processMessage(ByteArray request) {
- List<ByteArray> response = new ArrayList<ByteArray>();
- if(request != null) {
- this.request = request.get();
- }
-
- switch(state) {
- case NONE:
- response.add(new ByteArray(greeting()));
- state = STATE.CONNECTED;
- break;
- case CONNECTED:
- response.add(new ByteArray(responseOK()));
- state = STATE.LOGIN_INFO;
- break;
- case LOGIN_INFO:
- if(this.request[4] == 0x01) {
- response = null;
- state = STATE.CLOSED;
- } else if(this.request[4] == 0x03) {
- response.add(new ByteArray(response()));
- } else {
- response.add(new ByteArray(responseError()));
- }
- break;
- case AUTHENTICATE:
- break;
- case LOGGED_IN:
- break;
- default:
- state = STATE.CLOSED;
- break;
- }
-
- return response;
- }
-
- @Override
- public TALK_FIRST whoTalksFirst() {
- return TALK_FIRST.SERVER;
- }
- @Override
- public String toString(){
- return "MySQL";
- }
-
- @Override
- public int getPort() {
- return 3306;
- }
-
- @Override
- public boolean isClosed() {
- return state == STATE.CLOSED;
- }
-
- private byte[] wrapPckt(byte[] pckt) {
- byte[] buff = ByteBuffer.allocate(4).putInt(pckt.length).array();
- byte[] pcktLength = {buff[3], buff[2], buff[1]};
- byte[] pcktNumber = new byte[1];
- if(request != null) pcktNumber[0] = (byte) (request[3] + 1);
- else pcktNumber[0] = 0x00;
-
- byte[] response = concat(pcktLength, pcktNumber, pckt);
- return response;
- }
-
- private byte[] greeting() {
- byte[] protocol = {0x0a};
- String version = "5.5.31-0+wheezy1";
- byte[] versionFin = {0x00};
- byte[] thread = {0x2a, 0x00, 0x00, 0x00};
- byte[] salt = {0x44, 0x64, 0x49, 0x7e, 0x60, 0x48, 0x25, 0x7e, 0x00};
- byte[] capabilities = {(byte) 0xff, (byte) 0xf7};
- byte[] language = {0x08};
- byte[] status = {0x02, 0x00};
- byte[] unused = {0x0f, (byte) 0x80, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- byte[] salt2 = {0x6c, 0x26, 0x71, 0x2c, 0x25, 0x72, 0x31, 0x3d, 0x7d, 0x21, 0x26, 0x3b, 0x00};
- String payload = "mysql_native_password";
- byte[] fin = {0x00};
-
- byte[] response = concat(protocol, version.getBytes(),versionFin, thread, salt, capabilities, language, status, unused, salt2, payload.getBytes(), fin);
-
- return wrapPckt(response);
- }
-
- private byte[] responseOK() {
- byte[] affectedRows = {0x00, 0x00, 0x00};
- byte[] status = {0x02, 0x00};
- byte[] warnings = {0x00, 0x00};
-
- byte[] response = concat(affectedRows, status, warnings);
- return wrapPckt(response);
- }
-
- private byte[] response() {
- // 4 packets to respond
- byte[] pckt0 = {0x01, 0x00, 0x00, 0x01, 0x01};
- byte[] pckt1 = {0x27, 0x00, 0x00, 0x02, 0x03, 0x64, 0x65, 0x66, 0x00,
- 0x00, 0x00, 0x11, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d,
- 0x65, 0x6e, 0x74, 0x00, 0x0c, 0x21, 0x00, 0x18, 0x00, 0x00, 0x00, (byte) 0xfd, 0x00, 0x00, 0x1f, 0x00, 0x00};
- byte[] pckt2 = {0x05, 0x00, 0x00, 0x03, (byte) 0xfe, 0x00, 0x00, 0x02, 0x00};
- byte[] pckt3 = {0x09, 0x00, 0x00, 0x04, 0x08, 0x28, 0x44, 0x65, 0x62, 0x69, 0x61, 0x6e, 0x29};
- byte[] pckt4 = {0x05, 0x00, 0x00, 0x05, (byte) 0xfe, 0x00, 0x00, 0x02, 0x00};
-
- byte[] response = concat(pckt0, pckt1, pckt2, pckt3, pckt4);
- return response; //no wrapPckt() needed, because packets already have length and number
- }
-
- private byte[] responseError() {
- byte[] fill1 = {(byte) 0xff};
- byte[] code = {0x17, 0x04};
- byte[] fill2 = {0x23};
- String state = "08S01";
- String msg = "Unknown command";
-
- byte[] response = concat(fill1, code, fill2, state.getBytes(), msg.getBytes());
- return wrapPckt(response);
- }
-
- private byte[] concat(byte[]...bytes) {
- int newSize = 0;
- for(byte[] b: bytes) newSize += b.length; //get total new size
- byte[] dst = new byte[newSize]; //create new array with new size
-
- int currentPos = 0;
- int newPos;
- for(byte[] b:bytes) { //for each elem b out of bytes
- newPos = b.length; //get b.length and new position
- System.arraycopy(b, 0, dst, currentPos, newPos); //copy b in dst from currentPos to newPos
- currentPos += newPos; //increase currentPos to newPos + currentPos
- }
- return dst;
- }
- @Override
- public boolean isSecure() {
- return false;
- }
- @Override
- public Class<ByteArray> getType() {
- return ByteArray.class;
- }
- }
|