-
Notifications
You must be signed in to change notification settings - Fork 240
/
Copy pathncrack_rdp.cc
5237 lines (4126 loc) · 137 KB
/
ncrack_rdp.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/***************************************************************************
* ncrack_rdp.cc -- ncrack module for RDP *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2019 Insecure.Com LLC ("The Nmap *
* Project"). Nmap is also a registered trademark of the Nmap Project. *
* This program is free software; you may redistribute and/or modify it *
* under the terms of the GNU General Public License as published by the *
* Free Software Foundation; Version 2 ("GPL"), BUT ONLY WITH ALL OF THE *
* CLARIFICATIONS AND EXCEPTIONS DESCRIBED HEREIN. This guarantees your *
* right to use, modify, and redistribute this software under certain *
* conditions. If you wish to embed Nmap technology into proprietary *
* software, we sell alternative licenses (contact sales@nmap.com). *
* Dozens of software vendors already license Nmap technology such as *
* host discovery, port scanning, OS detection, version detection, and *
* the Nmap Scripting Engine. *
* *
* Note that the GPL places important restrictions on "derivative works", *
* yet it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we interpret that term as broadly as copyright law *
* allows. For example, we consider an application to constitute a *
* derivative work for the purpose of this license if it does any of the *
* following with any software or content covered by this license *
* ("Covered Software"): *
* *
* o Integrates source code from Covered Software. *
* *
* o Reads or includes copyrighted data files, such as Nmap's nmap-os-db *
* or nmap-service-probes. *
* *
* o Is designed specifically to execute Covered Software and parse the *
* results (as opposed to typical shell or execution-menu apps, which will *
* execute anything you tell them to). *
* *
* o Includes Covered Software in a proprietary executable installer. The *
* installers produced by InstallShield are an example of this. Including *
* Nmap with other software in compressed or archival form does not *
* trigger this provision, provided appropriate open source decompression *
* or de-archiving software is widely available for no charge. For the *
* purposes of this license, an installer is considered to include Covered *
* Software even if it actually retrieves a copy of Covered Software from *
* another source during runtime (such as by downloading it from the *
* Internet). *
* *
* o Links (statically or dynamically) to a library which does any of the *
* above. *
* *
* o Executes a helper program, module, or script to do any of the above. *
* *
* This list is not exclusive, but is meant to clarify our interpretation *
* of derived works with some common examples. Other people may interpret *
* the plain GPL differently, so we consider this a special exception to *
* the GPL that we apply to Covered Software. Works which meet any of *
* these conditions must conform to all of the terms of this license, *
* particularly including the GPL Section 3 requirements of providing *
* source code and allowing free redistribution of the work as a whole. *
* *
* As another special exception to the GPL terms, the Nmap Project grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. *
* *
* The Nmap Project has permission to redistribute Npcap, a packet *
* capturing driver and library for the Microsoft Windows platform. *
* Npcap is a separate work with it's own license rather than this Nmap *
* license. Since the Npcap license does not permit redistribution *
* without special permission, our Nmap Windows binary packages which *
* contain Npcap may not be redistributed without special permission. *
* *
* Any redistribution of Covered Software, including any derived works, *
* must obey and carry forward all of the terms of this license, including *
* obeying all GPL rules and restrictions. For example, source code of *
* the whole work must be provided and free redistribution must be *
* allowed. All GPL references to "this License", are to be treated as *
* including the terms and conditions of this license text as well. *
* *
* Because this license imposes special exceptions to the GPL, Covered *
* Work may not be combined (even as part of a larger work) with plain GPL *
* software. The terms, conditions, and exceptions of this license must *
* be included as well. This license is incompatible with some other open *
* source licenses as well. In some cases we can relicense portions of *
* Nmap or grant special permissions to use it in other open source *
* software. Please contact fyodor@nmap.org with any such requests. *
* Similarly, we don't incorporate incompatible open source software into *
* Covered Software without special permission from the copyright holders. *
* *
* If you have any questions about the licensing restrictions on using *
* Nmap in other works, we are happy to help. As mentioned above, we also *
* offer an alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing support and updates. They also fund the continued *
* development of Nmap. Please email sales@nmap.com for further *
* information. *
* *
* If you have received a written license agreement or contract for *
* Covered Software stating terms other than these, you may choose to use *
* and redistribute Covered Software under those terms instead of these. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes. *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to the dev@nmap.org mailing list for possible incorporation into the *
* main distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, or checking them into the Nmap *
* source code repository, it is understood (unless you specify *
* otherwise) that you are offering the Nmap Project the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because *
* the inability to relicense code has caused devastating problems for *
* other Free Software projects (such as KDE and NASM). We also *
* occasionally relicense the code to third parties as discussed above. *
* If you wish to specify special license conditions of your *
* contributions, just say so when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Nmap *
* license file for more details (it's in a COPYING file included with *
* Nmap, and also available from https://svn.nmap.org/nmap/COPYING) *
* *
***************************************************************************/
#include "ncrack.h"
#include "nsock.h"
#include "NcrackOps.h"
#include "Service.h"
#include "modules.h"
#include "crypto.h"
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <list>
#include <map>
using namespace std;
bool rdp_discmap_initialized = false;
map <int, const char *> rdp_discmap;
#ifdef WIN32
#ifndef __attribute__
# define __attribute__(x)
#endif
# pragma pack(1)
#endif
#define RDP_TIMEOUT 20000
#define COOKIE_USERNAME "NCRACK_USER"
extern NcrackOps o;
extern void ncrack_read_handler(nsock_pool nsp, nsock_event nse, void *mydata);
extern void ncrack_write_handler(nsock_pool nsp, nsock_event nse, void *mydata);
extern void ncrack_module_end(nsock_pool nsp, void *mydata);
typedef struct stream_struct
{
u_char *p;
u_char *end;
u_char *data;
unsigned int size;
} *stream;
typedef struct rdp_state {
uint8_t crypted_random[256];
uint8_t sign_key[16];
uint8_t encrypt_key[16];
uint8_t decrypt_key[16];
uint8_t encrypt_update_key[16];
uint8_t decrypt_update_key[16];
RC4_KEY rc4_encrypt_key;
RC4_KEY rc4_decrypt_key;
int rc4_keylen;
int encrypt_use_count;
int decrypt_use_count;
uint32_t server_public_key_length;
uint16_t mcs_userid;
uint32_t shareid;
u_char *rdp_packet;
u_char *rdp_next_packet;
u_char *rdp_packet_end;
uint16_t packet_len;
stream assembled[0x0F];
int login_result;
/*
* hack to find pattern for RDPv5 to determine when
* there is an authentication failure, since Windows
* does not explicitly send a status message about that
* if we detect a certain number of patterns a specific number
* of times, then we can assume that this is a failure
*/
int login_pattern_fail;
int rdp_version; /* 4, 5, 6 */
uint8_t order_state_type;
typedef struct order_memblt {
uint8_t color_table;
uint8_t cache_id;
int16_t x;
int16_t y;
int16_t cx;
int16_t cy;
uint8_t opcode;
int16_t srcx;
int16_t srcy;
uint16_t cache_idx;
} order_memblt;
bool win7_vista_fingerprint;
order_memblt memblt;
} rdp_state;
static int rdp_loop_read(nsock_pool nsp, Connection *con);
static void rdp_iso_connection_request(Connection *con);
static int rdp_iso_connection_confirm(Connection *con);
static void rdp_mcs_connect(Connection *con);
static int rdp_mcs_connect_response(Connection *con);
static int rdp_get_crypto(Connection *con, u_char *p);
static void rdp_mcs_erect_domain_request(Connection *con);
static void rdp_iso_data(Connection *con, uint16_t datalen);
static void rdp_mcs_attach_user_request(Connection *con);
static int rdp_mcs_attach_user_confirm(Connection *con);
static int rdp_iso_recv_data(Connection *con);
static void rdp_mcs_channel_join_request(Connection *con, uint16_t channel_id);
static int rdp_mcs_channel_join_confirm(Connection *con);
static void rdp_encrypt_data(Connection *con, uint8_t *data, uint32_t datalen,
uint32_t flags);
static void rdp_mcs_data(Connection *con, uint16_t datalen);
static void rdp_security_exchange(Connection *con);
static void rdp_client_info(Connection *con);
static u_char *rdp_mcs_recv_data(Connection *con, uint16_t *channel, bool *fastpath, uint8_t *fastpath_header);
static u_char *rdp_secure_recv_data(Connection *con, bool *fastpath);
static u_char *rdp_recv_data(Connection *con, uint8_t *pdu_type);
static void rdp_data(Connection *con, Buf *data, uint8_t pdu_type);
static void rdp_synchronize(Connection *con);
static void rdp_control(Connection *con, uint16_t action);
static void rdp_confirm_active(Connection *con);
static void rdp_input_msg(Connection *con, uint32_t time, uint16_t message_type,
uint16_t device_flags, uint16_t param1, uint16_t param2);
//static void rdp_scancode_msg(Connection *con, uint32_t time, uint16_t flags,
// uint8_t scancode);
static void rdp_demand_active_confirm(Connection *con, u_char *p);
static int rdp_parse_rdpdata_pdu(Connection *con, u_char *p);
static char *rdp_disc_reason(uint32_t code);
static void rdp_fonts_send(Connection *con, uint16_t sequence);
static void rdp_disconnect(Connection *con);
static u_char *rdp_iso_recv_data_loop(Connection *con, bool *fastpath, uint8_t *fastpath_header);
static void rdp_parse_update_pdu(Connection *con, u_char *p);
static void rdp_parse_orders(Connection *con, u_char *p, uint16_t num);
//static void rdp_parse_second_order(u_char *p);
static u_char *rdp_parse_destblt(u_char *p, uint32_t params, bool delta);
static u_char *rdp_coord(u_char *p, bool delta, int16_t *coord = NULL);
static u_char *rdp_parse_brush(u_char *p, uint32_t params);
static u_char *rdp_parse_patblt(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_screenblt(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_line(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_pen(u_char *p, uint32_t params);
static u_char *rdp_color(u_char *p);
static u_char *rdp_parse_rect(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_desksave(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_memblt(u_char *p, uint32_t params, bool delta, rdp_state *info);
static u_char *rdp_parse_triblt(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_polygon(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_polygon2(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_ellipse(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_ellipse2(u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_text2(Connection *con, u_char *p, uint32_t params, bool delta);
static u_char *rdp_parse_ber(u_char *p, int tag, int *length);
static u_char *rdp_process_fastpath(Connection *con, u_char *p);
//static u_char *rdp_parse_bitmap_update(u_char *p);
static void rdp_parse_bmpcache2(Connection *con, u_char *p, uint16_t sec_flags, bool compressed);
/* RDP PDU codes */
enum RDP_PDU_TYPE
{
RDP_PDU_DEMAND_ACTIVE = 1,
RDP_PDU_CONFIRM_ACTIVE = 3,
RDP_PDU_REDIRECT = 4, /* Standard Server Redirect */
RDP_PDU_DEACTIVATE = 6,
RDP_PDU_DATA = 7,
RDP_PDU_ENHANCED_REDIRECT = 10 /* Enhanced Server Redirect */
};
enum RDP_DATA_PDU_TYPE
{
RDP_DATA_PDU_UPDATE = 2,
RDP_DATA_PDU_CONTROL = 20,
RDP_DATA_PDU_POINTER = 27,
RDP_DATA_PDU_INPUT = 28,
RDP_DATA_PDU_SYNCHRONISE = 31,
RDP_DATA_PDU_BELL = 34,
RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 35,
RDP_DATA_PDU_LOGON = 38, /* PDUTYPE2_SAVE_SESSION_INFO */
RDP_DATA_PDU_FONT2 = 39,
RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
RDP_DATA_PDU_DISCONNECT = 47,
RDP_DATA_PDU_AUTORECONNECT_STATUS = 50
};
enum RDP_UPDATE_PDU_TYPE
{
RDP_UPDATE_ORDERS = 0,
RDP_UPDATE_BITMAP = 1,
RDP_UPDATE_PALETTE = 2,
RDP_UPDATE_SYNCHRONISE = 3
};
#define FASTPATH_MULTIFRAGMENT_MAX_SIZE 65535UL
#define FASTPATH_OUTPUT_ENCRYPTED 0x2
#define FASTPATH_OUTPUT_COMPRESSION_USED (0x2 << 6)
#define FASTPATH_FRAGMENT_SINGLE (0x0 << 4)
#define FASTPATH_FRAGMENT_LAST (0x1 << 4)
#define FASTPATH_FRAGMENT_FIRST (0x2 << 4)
#define FASTPATH_FRAGMENT_NEXT (0x3 << 4)
#define RDP_MPPC_COMPRESSED 0x20
#define FASTPATH_UPDATETYPE_ORDERS 0x0
#define FASTPATH_UPDATETYPE_BITMAP 0x1
#define FASTPATH_UPDATETYPE_PALETTE 0x2
#define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3
#define FASTPATH_UPDATETYPE_SURFCMDS 0x4
#define FASTPATH_UPDATETYPE_PTR_NULL 0x5
#define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6
#define FASTPATH_UPDATETYPE_PTR_POSITION 0x8
#define FASTPATH_UPDATETYPE_COLOR 0x9
#define FASTPATH_UPDATETYPE_CACHED 0xA
#define FASTPATH_UPDATETYPE_POINTER 0xB
#define RDP_ORDER_STANDARD 0x01
#define RDP_ORDER_SECONDARY 0x02
#define RDP_ORDER_BOUNDS 0x04
#define RDP_ORDER_CHANGE 0x08
#define RDP_ORDER_DELTA 0x10
#define RDP_ORDER_LASTBOUNDS 0x20
#define RDP_ORDER_SMALL 0x40
#define RDP_ORDER_TINY 0x80
enum RDP_ORDER_TYPE
{
RDP_ORDER_DESTBLT = 0,
RDP_ORDER_PATBLT = 1,
RDP_ORDER_SCREENBLT = 2,
RDP_ORDER_LINE = 9,
RDP_ORDER_RECT = 10,
RDP_ORDER_DESKSAVE = 11,
RDP_ORDER_MEMBLT = 13,
RDP_ORDER_TRIBLT = 14,
RDP_ORDER_POLYGON = 20,
RDP_ORDER_POLYGON2 = 21,
RDP_ORDER_POLYLINE = 22,
RDP_ORDER_ELLIPSE = 25,
RDP_ORDER_ELLIPSE2 = 26,
RDP_ORDER_TEXT2 = 27
};
enum RDP_SECONDARY_ORDER_TYPE
{
RDP_ORDER_RAW_BMPCACHE = 0,
RDP_ORDER_COLCACHE = 1,
RDP_ORDER_BMPCACHE = 2,
RDP_ORDER_FONTCACHE = 3,
RDP_ORDER_RAW_BMPCACHE2 = 4,
RDP_ORDER_BMPCACHE2 = 5,
RDP_ORDER_BRUSHCACHE = 7
};
/* RDP_BMPCACHE2_ORDER */
#define ID_MASK 0x0007
#define MODE_MASK 0x0038
#define SQUARE 0x0080
#define PERSIST 0x0100
#define FLAG_51_UNKNOWN 0x0800
#define MODE_SHIFT 3
#define LONG_FORMAT 0x80
#define BUFSIZE_MASK 0x3FFF
/* ISO PDU codes */
enum ISO_PDU_CODE
{
ISO_PDU_CR = 0xE0, /* Connection Request */
ISO_PDU_CC = 0xD0, /* Connection Confirm */
ISO_PDU_DR = 0x80, /* Disconnect Request */
ISO_PDU_DT = 0xF0, /* Data */
ISO_PDU_ER = 0x70 /* Error */
};
enum RDP_INPUT_DEVICE
{
RDP_INPUT_SYNCHRONIZE = 0,
RDP_INPUT_CODEPOINT = 1,
RDP_INPUT_VIRTKEY = 2,
RDP_INPUT_SCANCODE = 4,
RDP_INPUT_MOUSE = 0x8001
};
enum RDP_CONTROL_PDU_TYPE
{
RDP_CTL_REQUEST_CONTROL = 1,
RDP_CTL_GRANT_CONTROL = 2,
RDP_CTL_DETACH = 3,
RDP_CTL_COOPERATE = 4
};
#define RDP_KEYPRESS 0
#define PERF_DISABLE_FULLWINDOWDRAG 0x02
#define PERF_DISABLE_MENUANIMATIONS 0x04
#define PERF_ENABLE_FONT_SMOOTHING 0x80
#define CS_CORE 0xC001;
#define CS_SECURITY 0xC002;
#define CS_NET 0xC003;
#define CS_CLUSTER 0xC004;
#define MCS_CONNECT_INITIAL 0x7f65
#define MCS_CONNECT_RESPONSE 0x7f66
#define MCS_GLOBAL_CHANNEL 1003
#define MCS_USERCHANNEL_BASE 1001
#define MCS_SDIN 26 /* Send Data Indication */
#define MCS_DPUM 8 /* Disconnect Provider Ultimatum */
#define BER_TAG_BOOLEAN 1
#define BER_TAG_INTEGER 2
#define BER_TAG_OCTET_STRING 4
#define BER_TAG_RESULT 10
#define MCS_TAG_DOMAIN_PARAMS 0x30
/* Virtual channel options */
#define CHANNEL_OPTION_INITIALIZED 0x80000000
#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
#define SEC_TAG_SRV_INFO 0x0c01
#define SEC_TAG_SRV_CRYPT 0x0c02
#define SEC_TAG_SRV_CHANNELS 0x0c03
#define SEC_TAG_PUBKEY 0x0006
#define SEC_TAG_KEYSIG 0x0008
#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
#define SEC_CLIENT_RANDOM 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_LOGON_INFO 0x0040
#define SEC_LICENCE_NEG 0x0080
#define RDP_LOGON_AUTO 0x0008
#define RDP_LOGON_NORMAL 0x0033
enum states { RDP_INIT, RDP_CON, RDP_MCS_RESP, RDP_MCS_AURQ, RDP_MCS_AUCF,
RDP_MCS_CJ_USER, RDP_SEC_EXCHANGE, RDP_CLIENT_INFO,
RDP_DEMAND_ACTIVE, RDP_DEMAND_ACTIVE_SYNC, RDP_DEMAND_ACTIVE_INPUT_SYNC,
RDP_DEMAND_ACTIVE_FONTS, RDP_LOOP };
enum login_results { LOGIN_INIT, LOGIN_FAIL, LOGIN_ERROR, LOGIN_SUCCESS };
/* RDP header */
typedef struct rdp_hdr_data {
uint16_t length;
uint16_t code;
uint16_t mcs_userid;
uint32_t shareid;
uint8_t pad;
uint8_t streamid;
uint16_t remaining_length;
uint8_t type;
uint8_t compress_type;
uint16_t compress_len;
rdp_hdr_data() {
code = RDP_PDU_DATA | 0x10;
pad = 0;
streamid = 1;
compress_type = 0;
compress_len = 0;
}
} __attribute__((__packed__)) rdp_hdr_data;
typedef struct rdp_input_event {
uint16_t num_events;
uint16_t pad;
uint32_t time;
uint16_t message_type;
uint16_t device_flags;
uint16_t param1;
uint16_t param2;
rdp_input_event() {
num_events = 1;
pad = 0;
}
} __attribute__((__packed__)) rdp_input_event;
typedef struct rdp_fonts {
uint16_t num_fonts;
uint16_t pad;
uint16_t seq;
uint16_t entry_size;
rdp_fonts() {
num_fonts = 0;
pad = 0;
entry_size = 0x32;
}
} __attribute__((__packed__)) rdp_fonts;
typedef struct rdp_sync {
uint16_t type;
uint16_t type2;
rdp_sync() {
type = 1;
type2 = 1002;
}
} __attribute__((__packed__)) rdp_sync;
typedef struct rdp_ctrl {
uint16_t action;
uint16_t user_id;
uint32_t control_id;
rdp_ctrl() {
user_id = 0;
control_id = 0;
}
} __attribute__((__packed__)) rdp_ctrl;
/*
* Client Confirm Active PDU
* http://msdn.microsoft.com/en-us/library/cc240487%28v=PROT.10%29.aspx
*/
#define RDP_SOURCE "MSTSC"
typedef struct rdp_confirm_active_pdu {
uint16_t length;
uint16_t type;
uint16_t mcs_userid;
uint32_t shareid;
uint16_t userid;
uint16_t source_len;
uint16_t caplen;
u_char source[sizeof(RDP_SOURCE)];
uint16_t num_caps;
uint8_t pad[2];
rdp_confirm_active_pdu() {
type = RDP_PDU_CONFIRM_ACTIVE | 0x10;
userid = 0x3ea;
source_len = sizeof(RDP_SOURCE);
memcpy(source, RDP_SOURCE, sizeof(RDP_SOURCE));
num_caps = 16;
memset(&pad, 0, sizeof(pad));
}
} __attribute__((__packed__)) rdp_confirm_active_pdu;
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1 /* generalCapabilitySet in T.128 p.138 */
#define RDP_CAPLEN_GENERAL 0x18
/* extraFlags, [MS-RDPBCGR] 2.2.7.1.1 */
#define FASTPATH_OUTPUT_SUPPORTED 0x0001
#define LONG_CREDENTIALS_SUPPORTED 0x0004
#define AUTORECONNECT_SUPPORTED 0x0008
#define ENC_SALTED_CHECKSUM 0x0010
#define NO_BITMAP_COMPRESSION_HDR 0x0400
typedef struct rdp_general_caps {
uint16_t type;
uint16_t len;
uint16_t os_major;
uint16_t os_minor;
uint16_t protocol_version;
uint16_t pad;
uint16_t compression_type;
uint16_t extra_flags; /* careful with this, might trigger rdp5 */
uint16_t update_cap;
uint16_t remote_unshare_cap;
uint16_t compression_level;
uint8_t refresh_rect;
uint8_t suppress_output;
rdp_general_caps() {
type = RDP_CAPSET_GENERAL;
len = RDP_CAPLEN_GENERAL;
os_major = 1;
os_minor = 3;
protocol_version = 0x200;
pad = 0;
compression_type = 0;
extra_flags = 0;
update_cap = 0;
remote_unshare_cap = 0;
compression_level = 0;
refresh_rect = 0;
suppress_output = 0;
}
} __attribute__((__packed__)) rdp_general_caps;
#define RDP_CAPSET_BITMAP 2
#define RDP_CAPLEN_BITMAP 0x1C
typedef struct rdp_bitmap_caps {
uint16_t type;
uint16_t len;
uint16_t bpp;
uint16_t bpp1;
uint16_t bpp2;
uint16_t bpp3;
uint16_t width;
uint16_t height;
uint16_t pad;
uint16_t allow_resize;
uint16_t compression;
uint8_t high_color_flags;
uint8_t drawing_flags;
uint16_t multiple_rectangle;
uint16_t pad2;
rdp_bitmap_caps() {
type = RDP_CAPSET_BITMAP;
len = RDP_CAPLEN_BITMAP;
bpp = 8;
bpp1 = 1;
bpp2 = 1;
bpp3 = 1;
width = 800;
height = 600;
pad = 0;
allow_resize = 1;
compression = 1;
high_color_flags = 0;
drawing_flags = 0;
multiple_rectangle = 1;
pad2 = 0;
}
} __attribute__((__packed__)) rdp_bitmap_caps;
#define RDP_CAPSET_ORDER 3
#define RDP_CAPLEN_ORDER 0x58
typedef struct rdp_order_caps {
uint16_t type;
uint16_t len;
uint8_t term_desc[20];
uint16_t cache_x;
uint16_t cache_y;
uint16_t pad;
uint16_t max_order;
uint16_t num_fonts;
uint16_t cap_flags;
struct order {
uint8_t dest_blt;
uint8_t pat_blt;
uint8_t screen_blt;
uint8_t mem_blt;
uint8_t tri_blt;
uint8_t pad[3];
uint8_t line1;
uint8_t line2;
uint8_t rect;
uint8_t desksave;
uint8_t pad2;
uint8_t mem_blt2;
uint8_t tri_blt2;
uint8_t pad3[5];
uint8_t polygon1;
uint8_t polygon2;
uint8_t polyline;
uint8_t pad4[2];
uint8_t ellipse1;
uint8_t ellipse2;
uint8_t text2;
uint8_t pad5[4];
order() {
dest_blt = 1;
pat_blt = 1;
screen_blt = 1;
mem_blt = 1;
tri_blt = 0;
memset(&pad, 0, sizeof(pad));
line1 = 1;
line2 = 1;
rect = 1;
desksave = 1;
pad2 = 0;
mem_blt2 = 1;
tri_blt2 = 1;
memset(&pad3, 0, sizeof(pad3));
polygon1 = 1;
polygon2 = 1;
polyline = 1;
memset(&pad4, 0, sizeof(pad4));
ellipse1 = 1;
ellipse2 = 1;
text2 = 1;
memset(&pad5, 0, sizeof(pad5));
}
} __attribute__((__packed__)) order;
uint16_t text_cap_flags;
uint8_t pad2[6];
uint32_t desk_cache_size;
uint32_t unknown1;
uint32_t unknown2;
rdp_order_caps() {
type = RDP_CAPSET_ORDER;
len = RDP_CAPLEN_ORDER;
memset(&term_desc, 0, sizeof(term_desc));
cache_x = 1;
cache_y = 20;
pad = 0;
max_order = 1;
num_fonts = 0x147;
cap_flags = 0x2a;
text_cap_flags = 0x6a1;
memset(&pad2, 0, sizeof(pad2));
desk_cache_size = 0x38400;
unknown1 = 0;
unknown2 = 0x4e4;
}
} __attribute__((__packed__)) rdp_order_caps;
#define RDP_CAPSET_BMPCACHE 4
#define RDP_CAPLEN_BMPCACHE 0x28
typedef struct rdp_bmpcache_caps {
uint16_t type;
uint16_t len;
uint8_t unused[24];
uint16_t entries1;
uint16_t max_cell_size1;
uint16_t entries2;
uint16_t max_cell_size2;
uint16_t entries3;
uint16_t max_cell_size3;
rdp_bmpcache_caps() {
type = RDP_CAPSET_BMPCACHE;
len = RDP_CAPLEN_BMPCACHE;
memset(&unused, 0, sizeof(unused));
entries1 = 0x258;
max_cell_size1 = 0x100 * ((8 + 7) / 8);
entries2 = 0x12c;
max_cell_size2 = 0x400 * ((8 + 7) / 8);
entries3 = 0x106;
max_cell_size3 = 0x1000 * ((8 + 7) / 8);
}
} __attribute__((__packed__)) rdp_bmpcache_caps;
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_C0_CELLS 0x78
#define BMPCACHE2_C1_CELLS 0x78
#define BMPCACHE2_C2_CELLS 0x150
typedef struct rdp_bmpcache_caps2 {
uint16_t type;
uint16_t len;
uint16_t bitmap_cache_persist;
uint16_t caches_num; /* big endian */
uint32_t bmp_c0_cells;
uint32_t bmp_c1_cells;
uint32_t bmp_c2_cells;
uint8_t unused[20];
rdp_bmpcache_caps2() {
type = RDP_CAPSET_BMPCACHE2;
len = RDP_CAPLEN_BMPCACHE2;
bitmap_cache_persist = 0;
caches_num = htons(3);
bmp_c0_cells = BMPCACHE2_C0_CELLS;
bmp_c1_cells = BMPCACHE2_C1_CELLS;
bmp_c2_cells = BMPCACHE2_C2_CELLS;
memset(&unused, 0, sizeof(unused));
}
} __attribute__((__packed__)) rdp_bmpcache_caps2;
#define RDP_CAPSET_BRUSHCACHE 15
#define RDP_CAPLEN_BRUSHCACHE 0x08
typedef struct rdp_brushcache_caps {
uint16_t type;
uint16_t len;
uint32_t cache_type;
rdp_brushcache_caps() {
type = RDP_CAPSET_BRUSHCACHE;
len = RDP_CAPLEN_BRUSHCACHE;
cache_type = 1;
}
} __attribute__((__packed__)) rdp_brushcache_caps;
#define RDP_CAPSET_MULTIFRAGMENTUPDATE 26
#define RDP_CAPLEN_MULTIFRAGMENTUPDATE 8
typedef struct rdp_multifragment_caps {
uint16_t type;
uint16_t len;
uint32_t max_request_size;
rdp_multifragment_caps() {
type = RDP_CAPSET_MULTIFRAGMENTUPDATE;
len = RDP_CAPLEN_MULTIFRAGMENTUPDATE;
max_request_size = 65535;
}
} __attribute__((__packed__)) rdp_multifragment_caps;
#define RDP_CAPSET_LARGE_POINTER 27
#define RDP_CAPLEN_LARGE_POINTER 6
typedef struct rdp_large_pointer_caps {
uint16_t type;
uint16_t len;
uint16_t flags;
rdp_large_pointer_caps() {
type = RDP_CAPSET_LARGE_POINTER;
len = RDP_CAPLEN_LARGE_POINTER;
flags = 1;
}
} __attribute__((__packed__)) rdp_large_pointer_caps;
#define RDP_CAPSET_GLYPHCACHE 16
#define RDP_CAPLEN_GLYPHCACHE 52
typedef struct rdp_glyphcache_caps {
uint16_t type;
uint16_t len;
uint16_t entries1; uint16_t maxcellsize1;
uint16_t entries2; uint16_t maxcellsize2;
uint16_t entries3; uint16_t maxcellsize3;
uint16_t entries4; uint16_t maxcellsize4;
uint16_t entries5; uint16_t maxcellsize5;
uint16_t entries6; uint16_t maxcellsize6;
uint16_t entries7; uint16_t maxcellsize7;
uint16_t entries8; uint16_t maxcellsize8;
uint16_t entries9; uint16_t maxcellsize9;
uint16_t entries10; uint16_t maxcellsize10;
uint32_t frag_cache;
uint16_t glyph_support_level;
uint16_t pad0;
rdp_glyphcache_caps() {
type = RDP_CAPSET_GLYPHCACHE;
len = RDP_CAPLEN_GLYPHCACHE;
entries1 = 254; maxcellsize1 = 4;
entries2 = 254; maxcellsize2 = 4;
entries3 = 254; maxcellsize3 = 8;
entries4 = 254; maxcellsize4 = 8;
entries5 = 254; maxcellsize5 = 16;
entries6 = 254; maxcellsize6 = 32;
entries7 = 254; maxcellsize7 = 64;
entries8 = 254; maxcellsize8 = 128;
entries9 = 254; maxcellsize9 = 256;
entries10 = 64; maxcellsize10 = 2048;
frag_cache = 0x01000100;
glyph_support_level = 0x0002;
pad0 = 0;
}
} __attribute__((__packed__)) rdp_glyphcache_caps;
#define RDP_CAPSET_FONT 14
#define RDP_CAPLEN_FONT 8
typedef struct rdp_font_caps {
uint16_t type;
uint16_t len;
uint16_t flags;
uint16_t pad0;
rdp_font_caps() {
type = RDP_CAPSET_FONT;
len = RDP_CAPLEN_FONT;
flags = 0x0001;
pad0 = 0;
}
} __attribute__((__packed__)) rdp_font_caps;
#define RDP_CAPSET_INPUT 13
#define RDP_CAPLEN_INPUT 88
typedef struct rdp_input_caps {
uint16_t type;
uint16_t len;
uint16_t flags;
uint16_t pad0;
uint32_t keyboard_layout;
uint32_t keyboard_type;
uint32_t keyboard_subtype;
uint32_t keyboard_funckey;
uint8_t ime_filename[64];
rdp_input_caps() {
type = RDP_CAPSET_INPUT;
len = RDP_CAPLEN_INPUT;
flags = 0x0001;
pad0 = 0;
keyboard_layout = 0x409;
keyboard_type = 0x4;
keyboard_subtype = 0;
keyboard_funckey = 0xC;
memset(ime_filename, 0, sizeof(ime_filename));
//for (int i = 0; i < sizeof(ime_filename) - 1; i++) {
// ime_filename[i] = '\0';
// ime_filename[i+1] = 0;
//}
}
} __attribute__((__packed__)) rdp_input_caps;
#define RDP_CAPSET_SOUND 12
#define RDP_CAPLEN_SOUND 8
typedef struct rdp_sound_caps {
uint16_t type;
uint16_t len;
uint16_t sound_flags;
uint16_t pad0;
rdp_sound_caps() {
type = RDP_CAPSET_SOUND;
len = RDP_CAPLEN_SOUND;
sound_flags = 0x0001;
pad0 = 0;
}
} __attribute__((__packed__)) rdp_sound_caps;