2012-03-18 12 views
146

Estoy intentando iniciar sesión en RDP usando AS3 (aire). Me está yendo bien, considerando la falta de recursos para entender el proceso real.Intentando iniciar sesión en RDP usando AS3

He pasado el nombre de usuario de envío inicial, recibí una respuesta del servidor y ahora estoy en la conexión de solicitud inicial.

Envío todos mis datos y cuando detecto el tráfico, veo que netmon reconoce correctamente qué tipo de paquete estoy enviando (t125). Estoy no desconectado por RDP y envían un paquete ack, pero no recibo la respuesta que esperaba.

He estado haciendo referencias cruzadas con connectoid, que es un cliente de código abierto RDP. En el código de conexión, estoy atascado donde escriben una mezcla de enteros pequeños y grandes.

Cuando miro a los ejemplos limitados por ahí (más como vertederos de paquetes), veo que la longitud de la conexión para este proceso es 412, pero mi bytearray se parece más a 470.

He convertido connectoid métodos a lo Creo que es correcto, pero con una mezcla de tipo endian, todavía no estoy seguro.

Lo siento si esto está distorsionado, pero hago todo lo posible para ayudarlo a ayudarme. Adjuntaré algún código que muestre lo que he tratado de hacer en la conversión.

public function sendMcsData(): void { 
    trace("Secure.sendMcsData"); 
    var num_channels: int = 2; 
    //RdpPacket_Localised dataBuffer = new RdpPacket_Localised(512); 
    var hostlen: int = 2 * "myhostaddress.ath.cx".length; 
    if (hostlen > 30) { 
     hostlen = 30; 
    } 
    var length: int = 158; 
    length += 76 + 12 + 4; 
    length += num_channels * 12 + 8; 
    dataBuffer.writeShort(5); /* unknown */ 
    dataBuffer.writeShort(0x14); 
    dataBuffer.writeByte(0x7c); //set 8 is write byte //write short is setbigendian 16 // 
    dataBuffer.writeShort(1); 
    dataBuffer.writeShort(length | 0x8000); // remaining length 
    dataBuffer.writeShort(8); // length? 
    dataBuffer.writeShort(16); 
    dataBuffer.writeByte(0); 
    var b1: ByteArray = new ByteArray(); 
    b1.endian = Endian.LITTLE_ENDIAN; 
    b1.writeShort(0xc001); 
    dataBuffer.writeBytes(b1); 
    dataBuffer.writeByte(0); 
    var b2: ByteArray = new ByteArray(); 
    b2.endian = Endian.LITTLE_ENDIAN; 
    b2.writeInt(0x61637544); 
    dataBuffer.writeBytes(b2); 
    //dataBuffer.setLittleEndian32(0x61637544); // "Duca" ?! 
    dataBuffer.writeShort(length - 14 | 0x8000); // remaining length 
    var b3: ByteArray = new ByteArray(); 
    b3.endian = Endian.LITTLE_ENDIAN; 
    // Client information 
    b3.writeShort(SEC_TAG_CLI_INFO); 
    b3.writeShort(true ? 212 : 136); // length 
    b3.writeShort(true ? 4 : 1); 
    b3.writeShort(8); 
    b3.writeShort(600); 
    b3.writeShort(1024); 
    b3.writeShort(0xca01); 
    b3.writeShort(0xaa03); 
    b3.writeInt(0x809); //should be option.keybaortd layout just guessed 1 
    b3.writeInt(true ? 2600 : 419); // or 0ece 
    dataBuffer.writeBytes(b3); 
    // // client 
    // build? we 
    // are 2600 
    // compatible 
    // :-) 
    /* Unicode name of client, padded to 32 bytes */ 
    dataBuffer.writeMultiByte("myhost.ath.cx".toLocaleUpperCase(), "ISO"); 
    dataBuffer.position = dataBuffer.position + (30 - "myhost.ath.cx".toLocaleUpperCase() 
     .length); 
    var b4: ByteArray = new ByteArray(); 
    b4.endian = Endian.LITTLE_ENDIAN; 
    b4.writeInt(4); 
    b4.writeInt(0); 
    b4.writeInt(12); 
    dataBuffer.writeBytes(b4); 
    dataBuffer.position = dataBuffer.position + 64; /* reserved? 4 + 12 doublewords */ 
    var b5: ByteArray = new ByteArray(); 
    b5.endian = Endian.LITTLE_ENDIAN; 
    b5.writeShort(0xca01); // out_uint16_le(s, 0xca01); 
    b5.writeShort(true ? 1 : 0); 
    if (true) //Options.use_rdp5) 
    { 
     b5.writeInt(0); // out_uint32(s, 0); 
     b5.writeByte(24); // out_uint8(s, g_server_bpp); 
     b5.writeShort(0x0700); // out_uint16_le(s, 0x0700); 
     b5.writeByte(0); // out_uint8(s, 0); 
     b5.writeInt(1); // out_uint32_le(s, 1); 
     b5.position = b5.position + 64; 
     b5.writeShort(SEC_TAG_CLI_4); // out_uint16_le(s, 
     // SEC_TAG_CLI_4); 
     b5.writeShort(12); // out_uint16_le(s, 12); 
     b5.writeInt(false ? 0xb : 0xd); // out_uint32_le(s, 
     // g_console_session 
     // ? 
     // 0xb 
     // : 
     // 9); 
     b5.writeInt(0); // out_uint32(s, 0); 
    } 
    // Client encryption settings // 
    b5.writeShort(SEC_TAG_CLI_CRYPT); 
    b5.writeShort(true ? 12 : 8); // length 
    // if(Options.use_rdp5) dataBuffer.setLittleEndian32(Options.encryption ? 
    // 0x1b : 0); // 128-bit encryption supported 
    // else 
    b5.writeInt(true ? (false ? 0xb : 0x3) : 0); 
    if (true) b5.writeInt(0); // unknown 
    if (true && (num_channels > 0)) { 
     trace(("num_channels is " + num_channels)); 
     b5.writeShort(SEC_TAG_CLI_CHANNELS); // out_uint16_le(s, 
     // SEC_TAG_CLI_CHANNELS); 
     b5.writeShort(num_channels * 12 + 8); // out_uint16_le(s, 
     // g_num_channels 
     // * 12 
     // + 8); 
     // // 
     // length 
     b5.writeInt(num_channels); // out_uint32_le(s, 
     // g_num_channels); 
     // // number of 
     // virtual 
     // channels 
     dataBuffer.writeBytes(b5); 
     trace("b5 is bigendin" + (b5.endian == Endian.BIG_ENDIAN)); 
     for (var i: int = 0; i < num_channels; i++) { 
      dataBuffer.writeMultiByte("testtes" + i, "ascii"); //, 8); // out_uint8a(s, 
      // g_channels[i].name, 
      // 8); 
      dataBuffer.writeInt(0x40000000); // out_uint32_be(s, 
      // g_channels[i].flags); 
     } 
    } 
    //socket. 
    //buffer.markEnd(); 
    //return buffer; 
} 
+3

