Configuring Apache Guacamole with LDAP and 2FA

Apache Guacamole is open source software that is handy for remote administration or operations. It allows remote access to multiple systems, on multiple protocols, through a web interface. Its also handy to configure this capability into a bastion host, allowing remote management with minimal hassle.

Login prompt for Guacamole

Guacamole is open source and well documented, with support for several types of authentication as well as multi factor authentication. However, all of the writeups I found tended to either hardcode user passwords in the configuration file or skip the details on how to configure services. So I dug into it and documented configuration using LDAP for authentication, DUO for two factor authentication, and MySQL for holding connection configurations and mapping them to users. For this installation, I created a fresh Ubuntu 18.04 desktop and used an Active Directory domain already configured in my lab, consisting of a domain controller built on Windows Server 2016 and a Windows 10 host.

The first step in configuration of Guacamole is to build the server from source. OpenJDK and Maven must first be installed. After installing them using apt, the JAVA_HOME environmental variable must be set. It must be set both in the ~/.profile (or /etc/profile) and in the ~/.mavenrc config files.

The .mavenrc file must be created in the home directory of the user installing guacamole

There are a list of libraries detailed in the documentation required by Guacamole. Install these using apt.

Tomcat8 as well as supporting applications must be installed.

The code for the Guacamole server can be downloaded here. Once downloaded, the configure file must be generated using autoreconf.

Once complete, run configure with the –with-init-dir option set in order to ensure that the software will be loaded on OS startup.

After configuration, run make and make install followed by ldconfig to complete the guacamole installation. The guacamole client must then be installed. The client software can be downloaded here. Once downloaded, use maven to install it.

This will error is the JAVA_HOME variable is not properly set in ~/.mavenrc

Installation of the client and server are complete at this point, however Guacamole is inaccessible until configuration is completed. The GUACAMOLE_HOME variable must be set in the /etc/default/tomcat8 file.

Configuration files and Guacamole extensions will be located in the /etc/guacamole directory. This directory must be created along with the extensions and the lib directory.

The guacamole-1.1.0.war file must be placed in the /var/lib/tomcat8/webapps directory. The name of the .war file place in the /var/lib/tomcat8/webapps directory will determine what the name of the web directory on the configured tomcat port will be. In this configuration, the Guacamole server will be available at http://localhost:8080/guacamole/.

The Guacamole home directory must be symbolically linked to the /usr/share/tomcat8/.guacamole directory.

The next step is to begin the initial configuration within the /etc/guacamole/ file. The hostname and port that Guacamole will be associated with must be defined.

If you restart the tomcat8 and guacd services at this point, the server should be accessible at the configured URL. However, no authentication has been configured so you will be unable to log in. In order to use Active Directory for LDAP authentication within Guacamole, the first step is to download the guacamole-auth-ldap-1.0.0.tar.gz file from the Apache site. The tar file must be decompressed and the .jar file must be placed in the /etc/guacamole/extensions directory.

Guacamole will require access to a service account to allow Guacamole to search for Active Directory objects and authenticate users.

The file needs to account for the required LDAP parameters. The ldap-hostname parameter should point to an authentication server on the ldap-port using the ldap-encryption-method. The ldap-user-base-dn will be the base that Guacamole will look for users in. The ldap-username-attribute is the default for Windows. The ldap-search-bind-dn is the distinguished name for the account that will be used by Guacamole to search AD. And the ldap-search-bind-password is, of course, awesome.

ph34r my password strength

The tomcat8 and guacd services must be restarted in order to read the changes to the file. Once the restart is complete, you will be able to log in using AD user credentials! But there will be no available connections.

Connection configurations will be stored in MariaDB. In order to install MariaDB 10.4, the first step is to add the repository key for the MariaDB repo.

Next the repository needs to be added forthe appropriate server architecture.

Both the server and client applications for must now be installed.

The default time zone must be set for MariaDB using the default-time-zone parameter int he /etc/mysql/my.cnf file. This setting must be placed in the mysqld section of the my.cnf file

The database and user for Guacamole must next be created. First create the database. The database can be named whatever you want, for simplicity’s sake I’m sticking with the examples used in the documentation.

Next, create the user that guacamole will use in order to interact with the database. My super strong password reappears, ideally use something better than that.

