Actionscript 3 正在尝试使用AS3登录到RDP
我正在尝试使用AS3(air)登录RDP。考虑到缺乏了解实际流程的资源,我做得还不错 我已经通过了最初的发送用户名,收到了来自服务器的响应,我现在处于初始请求连接状态 我正在发送我的所有数据,当嗅探流量时,我看到netmon正确识别我正在发送的数据包类型(t125)。RDP没有断开我的连接,他们发送了一个Actionscript 3 正在尝试使用AS3登录到RDP,actionscript-3,air,rdp,vnc,Actionscript 3,Air,Rdp,Vnc,我正在尝试使用AS3(air)登录RDP。考虑到缺乏了解实际流程的资源,我做得还不错 我已经通过了最初的发送用户名,收到了来自服务器的响应,我现在处于初始请求连接状态 我正在发送我的所有数据,当嗅探流量时,我看到netmon正确识别我正在发送的数据包类型(t125)。RDP没有断开我的连接,他们发送了一个ack数据包,但我没有收到预期的响应 我一直在交叉引用connectoid,它是一个开源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;
}
公共函数sendMcsData():void{
跟踪(“Secure.sendMcsData”);
var num_通道:int=2;
//RdpPacket_本地化数据缓冲=新RdpPacket_本地化(512);
var hostlen:int=2*“myhostaddress.ath.cx”.length;
如果(hostlen>30){
hostlen=30;
}
变量长度:int=158;
长度+=76+12+4;
长度+=num_通道*12+8;
dataBuffer.writeShort(5);/*未知*/
数据缓冲写入端口(0x14);
dataBuffer.writeByte(0x7c);//集合8是写入字节//write short是setbigendian 16//
数据缓冲写入端口(1);
dataBuffer.writeShort(长度| 0x8000);//剩余长度
dataBuffer.writeShort(8);//长度?
数据缓冲写入端口(16);
数据缓冲写入字节(0);
变量b1:ByteArray=新的ByteArray();
b1.endian=endian.LITTLE_endian;
b1.写端口(0xc001);
数据缓冲写入字节(b1);
数据缓冲写入字节(0);
变量b2:ByteArray=新的ByteArray();
b2.endian=endian.LITTLE_endian;
b2.写入(0x61637544);
数据缓冲写入字节(b2);
//dataBuffer.setLittleEndian32(0x61637544);/“Duca”?!
dataBuffer.writeShort(长度-14 | 0x8000);//剩余长度
变量b3:ByteArray=新的ByteArray();
b3.endian=endian.LITTLE_endian;
//客户信息
b3.写端口(第二标签信息);
b3.writeShort(true?212:136);//长度
b3.书写体(真?4:1);
b3.书面培训(8);
b3.书面培训(600);
b3.写端口(1024);
b3.写端口(0xca01);
b3.写端口(0xaa03);
b3.writeInt(0x809);//应该是option.keybaortd布局刚刚猜到1
b3.writeInt(true?2600:419);//或0ece
数据缓冲写入字节(b3);
////客户端
//建造?我们
//是2600
//兼容的
// :-)
/*客户端的Unicode名称,填充为32字节*/
writeMultiByte(“myhost.ath.cx”.toLocaleUpperCase(),“ISO”);
dataBuffer.position=dataBuffer.position+(30-“myhost.ath.cx”.tolocaluppercase()
.长度);
变量b4:ByteArray=新的ByteArray();
b4.endian=endian.LITTLE_endian;
b4.书面通知(4);
b4.书面记录(0);
b4.书面通知(12);
数据缓冲写入字节(b4);
dataBuffer.position=dataBuffer.position+64;/*保留?4+12个双字*/
变量b5:ByteArray=新的ByteArray();
b5.endian=endian.LITTLE_endian;
b5.writeShort(0xca01);//out\uint16\u le(s,0xca01);
b5.书写运动(真?1:0);
if(true)//选项。使用
{
b5.writeInt(0);//out_int32(s,0);
b5.writeByte(24);//out\u uint8(s,g\u server\u bpp);
b5.writeShort(0x0700);//out(s,0x0700);
b5.writeByte(0);//out_uint8(s,0);
b5.书面材料(1);//书面材料(s,1);
b5.position=b5.position+64;
b5.writeShort(第4节)//out,
//第4节(标签);
b5.writeShort(12);//out_uint16_le(s,12);
b5.writeInt(false?0xb:0xd);//out\u uint32\u le(s,
//g_控制台_会话
// ?
//0xb
// :
// 9);
b5.writeInt(0);//out_int32(s,0);
}
//客户端加密设置//
b5.写端口(SEC_TAG_CLI_CRYPT);
b5.writeShort(真?12:8);//长度
//if(Options.use_rdp5)dataBuffer.setLittleEndian32(Options.encryption?
//0x1b:0);//支持128位加密
//否则
b5.writeInt(真?(假?0xb:0x3):0);
if(true)b5.writeInt(0);//未知
如果(真&(通道数>0)){
跟踪((“num_通道是”+num_通道));
b5.writeShort(SEC_TAG_CLI_CHANNELS);//out_uint16_le,
//SEC_TAG_CLI_CHANNELS);
b5.writeShort(num_channels*12+8);//out_uint16_le(s),
//g_num_通道
// * 12
// + 8);
// //
//长度
b5.writeInt(num_channels);//out_uint32_le(s,
//g_num_通道);
////数量
//虚拟的
//渠道
数据缓冲写入字节(b5);
跟踪(“b5是bigendin”+(b5.endian==endian.BIG_endian));
对于(变量i:int=0;i
显然,缓冲区的大部分是小端数,但其开头的几个字节预计是16位(短)的大端数。这意味着,您必须以小尾端编写数据,就像它将被解释为大尾端一样。为了将数据从big-endian转换为little-endian,可以使用tempora
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;
}