¿Puede capturar el paquete ofensivo de un conocido cliente RDP conocido y compararlo con los paquetes que le interesan? Puede ser un error dentro de cómo está codificando un segmento de su matriz de bytes. – Ben

+0

¿Puede dar más detalles sobre lo que quiere decir con que está en la "conexión de solicitud inicial", por favor? La solicitud inicial ya debería haber sido aprobada para que inicies sesión, por lo que no está claro exactamente en qué estado estás atascado. ¿Has enviado tu solicitud de conexión (0xe0) y has recibido tu confirmación (0xd0) y ahora estás en la fase de "conexión inicial"? O en algún lugar más abajo en la línea de eventos? ¿El paquete que está generando en el código anterior es el paquete "MCS: connect-initial"? –

+2

Pregunta tonta, pero ¿ha intentado RDP manualmente en esa casilla para ver si funciona? podría haber algo sucediendo para evitar el inicio de sesión como un banner "esta máquina es solo para uso autorizado, bla, bla" –

Respuesta

3

Al parecer, la mayoría de la memoria intermedia es poco endian, pero se espera que varios bytes en su principio a ser números big endian de 16 bits (corto). Esto significa que debe escribir datos en little endian como si fuera interpretado como big endian. Con el fin de convertir los datos de big endian a little endian, puede usar un ByteArray temporal que tiene su endian configurado en grande, escribir datos en él, luego llamar al writeBytes() en su matriz de búfer principal y luego borrar la matriz big endian temporal. Las constantes de escritura se pueden realizar de forma manual, ya que puede cambiar el orden de bytes usted mismo, por ejemplo, cuando está escribiendo 0x0005 en big endian, escriba simplemente 0x0500 como little endian. Al parecer, escribió el código con el dataBuffer extraño con Endian siendo grande, por lo que conoce esta técnica. Aún así, es mejor que solo genere un dataBuffer adecuado en la función. Estoy tratando de corregir tu código a continuación basándome en el código connectoid que he descargado, para que devuelva un ByteArray correctamente formado con endian siendo poco - esto solo importa si leerás los datos ordenados, no cuando leas los bytes .