The user that was created in the previous step must be granted privileges for the database we configured. Flush privileges to reload the grant table and this stage is done.

In order to use MySQL, we must install an extension and a library. First, the extension file, guac-auth-jdbc-1.0.0.tar.gz, must be downloaded from the Apache Guacamole website. Once decompressed, copy the guac-auth-jdbc-1.0.0.jar file to the /etc/guacamole/extensions directory.

Guacamole also requires a library in order to interact with MySQL. The MySQL Connector/J is used as a library by Guacamole to interface with MySQL. Download the file and install the .deb.

Once installed, a symbolic link must be created of the .jar file that was installed in the /etc/guacamole/lib directory.

The decompressed files for the JDBC extension contain a schema directory with configuration files for different database types. The .sql configuration files must be applied to the database.

Edit the file to point to the mysql database on localhost at port 3306. Ensure that the mysql-database and mysql-username values match what was configured in the database, and use an awesome password.

The .sql configuration files should have configured a user in the database named guacadmin with the password guacadmin. Restart the tomcat8 and guacd services, and you should now be able to log in as the guacadmin user. Change the password to something strong (not my weak example password from the config file).

In order to populate users from AD, we need to establish guacadmin as an LDAP user. The way Guacamole works, it attempts authentication against all configured methods simultaneously. So in this case, it will attempt to authenticate guacadmin against both LDAP and MySQL and if either method is successful, it will log the user in. So a user named guacadmin can be created in AD and the password does not need to match the MySQL password in order to authenticate the user.

If we log in as guacadmin using AD credentials, we should be able to see all users in the LDAP user base path that we established in the file by logging in and going to the Users settings in the we interface.

In order to allow AD users to log in remotely to Windows machines, they need to be given permissions in AD. The easiest way to do this is to use Group Policy. First step, add a new security group, in this case named Guac_Users. Add users to this group who should be allowed to log in remotely to Windows.

In the Group Policy Management console, right click the domain and select “Create a Group Policy in this Domain and link it here”, in this case the new policy is named Guac_Users.

Right click the new policy and select Edit, then navigate to “Computer Configuration”=>“Policies”=> “Windows Settings”=>Security Settings” and then right click “Restricted Groups” and select “Add Group”.

Select the Guac_Users group that was previously configured.

Assign the group as a member of the Remote Desktop Users group.

Select Apply and you should see the policy update to show the Guac_Users group as a member of the Remote Desktop users group.

The users should be configured and granted permissions once the GPO populates. Connections must be configured in the Guacamole web console. There are a ton of configuration options for each connection, this config is only concerned about setting up a basic connection using NLA. Log in as guacadmin and go to Settings and then Connections and select New Connection. Give it a name and select RDP for the protocol.

Scroll down to the Parameters section. Input the hostname or IP to connect to. Put in the RDP port, the domain name, and set the Security mode to NLA. Check “Ignore server certificate” to

For the username and password, Apache Guacamole has a feature called parameter tokens we can use to specify the username and password without hard coding in the config files or the database. Input ${GUAC_USERNAME} for the username and ${GUAC_PASSWORD} for the password. This will set the value of these variables to the credentials used by the user to log into the web interface, and then use those stored credentials to authenticate to the remote machine.

Save the connection and go to the Users menu. Select the user to be granted permissions to use this connection, and scroll down to the bottom. Select the connection and save the user.

Log out of the guacadmin account, log into the configured user. The configured user should automatically start logging into the host that was configured in the connection!

Note that it automatically logs in because there is only one connection configured. If more than one connection is configured then the user will be brought to a selection screen similar to the pic below.

Authentication is set up, a connection is set up, and everything is working as expected. Getting two factor authentication set up for Guacamole is relatively easy, and the last step here. In this example two factor authentication will be set up with Duo. Download the guacamole-auth-duo-1.0.0.tar.gz from here. Expand the tar file and copy the guacamole-auth-duo-1.0.0.jar file into the /etc/guacamole/extensions directory.

Log into the Duo web console and configure a new Web SDK. In order to configure Guacamole, we need three pieces of information from the Web SDK settings: the integration key, the secret key, and the api hostname. The secret key is sensitive and acts as the password from Duo for the configured application. Note these items and save the newly configured application.

