Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review keycodes to support various language #5

Open
upils opened this issue Feb 6, 2020 · 5 comments
Open

Review keycodes to support various language #5

upils opened this issue Feb 6, 2020 · 5 comments

Comments

@upils
Copy link

upils commented Feb 6, 2020

On a french version of Windows with keyboard in French, key sent are sent like on a QWERTY keyboard.

Can you give the source of the harcoded key values ? What I was able to find with a quick search do not match with your values (like here)

I was thinking to add another argument to specify the language of the targeted system in order to use the appropriate keymap.

@upils
Copy link
Author

upils commented Feb 6, 2020

A coworker found keymap lists here https://github.com/apache/guacamole-server/tree/master/src/protocols/rdp/keymaps

@0xthirteen
Copy link
Owner

I don't currently have any plans to support other languages. It would be easy to change the codes in the keycodes method for what you need. There are a handful of pages that will show the keycodes like https://www.csee.umbc.edu/portal/help/theory/ascii.txt.

@RiccardoAncarani
Copy link

RiccardoAncarani commented Jun 28, 2020

Not exactly a solution, but you can query the remote machine using WMI and look for the Win32_Keyboard class.
The KeyCodes function would be then something like:

switch (keyboardLayout)
            {
                //https://github.com/apache/guacamole-server/tree/master/src/protocols/rdp/keymaps
                case "00000809": // UK layout
                    keycode["\\"] = new Code(new[] { false, true }, new[] { 0x56 });
                    break;
                default:
                    keycode["\\"] = new Code(new[] { false, true }, new[] { 0x2b });
                    break;
            }

That is just an example with the GB keyboard setting that was causing me troubles with \
But I'm just too lazy to check all the other keys.

The code I'm using to do the WMI query within SharpRDP:

if (wmi)
                    {
                        Console.WriteLine("[.] Acquiring keyboard layout..");
                        ConnectionOptions options = new ConnectionOptions();

                        options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
                        options.EnablePrivileges = true;
                        options.Authentication = AuthenticationLevel.PacketPrivacy;

                        if (!String.IsNullOrEmpty(username))
                        {
                            Console.WriteLine("[+] Using explicit credentials");
                            options.Username = username;
                            options.Password = password;


                        }


                        ManagementScope scope = new ManagementScope("\\\\" + server + "\\root\\cimv2", options);
                        scope.Connect();
                        ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Keyboard");
                        ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
                        ManagementObjectCollection q = searcher.Get();
                        
                        foreach (ManagementObject m in q)
                        {
                            layout = m["Layout"].ToString();
                            Console.WriteLine("[+] Acquired remote keyboard layout via WMI: " + layout);
                        }
                    }
                    else
                    {
                        layout = "0000";
                    }

EDIT: Clearly, this adds the requirement to communicate using something that is not just RDP. This might not be ok for every situation.

@rcaroncd
Copy link

