Próbuję zalogować się do RDP przy użyciu AS3 (powietrze). Radzę sobie dobrze, biorąc pod uwagę brak zasobów, aby zrozumieć rzeczywisty proces.
Przekroczyłem początkową nazwę użytkownika wysyłającą, otrzymałem odpowiedź z serwera i jestem teraz na początkowym żądaniu połączenia.
Wysyłam wszystkie swoje dane i podczas podsłuchiwania ruchu widzę, że netmon poprawnie rozpoznaje, jaki rodzaj pakietu wysyłam (t125). Ja nie jest odłączony przez RDP i wysłać ack
paczkę - ale nie otrzymam odpowiedź, że spodziewam.
Odnosiłem się do tego connectoid
, który jest klientem RDP typu open source. W kodzie połączenia utknąłem tam, gdzie piszą mieszankę małych i dużych liczb całkowitych.
Kiedy patrzę na ograniczone przykłady (bardziej jak zrzuty pakietów), widzę, że długość połączenia dla tego procesu wynosi 412, ale moja bytearray
jest bardziej podobna do 470.
Przekonwertowałem connectoid
metody na to, co uważam za poprawne, ale w przypadku mieszanki typu endian nadal nie jestem pewien.
Przepraszam, jeśli to jest zniekształcone, ale staram się jak najlepiej pomóc Ci pomóc. Dołączę kod pokazujący, co próbowałem zrobić podczas konwersji.
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;
}
źródło
Odpowiedzi:
Najwyraźniej większość bufora to little endian, ale oczekuje się, że kilka bajtów na jego początku będzie 16-bitowymi liczbami big endian (krótkimi). Oznacza to, że musisz zapisywać dane w little endian, tak jakby były interpretowane jako big endian. Aby przekonwertować dane z big endian na little endian, możesz użyć tymczasowego
ByteArray
, którego endian jest ustawiony na big, zapisać w nim dane, a następnie wywołaćwriteBytes()
główną tablicę buforów, a następnie wyczyścić tymczasową tablicę big endian. Zapisywanie stałych można wykonać ręcznie, ponieważ możesz samodzielnie zmienić kolejność bajtów, powiedzmy, że pisząc0x0005
w big endian jako short, po prostu piszesz0x0500
jako little endian. Najwyraźniej napisałeś kod z obcymidataBuffer
endian jest duży, więc znasz tę technikę. Mimo to lepiej, jeśli utworzysz po prostu właściwośćdataBuffer
w funkcji. Poniżej próbuję naprawić Twój kod na podstawieconnectoid
pobranego przeze mnie kodu, aby zwrócił poprawnie uformowanyByteArray
endian, który jest mały - ma to znaczenie tylko wtedy, gdy odczytujesz z niego uporządkowane dane, a nie bajty.Mam nadzieję że to pomoże.
źródło