The next step is to configure a user in the Duo web interface. Follow the prompts to create a new user, then associate a device with that user for use with Duo.

The last item needed for configuration is the application key. The application key must be kept secret and along with the secret key should be treated as a password. The application key must be at least 40 characters and should be random. Any random string can be used, I chose to generate a random string using the below command.

head -c 50 < /dev/urandom | sha256sum | cut -c 1-40

Now the files must be updated. Input the API hostname, integration key, secret key, and application key as below.

Restart the tomcat8 and guacd processes to read the changes from the Duo requires the server time to be in sync, use chrony to sync the time.

Once synced, log in with the configured user and you should be prompted for Duo two factor authentication.

Input the two factor code and the user will be authenticated!

The frustration I felt when initially researching this was that I didn’t feel comfortable putting user credentials in a text file, or have an idea of how to manage that if implemented for a team, but the writeups I read were using that basic authentication which relies on hardcoding those creds. There’s no getting around putting sensitive data in that file. We have the service account credentials, the database password for the guacamole user, and the Duo keys all stored in the file. But no user data is saved in there, and if you had to make your team use this it’s usable and scalable.

Why do you need NOPs?

I’ve read a lot of things and taken both the OSCP and OSCE courses, yet I’ve never seen anyone really break out why we use NOPsleds. There are instances where they are used to line up shellcode to a particular offset, which is self-explanatory. However, there are cases where an exploit won’t work without them. Why is that?

Looking at the TRUN command in Vulnserver, it’s a relatively easy exploit. We begin crafting our overflow string, this time with no NOPs. We already established the EIP offset is 2003, and we’re using reverse shell shellcode generated by msfvenom. The only bad character identified is \x00, we we encode with the default x86/shikata_ga_nai encoder and specify the bad character. POC code for the exploit is available here.

No NOPs this time

In this instance, we are using the JMP ESP instruction located at 0x62501205 to jump to our shellcode. Before sending the exploit, ensure a breakpoint is set at this address. We send the exploit and step through it in the debugger. Take the jump to ESP and we see, we are properly lined up.

Sitting at ESP…

If we move forward one instruction at a time, the program crashes and shellcode does not execute. If we’re paying attention, we will see that part of our shellcode was overwritten with some weird instructions.

RET instruction is gone, shellcode overwritten…

So, back to the drawing board. Modify the string to add the nops in, and let’s look at execution.

NOPsled in place…

At this point we can see our shellcode at the end of the NOPs. If we continue execution, we will receive a shell. But at this point it’s important to step back and understand the process here.

Shellcode begins…

Starting at 0x00b7fa24 we see our shellcode, but what we actually see if the msfvenom decoding stub. The important part to note is the instruction at 0x00b7fa2b: FSTENV (28-Byte) PTR SS:[ESP-C]. Floating point instructions are used for placing EIP on the stack, which is useful for all sorts of reasons but for our purposes here in order to perform relative calculations for the decoder to work. If we advance execution to 0x00b7fa2f (but don’t execute this instruction) we can see this play out.

Did not crash this time…

So we use FXCH to manipulate the floating point registers and put the value of EIP into an FPU register. Then we execute the FSTENV (28-BYTE) PTR SS:[ESP-c] instruction, which dumps the floating point environment into memory. It dumps 28 bytes of data starting at ESP-C, which in this case would be 0x00b7fa00. If we look at the stack, the memory address that FXCH instruction was performed at is now at the top of the stack. The next instruction will pop this value into EBX, and now EBX will be used by the decoder for relative calculations. At this point, if we press F9 to continue execution (in Immunity…)

It works!

I find this very interesting to see in action. I happened on information about how these instructions worked when dealing with a stack alignment problem in another exploit. Understanding how the decoder worked could have saved me some time.

Vulnserver: LTER SEH Buffer Overflow

Vulnserver is an intentionally vulnerable application used for training exploit development. It consists of several commands, some vulnerable and some not, and the the user is intended to find and exploit these vulnerabilities. For many specific vulnerabilities, there are several ways to exploit them. In my preparation for the OSCE exam, I was able to find and exploit each command in turn. However, it wasn’t until reviewing the infamous HP NNM 7.5.1 exploit that I was able to exploit the LTER command in Vulnserver by overflowing the SEH address.

To start we find the crash. I used boofuzz for this, using a template found out on this blog site. The crash should occur fairly quickly.

boofuzz template for vulnserver

After fuzzing we replicate the crash manually by sending a metasploit pattern to identify the offset. We get the “LTER /.:/” prepend string from the fuzz results.

Sending a pattern of 5000 bytes

Ensure the application is open and attached to a debugger on the target machine. The application has crashed and we can see the MSF pattern overwriting several locations in memory. Inspecting the SEH chain shows us the SEH pointer is overwritten. Querying these values in the pattern_offset utility in MSF returns an offset of 3495 for NSEH, 3499 for SEH. Note, the offset for NSEH on Windows 2003 will be 3491, on Windows Vista it will be 3515. By sending a shorter buffer, you can overwrite EIP directly instead of overwriting the SEH pointer. This can be a useful exercise for dealing with character restrictions in a simpler problem.

SEH pointer is overwritten

Further testing shows that we have 28 bytes following SEH to test bad characters manually. While testing, we send the below string:

testing bad characters…

And we find some strange results:

Everything after 7F is mangled…

It wasn’t until doing the OSCE course that I really recognized what was happening here and some of the additional options I have here. The characters after 7F are being mangled, but testing reveals that they are being mangled in a predictable way, basically subtracting 7F from any value greater than 7F. The end result is that we are left with a more or less alpha-numeric character set to work with.

The next step is to identify a “pop pop ret” pointer in the essfunc.dll module that consists of allowed characters. We can use mona or findjmp.exe in order to find this address, or just search immunity for “pop r32 pop r32 ret” but this is the least readable of the three options. We add this address into our attack string at the SEH location.

pop pop ret found at 0x6250120b in essfunc.dll

We need more space to work with, 28 bytes is not enough to function with even without character restrictions. We can take a backwards jump, with a couple of modifications. For a normal backwards jump, we would use the opcodes eb XX, where XX is equal to the number of bytes we want to jump, minus 1, subtracted from 255 and converted to hex. So if we want to jump back 64 bytes we would use c0, 128 bytes would be 80. We can’t use either of these but if we use FF it will be converted to 80 when vulnserver.exe does it’s alpha-numeric conversion. Instead of using eb for a short jump, we can use 77 for a conditional short jump. This jump relies on the zero flag and the carry flag being unset. We can ensure they are set to zero by putting an operation in front of them, such as \x42 which translates to INC EDX. It would take a very unlikely set of circumstances for INC EDX to lead to the zero flag and carry flag being set.

Backwards alphanumeric jump

We set nseh equal to “\x42\x77\xff\x42” and add it to the attack string. If we send this string and follow it in the debugger, then take the jump, we arrive at about 127 bytes of code we can use.

Jump back into the buffer, giving us some breathing room…

Now that we have more space, we can sub-encode values. Sub encoding uses alpha-numeric values and SUB instructions to put specific values we need on the stack. As an example, we will take the value 0xe7ffe775 and sub encode it. First, subtract the value from 0xffffffff and then add 1. We get the value 1800188b. We can then break the bytes out into a table, as seen below. We must ensure that the values we pick add up to our bytes in the left column, but also that they are not in the list of bad characters for the application.

Table for manual sub encoding

To break this down, if we first zero out EAX, we can then perform these instructions (SUB EAX, 15521542; SUB EAX,015e0208; SUB EAX, 01500141) and then EAX will contain the value e7ffe775. Push this value on the stack, and now we have our decoded instructions on the stack. There are calculators online for doing this kind of encoding but it’s a good exercise to do it manually and learn how it is done.

My objective here was to jump all the way back to the beginning of the buffer so that I have 3000+ bytes to work with. The first thing we need to do is align the stack in our current buffer area. To do this we increase ESP by 1188 in order to place ESP right at the end of our current buffer. So whatever we push onto the stack will get executed. To do this, we push the value of ESP onto the stack, we pop it into EAX, we adjust it using sub encoding, and then we push the value of EAX onto the stack and pop it into ESP. Now, our stack is located at the end of our current buffer segment.

Sub encoded stack adjustment