Hi, here are the keycodes of the qwerty keyboard in Spanish, in case anyone was looking for it. Some keys I haven't been able to make work, in case I get them I'll put them here. I hope they solve the problem soon.

            keycode["Esc"] = new Code(new[] { false, true }, new[] { 0x01 });
            keycode["Enter+down"] = new Code(new[] { false }, new[] { 0x1c });
            keycode["Enter+up"] = new Code(new[] { true }, new[] { 0x1c });
            keycode["Win"] = new Code(new[] { false, true }, new[] { 0x15b });
            keycode["Down"] = new Code(new[] { false, true }, new[] { 0x150 });
            keycode["Right"] = new Code(new[] { false, true }, new[] { 0x14d });
            keycode["Left"] = new Code(new[] { false, true }, new[] { 0x14b });
            keycode["Alt"] = new Code(new[] { false, true }, new[] { 0x38 });
            keycode["Shift"] = new Code(new[] { false, true }, new[] { 0x2a });
            keycode["Space"] = new Code(new[] { false, true }, new[] { 0x39 });
            keycode["Tab"] = new Code(new[] { false, true }, new[] { 0x0f });

            keycode["Calc"] = new Code(new[] { false, true }, new[] { 0x121, 0x121 });
            keycode["Paste"] = new Code(new[] { false, true }, new[] { 0x10a, 0x10a });

            keycode["1"] = new Code(new[] { false, true }, new[] { 0x02 });
            keycode["2"] = new Code(new[] { false, true }, new[] { 0x03 });
            keycode["3"] = new Code(new[] { false, true }, new[] { 0x04 });
            keycode["4"] = new Code(new[] { false, true }, new[] { 0x05 });
            keycode["5"] = new Code(new[] { false, true }, new[] { 0x06 });
            keycode["6"] = new Code(new[] { false, true }, new[] { 0x07 });
            keycode["7"] = new Code(new[] { false, true }, new[] { 0x08 });
            keycode["8"] = new Code(new[] { false, true }, new[] { 0x09 });
            keycode["9"] = new Code(new[] { false, true }, new[] { 0x0a });
            keycode["0"] = new Code(new[] { false, true }, new[] { 0x0b });

            keycode["A"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x1e });
            keycode["B"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x30 });
            keycode["C"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x2e });
            keycode["D"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x20 });
            keycode["E"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x12 });
            keycode["F"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x21 });
            keycode["G"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x22 });
            keycode["H"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x23 });
            keycode["I"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x17 });
            keycode["J"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x24 });
            keycode["K"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x25 });
            keycode["L"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x26 });
            keycode["M"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x32 });
            keycode["N"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x31 });
            keycode["O"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x18 });
            keycode["P"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x19 });
            keycode["Q"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x10 });
            keycode["R"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x13 });
            keycode["S"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x1f });
            keycode["T"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x14 });
            keycode["U"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x16 });
            keycode["V"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x2f });
            keycode["W"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x11 });
            keycode["X"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x2d });
            keycode["Y"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x15 });
            keycode["Z"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x2c });

            keycode["a"] = new Code(new[] { false, true }, new[] { 0x1e });
            keycode["b"] = new Code(new[] { false, true }, new[] { 0x30 });
            keycode["c"] = new Code(new[] { false, true }, new[] { 0x2e });
            keycode["d"] = new Code(new[] { false, true }, new[] { 0x20 });
            keycode["e"] = new Code(new[] { false, true }, new[] { 0x12 });
            keycode["f"] = new Code(new[] { false, true }, new[] { 0x21 });
            keycode["g"] = new Code(new[] { false, true }, new[] { 0x22 });
            keycode["h"] = new Code(new[] { false, true }, new[] { 0x23 });
            keycode["i"] = new Code(new[] { false, true }, new[] { 0x17 });
            keycode["j"] = new Code(new[] { false, true }, new[] { 0x24 });
            keycode["k"] = new Code(new[] { false, true }, new[] { 0x25 });
            keycode["l"] = new Code(new[] { false, true }, new[] { 0x26 });
            keycode["m"] = new Code(new[] { false, true }, new[] { 0x32 });
            keycode["n"] = new Code(new[] { false, true }, new[] { 0x31 });
            keycode["o"] = new Code(new[] { false, true }, new[] { 0x18 });
            keycode["p"] = new Code(new[] { false, true }, new[] { 0x19 });
            keycode["q"] = new Code(new[] { false, true }, new[] { 0x10 });
            keycode["r"] = new Code(new[] { false, true }, new[] { 0x13 });
            keycode["s"] = new Code(new[] { false, true }, new[] { 0x1f });
            keycode["t"] = new Code(new[] { false, true }, new[] { 0x14 });
            keycode["u"] = new Code(new[] { false, true }, new[] { 0x16 });
            keycode["v"] = new Code(new[] { false, true }, new[] { 0x2f });
            keycode["w"] = new Code(new[] { false, true }, new[] { 0x11 });
            keycode["x"] = new Code(new[] { false, true }, new[] { 0x2d });
            keycode["y"] = new Code(new[] { false, true }, new[] { 0x15 });
            keycode["z"] = new Code(new[] { false, true }, new[] { 0x2c });
            keycode[" "] = new Code(new[] { false, true }, new[] { 0x39 });

            keycode[","] = new Code(new[] { false, true }, new[] { 0x33 });
            keycode["."] = new Code(new[] { false, true }, new[] { 0x34 });
            keycode["+"] = new Code(new[] { false, true }, new[] { 0x4E });
            keycode["-"] = new Code(new[] { false, true }, new[] { 0x35 });
            keycode["'"] = new Code(new[] { false, true }, new[] { 0x28 });
            keycode["="] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x0b });
            keycode[":"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x34 });
            keycode["/"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x08 });
            keycode["\""] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x03 });
            keycode["&"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x07 });
            keycode["%"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x06 });
            keycode["("] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x09 });
            keycode[")"] = new Code(new[] { false, false, true, true }, new[] { 0x2a, 0x0a });

            keycode["Win+R+down"] = new Code(new[] { false, false }, new[] { 0x15b, 0x13 });
            keycode["Win+R+up"] = new Code(new[] { true, true }, new[] { 0x15b, 0x13 });
            keycode["Win+D"] = new Code(new[] { false, false, true, true }, new[] { 0x15b, 0x20 });
            keycode["Alt+Shift"] = new Code(new[] { false, false, true, true }, new[] { 0x38, 0x2a });
            keycode["Alt+Space"] = new Code(new[] { false, false, true, true }, new[] { 0x38, 0x39 });
            keycode["Ctrl+Shift"] = new Code(new[] { false, false, true, true }, new[] { 0x1d, 0x2a });
            keycode["Alt+F4"] = new Code(new[] { false, false, true, true }, new[] { 0x38, 0x3e });
            keycode["Ctrl+V"] = new Code(new[] { false, false, true, true }, new[] { 0x1d, 0x2f });
            keycode["Alt+F"] = new Code(new[] { false, false, true, true }, new[] { 0x38, 0x21 });

            keycode["Ctrl+Shift+down"] = new Code(new[] { false, false }, new[] { 0x1d, 0x2a });
            keycode["Ctrl+Shift+up"] = new Code(new[] { true, true }, new[] { 0x1d, 0x2a });

I have compiled it with visual studio and executed it this way (the remote machine with the ES keyboard):

.\SharpRDP.exe  computername=10.0.2.4 command="powershell.exe -enc RwBlAHQALQBTAE0AQgBzAGgAYQByAGUAIAA+ACAAQwA6AFwAVwBpAG4AZABvAHcAcwBcAFQAYQBzAGsAcwBcAHAAZQBwAGUALgBsAG8AZwA=" username=.\Administrador password=Passw0rd!

if I use the flag exec=cmd or exec=powershell the command is never executed. I haven't been able to find out why this bug happens. And I have also removed ToLower from the command entered, because if you force the base64 to be converted to lowercase, for example, the command no longer works. All this at Client.cs

@hi-unc1e
Copy link

hi-unc1e commented Sep 5, 2022

一位同事在这里找到了键盘映射列表https://github.com/apache/guacamole-server/tree/master/src/protocols/rdp/keymaps

Great! I found the map of Caplocks, helping me a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants