[actionscript-3] AS3을 사용하여 RDP에 로그인하려고

AS3 (air)을 사용하여 RDP에 로그인하려고합니다. 실제 프로세스를 이해하기 위해 리소스가 부족하다는 점을 고려하여 확인하고 있습니다.

초기 발신 사용자 이름을 지난 후 서버로부터 응답을 받았으며 이제 초기 요청 연결 상태입니다.

나는 모든 데이터를 보내고 있으며 트래픽을 스니핑 할 때 netmon이 어떤 종류의 패킷을 보내고 있는지 정확하게 인식하고 있음을 알 수 있습니다 (t125). 나는 하지 RDP로 연결되고 그들이는 전송 ack패킷을 -하지만 난 기대하고 있다는 응답을받지 않습니다.

connectoid오픈 소스 RDP 클라이언트 인와 상호 참조하고 있습니다. 연결 코드에서 작은 엔디안 정수와 큰 엔디안 정수를 혼합하여 쓰는 위치에 붙어 있습니다.

제한된 예제 (패킷 덤프와 같은)를 볼 때이 프로세스의 연결 길이는 412이지만 내 bytearray것은 470과 같습니다.

나는 회심했다 connectoid 옳다고 믿는 것으로 방법을 했지만, 엔디안 유형의 혼합으로 여전히 확실하지 않습니다.

문제가 발생하면 죄송하지만 최선을 다해 도와 드리겠습니다. 변환에서 시도한 것을 보여주는 코드를 첨부하겠습니다.

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



답변

분명히 버퍼의 대부분은 리틀 엔디안이지만 시작시 몇 바이트는 16 비트 (짧음)의 큰 엔디안 수 일 것으로 예상됩니다. 즉, 빅 엔디안으로 해석되는 것처럼 리틀 엔디안으로 데이터를 작성해야합니다. 빅 엔디안에서 리틀 엔디안으로 데이터를 변환하려면 ByteArray엔디안이 big으로 설정된 임시 를 사용하여 데이터를 쓴 다음 writeBytes()기본 버퍼 배열 을 호출 한 다음 임시 빅 엔디안 배열을 지울 수 있습니다. 바이트 순서를 직접 바꿀 수 있기 때문에 상수를 직접 작성할 수 있습니다. 예를 들어 0x0005빅 엔디안을 짧게 쓰는 경우 리틀 엔디안을 쓰는 0x0500것입니다. 외견 상으로 코드를 작성한 것 같습니다.dataBuffer엔디안이 크면이 기술을 알고 있습니다. 그럼에도 불구 dataBuffer하고 함수에서 적절한 것을 생성하는 것이 좋습니다 . 내가 connectoid다운로드 한 코드를 기준으로 아래에서 코드를 수정하려고 하므로 ByteArray엔디안이 적어 제대로 구성된 형식 을 반환 합니다. 바이트를 읽을 때가 아니라 순서가 지정된 데이터를 읽는 경우에만 중요합니다.

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

도움이 되었기를 바랍니다.


답변