From here, we want to jump backwards from the location of our stack to the beginning of our buffer. We do the math and see that we need to jump back 0xdb9, we would normally perform a near jump to FFFFF264, opcodes would translate to E9 64F2FFFF due to endianess. We will have to write this as two instructions on the stack to account for the uneven number of bytes, since we can only write 4 bytes at a time. We must zero out the EAX register before sub encoding instructions. We want to sub encode the values 64F2FFFF and E9414141 and push them on the stack in that order.

Sub encoding a near jump back to the beginning of our buffer

In this instance, I am using the same method muts used in the NNM exploit to zero out EAX. There are other methods, the one I normally like is pushing 41414141 onto the stack, popping it into EAX, and then XORing EAX with 41414141 again. If we execute these instruction, we see our jump get revealed at our stack location.

We’re jumping back and…

And now we are back at the beginning of the buffer and have a ton of buffer space for code execution. We’re actually 8 bytes into our buffer here, which is important to note for keeping our attack string aligned.

Now we’re at 00b7f23c

Now we have plenty of space. Msfvenom can generate alpha-numeric shellcode, so at this point we’re home free. Or almost. There are two other factors to consider. The first is that msfvenom-generated alpha-numeric shellcode is prepended by a non-alpha-numeric stub which sets the shellcode location in order to to operations relative to the start of the shellcode. This is a problem in this case. Offsec is nice enough to document the BufferRegister feature of msfvenom, which sets your buffer to a particular register. In order for this to work, we need to line up a register with our shellcode. So we adjust ESP using the same method as before and we can see below that our stack now lines up with our buffer, so the BufferRegister setting in msfvenom will work, our shellcode is waiting for us about 900 bytes and change away, and we should have a shell.

Lined up buffer.

You’ll note that this doesn’t work, and this is due to stack alignment. The stack must be aligned to a DWORD in x86 processors, which means that the memory address must be divisible by 4. Since ESP has been set to a place not evenly divisible by 4, instructions get confused and execution just gets messed up. So we adjust the stack to a location divisible by 4 and ensure we adjust all of our padding as well, and that’s it.

Adjusted shellcode


It works.

I have the working code posted here. It should be noted that I chose ESP, but you can use any register, I believe

Backdooring Portable Executables: Code Caves and threading failure

To start off, let’s take care of the issue with the code cave. We don’t want to add another section to the PE, we want to modify the executable as little as possible to prevent possible detection. We can use the Memory Map tool in Immunity Debugger to manually review the sections for large, uninterrupted spaces of nulls. This blog shows a pretty succinct process for backdooring executables (and is my primary source for the next portion on threading) and introduces a tool called Cminer. Using Cminer on putty.exe, we find two potential caves:

Using Cminer to locate code caves in putty.exe of 350 bytes or more

These are actually rather small at 500ish bytes a piece, and may not work for encoded shellcode, requiring a jump from one cave to the other. But for unencoded shellcode, we are looking at about 350 bytes so this is plenty of space. Also note, manual inspection of the memory space will show that there is a ton more null space in the .xdata segment, it does not end with 0x4b8800. Whether this is some kind of issue with the tool or user error, I’m not sure. The good news is that if needed we can fit plenty of encoded shellcode in there. The bad news, I tested several different open source tools and none really provided reliable results. In fact, manual inspection revealed huge portions of null space in every section in the putty.exe PE, so, yeah I don’t know, probably a rabbit hole that it would be good to go down eventually and figure out how to accurately do this using automation. For right now, manual inspection is needed but Cminer did accurately provide two code cave locations so there is that. It should be noted that even though there are huge areas of null space, trying to overwrite some of those areas will cause the debugger to complain, so it’s a trial and error thing to find a suitable area.

So uhhh… about that nullspace ending at 0x004b8800…

From here it proceeds the same as with the previous example. Step into the code cave, save the program state, place the shellcode (this time generated using msfvenom with EXITFUNC=seh), adjust the stack, and close it out by loading the saved program state from the stack and proceeding with program execution.

For threading, I used a few different resources, the most easy to read was here, but was not successful. OSCE course starts in two days so I’m not going to spend anymore time on it, I’m close but it’s not quite working out.

Backdooring Portable Executables: Fixing execution

