2012-03-18 95 views
146

我想使用AS3(空氣)登錄到RDP。考慮到缺乏資源來理解實際過程,我做得很好。試圖使用AS3登錄到RDP

我已經超過了最初的發送用戶名,從服務器收到響應,並且我現在處於初始請求連接。

我正在發送所有數據,當嗅探流量時,我發現netmon正在正確識別我正在發送什麼類型的數據包(t125)。我是而不是被RDP斷開,他們發送ack數據包 - 但我沒有收到我期待的回覆。

我一直在與connectoid交叉引用,這是一個開源的RDP客戶端。在連接代碼中,我被困在他們編寫小和大端整數混合的地方。

當我看到有限的例子在那裏(更像是數據包轉儲),我看到了這個過程連接長度爲412,但我bytearray更像是470

我已經轉換connectoid方法是什麼我相信是正確的,但是用endian類型的混合,我仍然不確定。

對不起,如果這是亂碼,但我正在盡我所能來幫助你來幫助我。我將附上一些代碼,顯示我在轉換中嘗試做的事情。

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

您能否從已知良好的RDP客戶端捕獲有問題的數據包,並與您感興趣的數據包進行比較?這可能是您對字節數組的一部分進行編碼的一個錯誤。 – Ben 2014-04-10 16:50:20

+0

您能詳細說明您對「初始請求連接」的含義嗎?最初的請求應該已經通過您的登錄,所以目前還不清楚您在什麼狀態下卡住。您已發送連接請求(0xe0)並收到您的確認(0xd0),現在您處於「連接初始」階段?還是在事件的後面呢?您在上述代碼中生成的數據包是「MCS:connect-initial」數據包嗎? – 2015-01-19 20:15:46

+2

愚蠢的問題,但你有沒有嘗試手動RDP進入該框看到它的作品?可能會發生某些事情來阻止登錄,如橫幅「此機器僅供授權使用,但僅限於blah blah」 – 2015-03-18 13:30:24

回答

3

顯然,大多數的緩衝區是小端,但在它的開始幾個字節預計是16位(短)的大端號碼。這意味着,你必須以小端編寫數據,就好像它將被解釋爲大端。爲了將數據從大端數據轉換爲小端數據,可以使用一個臨時的ByteArray,它的端序設置爲大,在其中寫入數據,然後在主緩衝區數組上調用writeBytes(),然後清除臨時大端數組。寫入常量可以手動完成,因爲你可以自己移動字節順序,比如說當你在寫大寫字母0x0005時,你可以寫0x0500作爲小寫字母。你似乎寫了代碼與無關dataBuffer與endian很大,所以你知道這種技術。不過,最好在函數中生成一個合適的dataBuffer。我正在嘗試根據我已下載的connectoid代碼修復您的代碼,以便它將返回一個正確形成的ByteArray,並且endian很少 - 如果您要從中讀取有序數據,而不是讀取字節。

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; 
} 

希望這會有所幫助。