public function sendMcsData(): ByteArray { 
    trace("Secure.sendMcsData"); 
    var num_channels: int = 2; 
    var dataBuffer:ByteArray=new ByteArray(); //RdpPacket_Localised dataBuffer = new RdpPacket_Localised(512); 
    // it's better to build the data buffer in the function, as in java, otherwise you can receive interference 
    dataBuffer.endian=Endian.LITTLE_ENDIAN; // for clarity 
    var hostlen: int = 2 * "myhost.ath.cx".length; // hardcoded? TODO FIX 
    if (hostlen > 30) { 
     hostlen = 30; 
    } 
    var length: int = 158; 
    length += 76 + 12 + 4; // Options.use_rdp5 is true, apparently 
    length += num_channels * 12 + 8; 
    dataBuffer.writeShort(0x0500); // writing big-endian 0x5 *unknown* 
    dataBuffer.writeShort(0x1400); // writing big-endian 0x14 
    dataBuffer.writeByte(0x7c); //set 8 is write byte 
    //write short is setbigendian 16 // 
    dataBuffer.writeShort(0x0100); // writing big-endian 0x01 
    var be:ByteArray=new ByteArray(); 
    be.endian=Endian.BIG_ENDIAN; // create big-endian array for the data that's not static 
    be.writeShort(length | 0x8000); // remaining length 
    dataBuffer.writeBytes(be); 
    be.clear(); // so that extra writing will not spoil the array 
    dataBuffer.writeShort(0x0800); // writing big-endian 0x08 (length?) 
    dataBuffer.writeShort(0x1000); // writing big-endian 16 (0x10) 
    dataBuffer.writeByte(0); 
    dataBuffer.writeShort(0xc001); // this one is little endian by default 
    dataBuffer.writeByte(0); 
    dataBuffer.writeUnsignedInt(0x61637544); 
    //dataBuffer.setLittleEndian32(0x61637544); // "Duca" ?! 
    be.writeShort((length - 14) | 0x8000); // remaining length 
    dataBuffer.writeBytes(be); 
    be.clear(); 
    dataBuffer.writeShort(SEC_TAG_CLI_INFO); 
    dataBuffer.writeShort(212); // length 
    dataBuffer.writeShort(4); 
    dataBuffer.writeShort(8); 
    dataBuffer.writeShort(600); // Options.width 
    dataBuffer.writeShort(1024); // Options.height 
    dataBuffer.writeShort(0xca01); 
    dataBuffer.writeShort(0xaa03); 
    dataBuffer.writeInt(0x0409); //Options.keylayout, default English/US - fixed 
    dataBuffer.writeInt(2600); // or 0ece 
    dataBuffer.writeBytes(b3); 
    // // client 
    // build? we 
    // are 2600 
    // compatible 
    // :-) 
    /* Unicode name of client, padded to 32 bytes */ 
    var targetPos:int=dataBuffer.position+32; // to account for padding 
    dataBuffer.writeMultiByte("myhost.ath.cx".toLocaleUpperCase(), "UTF-16"); 
    // buffer.outUnicodeString(Options.hostname.toUpperCase(), hostlen); 
    // apparently encoding is used "Unicode" that is UTF-16. If that will not work, set UTF-8 here 
    // and by all means check what is on the wire when you connect via conventional RDP 

    dataBuffer.position = targetPos; 
    // this seems to be your mistake in converting position truncate, 
    // as position after writing already accounts for the writing been processed. 
    // This line alone can be the source of size discrepancy you observe. 
    dataBuffer.writeInt(4); 
    dataBuffer.writeInt(0); 
    dataBuffer.writeInt(12); 
    dataBuffer.position = dataBuffer.position + 64; // /* reserved? 4 + 12 doublewords */ 
    // note, if the position wouldn't shift forward, write zeroes manually 
    dataBuffer.writeShort(0xca01); // out_uint16_le(s, 0xca01); 
    dataBuffer.writeShort(1); 
    if (true) //Options.use_rdp5) 
    { 
     dataBuffer.writeInt(0); // out_uint32(s, 0); 
     dataBuffer.writeByte(24); // out_uint8(s, g_server_bpp); 
     dataBuffer.writeShort(0x0700); // out_uint16_le(s, 0x0700); 
     dataBuffer.writeByte(0); // out_uint8(s, 0); 
     dataBuffer.writeInt(1); // out_uint32_le(s, 1); 
     dataBuffer.position = dataBuffer.position + 64; 
     dataBuffer.writeShort(SEC_TAG_CLI_4); // out_uint16_le(s, 
     // SEC_TAG_CLI_4); 
     dataBuffer.writeShort(12); // out_uint16_le(s, 12); 
     dataBuffer.writeInt(0xd); // out_uint32_le(s, 
     // g_console_session 
     // ? 
     // 0xb 
     // : 
     // 9); 
     // the comments say 9, but the code says 0xd - leaving 0xd in place 
     // Options.console_session is hardcoded false 
     dataBuffer.writeInt(0); // out_uint32(s, 0); 
    } 
    // Client encryption settings // 
    dataBuffer.writeShort(SEC_TAG_CLI_CRYPT); 
    dataBuffer.writeShort(12); // length 
    // if(Options.use_rdp5) dataBuffer.setLittleEndian32(Options.encryption ? 
    // 0x1b : 0); // 128-bit encryption supported 
    // else 
    dataBuffer.writeInt(true ? (false ? 0xb : 0x3) : 0); 
    dataBuffer.writeInt(0); // unknown 
    if (true && (num_channels > 0)) { 
     trace(("num_channels is", num_channels)); 
     dataBuffer.writeShort(SEC_TAG_CLI_CHANNELS); // out_uint16_le(s, 
     // SEC_TAG_CLI_CHANNELS); 
     dataBuffer.writeShort(num_channels * 12 + 8); // out_uint16_le(s, 
     // g_num_channels 
     // * 12 
     // + 8); 
     // // 
     // length 
     dataBuffer.writeInt(num_channels); // out_uint32_le(s, 
     // g_num_channels); 
     // // number of 
     // virtual 
     // channels 
     for (var i: int = 0; i < num_channels; i++) { 
      targetPos=dataBuffer.position+8; // account for padding/truncation 
      dataBuffer.writeMultiByte("testtes" + i, "ascii"); //, 8); // out_uint8a(s, 
      // g_channels[i].name, 
      // 8); 
      dataBuffer.position=targetPos; 
      dataBuffer.writeInt(0x00000040); // out_uint32_be(s, 
      // g_channels[i].flags); 
      // writing big-endian 0x40000000 
     } 
    } 
    trace("sendMCSData: Data buffer length is",dataBuffer.length); // debug 
    return dataBuffer; 
} 

Espero que esto ayude.

Cuestiones relacionadas