The best part of writing things down here is that inevitably 5 minutes later, I find someone with the same problem. When backdooring putty.exe, I came across an issue with the EXITFUNC code appended onto the end of msfvenom code. The code ends with a CALL EBP, which goes off into the shellcode and eventually to ntdll.KiFastSystemCallRet where it terminates the program.

We got a shell, but the program terminates here…

Not ideal. So one solution was to change that CALL EBP instruction to NOPs. Skipping that call allows execution to proceed, everything is right with the world, except the gnawing feeling that it’s just gross.

so dirty…

But hey, it works. Turns out though, Capt Meelo had the same issue and came up with a couple of solutions. His first solution was the same as the one up here, turn that CALL instruction into NOPs and the program executes as expected. Kind of reassuring to see that someone came up with the same fix, even if it’s not ideal. But his second solution was kind of a head-slapper moment. Just create the shellcode using the EXITFUNC=seh option:

generating shellcode

A closer inspection of the shellcode reveals they’re identical, as you’d expect since looking at the metasploit github shows you that EXITFUNC is determined by code tacked on to the end of the shellcode. The real difference is in a value moved into EBX at 0x004c3127 shown below.

Left: EXITFUNC=seh Right: EXITFUNC=none

So, lesson learned. If there’s an issue with a particular part of the shellcode, maybe try all the options associated with that shellcode first before manually NOPing out instructions. Using EXITFUNC=seh resumes execution like a charm. There is one remaining issue, though. Putting simple shellcode like popping calc will always work, but in the case of a reverse shell we find that the program does not execute unless a listener is configured on the correct port. This is not ideal. So on the agenda: redirecting to existing null space int he code rather than adding a section and fixing the last remaining execution issue.

Backdooring Portable Executables

Prepping for OSCE, lots of shellcoding and debugging going on. Shellcoding is particularly frustrating today so to change gears for a bit I’m going to write up backdooring PEs. Examples are x86, tested on Windows XP SP3, using the x86 putty executable available here. I also used Stud_PE, Immunity Debugger, and a great blog post over at Sector876 that helped me get the basics down. There’s a couple of different methods, let’s start with the first, we’ll add a section.

First, let’s start by opening the program in Stud_PE. Select the Sections tab and you can see all of the sections present in the executable. Right click and choose “New Section” and adjust the size. Ensure you’ve added enough space to fit your shellcode in, and select the option to fill the space with null bytes. After you save, run the executable to ensure it still functions and nothing is broken.

adding a section with Stud_PE

Open the executable in the debugger and inspect the sections, in Immunity this is easily found in the Memory Map tab. If you inspect the section, you should find it filled with null bytes. Note the memory address that the section starts at, in this instance we see 0x004c3000.

our new section, all filled with nulls

We will need to redirect program execution to this address, where we will eventually put shellcode. For now, note the existing instructions at the program’s entry point. We will need these for redirecting back to normal execution for the program.

our initial instructions

After saving these addresses, it is time to redirect execution. In Immunity we do this by right clicking the instruction and selecting Assemble, then inputting our jump instruction. We want to jump to 0x004c3000 in this case.

assembling our jmp instruction

After assembling the instruction should update in the debugger to exactly what we need.

jmp to…

Hit F7 in Immunity to move to the next instruction and you should see the new section we added, filled with nulls.

nulls, nulls everywhere

The first thing that should be done at this point is to save the executable. After saving, in the new section overwrite the first two instructions with PUSHAD and PUSHFD instructions. This saves the program state before we pass it our shellcode. Press F7 twice to move ahead and then note the location of ESP. We will need this location after the shellcode to adjust the stack prior to normal program execution. In this instance, ESP is at 0x0012FFA0 following the two instructions added.

ready for shellcode now

Use msfvenom to create shellcode. In this instance we’re creating a reverse tcp shell for Windows in hex format, no bad chars specified. In Immunity, this is placed in the executable by selecting enough memory locations to hold our shellcode starting with the instruction following the PUSHFD, then right clicking and performing a binary paste.

generating shellcode

Once the shellcode is pasted in, place a breakpoint on the last instruction of the shellcode and press F9 to continue execution. Note that if the shellcode is a reverse shell, unless you have a listener set up it will take execution off into an exception, and that you’ll have to close the listener to hit your breakpoint. Once at the breakpoint, note the address at ESP. In this case it is 0x0012fd9c.

ESP location after shellcode execution

The determine the ESP offset, we subtract the initial ESP value from the ending value, so 12ffa0 – 12fd9c, and our offset is 0x204. in order to get ESP back where it belongs for normal program execution, we need to add 0x204 to ESP, so we right click the instruction immediately following the shellcode and input ADD ESP, 0x204. The next two instructions should be POPFD followed by POPAD to resume the program’s saved state from before the shellcode.

Perfect! Or was it…

At this point, it doesn’t work. You get your shell, the program doesn’t open, you close your shell, the program crashes. Frustrating. What we want is for the program to open and for you to get your shell at the same time. And for it to not crash when we close out of our shell. First things first. The opening issue has already been solved for us.

The offending code

So we found it. It’s near the bottom, in the blog linked above he links to the metasploit github where you can find it for yourself. So we update it…

Easy enough

Still not quite right though, normal program execution doesn’t happen. Over at the metasploit github page, you can view the code for the exitfunc portion. This code is appended to the end of your msfvenom-generated code even if you choose EXITFUNC=none, right at the end. Check out this part is particular:

very last line of your shellcode

If you trace it in the debugger, your shellcode calls EBP which takes it off back into the shellcode and eventually out into ntdll.KiFastSystemCallRet which… ok, turning into a rabbit hole. Researching this, figuring out why it is doing this, is a priority. But for right now, quick and dirty, oh so dirty, just overwrite that call with NOPs and it works.

this is a gross solution and I should feel bad…

On the agenda is creating a backdoor using existing null space within the application and figuring out this business with the EXITFUNC in msfvenom.

program’s running…
shell’s working… it’s still gross though

kwprocessor and princeprocessor

I ran across this tool while doing Rastalabs. It’s kwprocessor, designed to help build keyboard walks for wordlists. It is actually pretty easy to use and can produce some quality wordlists for keywalks, and given how common those are in the operational environment it’s a good tool to have.

Installation is easy, just run “make”. In order to build for a Windows environment, ensure mingw-w64 is installed and run “make windows”. This will produce both 32 and 64 bit executables for Windows. I didn’t have much luck using the Windows version, the output was not what you would expect. I suspect this is due to formatting issues of the inputs to kwp (discussed below) but did not test that.

The help function is available using the –help flag, and it shows you how to format the command and manipulate the output. There are two basic options in the help: keyboard and keywalk. The keyboard options specify which characters will be included. The keywalk options specify the directions the keywalks will be generated in.

The default values are specified on the right, and for the boolean values (the keyboards and keywalks) anything with a 1 is run by default. By default the command outputs to STDOUT, so you can redirect the output to a file if you are looking to add to an existing file rather than create one from scratch. Changes to the defaults must be specified individually, so a typical command might look like this:

./kwp -s 1 -3 1 -4 0 -7 1 -9 1 basechars/full.base keymaps/en-us.keymap routes/4-to-4-exhaustive-route -o /opt/test_wordlists/list1.txt

There are three required parameters for running kwp: basechars, keymap, and route. Basechars are just that, the base characters that the keyboard walk will start from. There are two built-in options: full.base and tiny.base.  The tiny base seems extremely small, but given how often passwords comprised of keyboard walks begin with these characters it is easy to see how it would be effective.

Several different keymaps are provided. Keymaps are files containing maps of locations of keys on language-specific keyboard layouts. A few common languages are given, but the format is simple enough that if necessary it could be changed. The keymap is the foundation that the list is built from, so choosing the correct keymap is critical.

Routes are the last, maybe most important, parameter to pass the command. Atom, the creator of kwprocessor, breaks routes down better than I ever could in the github readme. An important note on routes is that the two largest routes, 2-to-16-max-4-direction-changes.route and 2-to-32-max-5-direction-changes.route, don’t work for me on Linux. On Windows I was able to get the routes to work, however the previously mentioned formatting issues rendered the wordlist unusable. I think some troubleshooting could solve the format issue, but it isn’t necessary.

A good strategy for best using the tool is not to create the largest wordlist possible, but rather to create smaller wordlists and combinate them into larger wordlists. A real world example of a keyboard walk I have seen is 1qaz@WSX. This is a fairly simple password actually, but is the kind of thing administrators would use to be easily remembered and meet all the password complexity requirements. Creating a list that would contain this password would probably be enormous and tricky to generate, and requires jumps. Better to create lists of smaller words that can be more easily combined. I started by creating a custom basechars file to ensure that I am only starting from the left side of the keyboard.

Next I created a wordlist that would include all the four character walks from the left side of the keyboard that make sense. To me anyway and based on my experience, there’snot much science behind my process here.

My objective is to get the smallest possible wordlist to ensure that the list remains usable with a combinator. I have some results here from several different passes through kwprocessor in order to minimize the list and finally sorted to remove any duplicates.

Atom has another tool, princeprocessor, which can help to combine words. This is something I’m still working on, and princeprocessor takes some trial and error to avoid making enormous wordlists. But I was able to make it work and generate a wordlist of eight character keywalks which would include keywalks not easily generated by kwprocessor due to the key jumps.

This created a list that had our example password above, but also wasn’t small enough that we would be able to work with it on fairly limited hardware.

This is only a start. My objective is to use these tools to be able to generate on the fly 16 character keyboard walks that can be used on mid-range hardware to crack admin hashes. The problem is that the possible number of combinations goes up so quickly that it would make this very difficult for large wordlists. You can see the keyspace in princeprocessor for yourself prior to running the tool.

The next steps are to further reduce the size of the initial wordlist, take out uncommon or unlikely characters, take out words that wouldn’t meet common password complexity requirements. This is an ongoing project but one that I feel will ultimately be worthwhile on red team missions. The more refined I can get the initial list, the better the end product will be.


Things got so busy I forgot I had this, luckily I remembered when I had a bunch of stuff I need to write down somewhere accessible. How fortunate.

OSCP – Day Zero

Today is the day, I just received all my materials and am setting everything up. I should be able to get at least a couple of productive hours in tonight and then another few tomorrow.

My goal is, win or lose, to look back and see how I could have prepared better and apply that to the next milestone. I know that, of course, I could have done more, but I feel like I did ok for preparation right now. My overriding mantra was not to sweat it too much. I know enough about the OSCP coursework that I know it will walk me through some of the things I know I had some difficulty with, like exploit development and web stuff. But I also geared my prep to hit some of those areas. I went over several exercises in developing buffer overflow exploits. I went through the Kioptrix series (among others) from and focused on the SQLi in particular. I hit the web penetration testing exercises and broke down the mechanics, the way I like to learn.

So I’m cautiously optimistic. Let’s see how I feel in a few weeks. I’ve been reading a lot lately focused more on how to learn rather than what to learn. I just discovered the Slack channels over at NetSec Focus and immediately got some good advice about not focusing on the number of roots/day or any kind of metric like that, but understanding the practice and the mechanics of the service/attack.

Let’s see how it goes.

Kioptrix 3 – 3 Ways to Win

This one is great. More web stuff. More of me failing at SQL injection. It’s worth failing to learn, though. I keep making progress via exploits and tools, but I need to get stronger on these more basic concepts.

The entire challenge hinges on getting one of two user account passwords. Looking at the webpages and seeing the LotusCMS software, my first instinct was to look for a vulnerability for that. And I found a couple, but this one worked:  So that works and gets a shell with the www-data account, which isn’t much. There are a couple of exploits listed for the Linux kernel that should have escalated privs, but they didn’t work. So I tried doing grep -rn “password”, which worked on one of the SANS Holiday Hack challenges. Sure enough, hard-coded mysql password.

There are three ways, that I know of, to get the user creds. First is the method I used, which is to used the LotusCMS exploit then find the hardcoded MySQL password and then go to and logging in there. From there, you can get the user credentials for loneferret and dreg. You can also use SQL injection on the parameters from the gallery on the main site and get the cred that way, or use sqlmap to get the creds.

Once in, you can sudo to use the ht text editor as root, which allows you to edit the sudoers file. Clever. I liked seeing multiple paths to victory here, even if I only saw them all after the fact. Now on to Kioptrix 4, which is quite a bit harder for me.