Archive for the 'Analysis' Category


LIGATT’s LocatePC — an update

It would seem my blog saw a spike in traffic over the past 24 hours, as some people on twitter found my review of Ligatt’s LocatePC. It could perhaps be related to this Full Disclosure post about an SQL injection vulnerability in the LocatePC software. Reading that post renewed my interest in analyzing LocatePC, so I thought I’d provide an update to the current status of version 1.05 of Ligatt Security’s software. It’s worth noting that since my last blog post on the matter, Ligatt now also offers an OSX version of LocatePC which I have not looked at.

Note: At no time did I run LocatePC. This examination is based purely on reversing the binaries available on the Ligatt Security website which are free to download.

The biggest change to note between 1.01 and 1.05 is that LocatePC actually connects back to their servers. Interaction between the software and the back-end database is actually occurring now when it wasn’t last June.

Second biggest change: it’s no longer using direct MySQL connections to interact with the database. Good work! I’ll happily take credit for that improvement in the software. Instead of a direct link to the database, it’s now using a web-based API that passes XML messages between client and server. It’s doing this over HTTPS, which should prevent any eavesdroppers from sniffing the traffic it sends.

I think enumeration of an API to be a pretty fun way to spend a couple of hours. Each API request is of the format { procedure, values, types } where “procedure” is a specific stored procedure in the MySQL back-end, “types” is an array of values “string”, “num” or “base64”, and “values” is an array of the data being described by types; the arrays “types” and “values” are the same length.

Comparing this to the old version of LocatePC, it seems that every query that was being done was replaced with an API call. This API is quite easily accessible, as demonstrated by the Full Disclosure post which connects directly to their API server. Most of the calls require some sort of shared secret to insert or retrieve data:

  • Registering a new user requires a license key
  • Registering a new install requires a user and password associated with a license key
  • Checking most information for an existing install requires knowing the 32-character secret (mentioned in the previous post)

However there looks to be a weak link in this chain of secrets. “spSelectProgramLoginByMacs” takes as an argument a string with one or more MAC addresses, and returns the 32-character shared secret used to uniquely identify a LocatePC installation. With the 32-character string, combined with knowledge of the MAC, one can execute any command that the LocatePC software itself could. Oh, and if you don’t have the correct MAC you can always run “spSelectUserMacByProgramLogin” which takes the 32-character identifier and returns the MAC address of the machine.

What this boils down to is the privacy and security of a LocatePC user is protected only by the secrecy of every one of their MAC addresses. And the LocatePC database not being compromised. And the user using unguessable username password combinations. And their registration code not being public. And them trusting the employees of Ligatt Security.

A list of stored procedures used by LocatePC follows. I leave it as an exercise to the reader to find nefarious combinations of functions, because frankly I’m bored of this shitty software.

  • spBackupPassword
  • spConfigCheckLogin
  • spConfigCheckLoginWithPlog
  • spDeleteDirectoryContents
  • spDeleteUserByAllMacs
  • spDeleteWatchedDirectory
  • spDelMacExe
  • spGetPermitKeylogWebcam
  • spInsertCheckinRow
  • spInsertKeylog
  • spInsertMacExe
  • spInsertUser
  • spInsertWatchedDirectory
  • spIsCamOn
  • spIsKeyloggerOn
  • spIsProgramLoginUnique
  • spIsUninstallOn
  • spSelectCheckIn
  • spSelectCurrentVersionIfNewer
  • spSelectCustomerJobs
  • spSelectCustomerTypes
  • spSelectFilesToDelete
  • spSelectFilesToUpload
  • spSelectFromMacexe
  • spSelectNewFiles <– this one takes no arguments are returns the URL for the latest version of LocatePC
  • spSelectOneUserWithRegCode
  • spSelectPasscodeAndHotkey
  • spSelectProgramLoginByMacs
  • spSelectRegCodeUninstall
  • spSelectShutdown
  • spSelectUserMacByProgramLogin
  • spSelectUserMessage
  • spSelectWatchedDirectories
  • spSelectWaysToHearAboutUs
  • spUploadImage
  • spUnsetUninstall
  • spUpdateCheckin
  • spUpdateDirError
  • spUpdateDirUploadTime
  • spUpdateHotkey
  • spUpdateLastLogin
  • spUpdateMacExe
  • spUpdatePasscode
  • spUpdatePermitKeylogWebcam
  • spUploadDirItem
  • spUploadFile
  • spUploadFileError

LocatePC – the LIGATT trojan

This is my first malware analysis, so feedback is welcome and encouraged. For now, it’s still legal to reverse engineer software in Canada, so until Bill C-32 gets passed I’m going to keep doing it.
I selected LocatePC, which was found on the LIGATT Security website. Downloading the ZIP file gives us two executables, the first is the installer, the other is the actual trojan. Both files are written in C#, compiled as .NET assembly. This software is a commercial product designed to stay resident on someone’s computer, and allow them to be notified in the event their computer is stolen. Both executables suffer from severe flaws, both in security and in usability. In cases where I’ve deemed appropriate, I’ve censored information; these omissions are left as an exercise for the reader to uncover.
The Installer
Upon launch, the installer immediately establishes a connection to a remote MySQL server:
new MySqlConnection(“Server=; Port=3306; Database=locate_pc; User=****; Password=****; Encrypt=true”);
This is a rookie coding mistake: hard-coding credentials into an application. With this information, anyone could login to that MySQL database and manipulate the data. Fortunately for LIGATT, a firewall is preventing the software from making a connection to the database. This causes the installer to immediately quit, giving the user a “Communication error” alert box.
Now, at this point it’s clear that the software doesn’t work. But using some reverse engineering, we can see what the rest of the program does. There’s no sense leaving any of it uncovered.
So, assuming we can connect to the database, the installer then fetches a list of all MAC addresses on this machine. This list of MACs is used right away to check the database to identify whether the trojan is installed on the computer. The installer then asks the user for a registration code, and if they don’t have one they are directed to purchase one from the LIGATT website. Once a valid registration code is given, it checks to ensure it has not expired, and that the maximum number of licenses have not been used.
We are then presented with a nice Menu, giving us the option to install the trojan. Upon clicking it, the installer creates a new directory (INSTALLDIR) to install the trojan to, with the following format:
C:\Windows\<random existing directory>\<random 32-bit int>\
The directory is assigned to be readable & writeable by Everyone, and is given the hidden attribute. It then selects a name for the trojan (EXENAME), from the following list:
wingfuw winnmji winvmnw winhkip winfmvy winttkz windcmv winvtek winpfbp winzfdn winvqun winvwkx winqjbi wingroi winnzfv winhlng winybpn winhcwt winecmz winqrxi winxpju winriia winhiwf winayct winfkcd windpxb winebte winbhpu winjcdy winsicz winfzyn winrgri winmylp winonfq winpqjf wincmws winmsex winvgsi winesrl winewiv winveha winufbq winrzcg windtup winxtlk windiqu winsggx winzqei winpesf winairh winfomi winecfi winvljm winpnvz winuyyb winznpy winvxhf winycqe winlqlx winuilq winleud wingfnh windmci winrseu winqecu winedhi winnwmb winpamg windhwh winvqby winqmhu winhxzu winnics winpixl windevl winxdsi winggjm winszpd wingoyy winykec winqmrp winejgy winvtzu winqbtd winwpxd winjjep winlcgv winydrq winevmy winxolq winzuew winbvzd winekyb winatwy wintkjg winvgon winjqyt winwazf winrymo winguwl winpxwi wincmst winfkow winvgze winqgzc winhxpu winnyeu winutki winbrur winszra winydvf wintgkd winwapw winvmcy winohmp winrgzv winddwr wincnpf winncjg winaslp winlnyy winotfu winrpva winadqw winywgb winoeye winzmoo winloxz winabhl winxyje winoplo winlztk winmpti winopnn wingorv winvwuw winfung winuznj winjcbc winsvfr winerno winhgdg winoifn winktkk winsnya winbhya winidhb winkvls winnqcp winhnld
It then grabs “LocatePC.exe” from the current directory, and copies it to “INSTALLDIR\EXENAME.exe”; the installer then updates the database with the MAC address of our machine, the installation directory, and the executable’s name.
At this point, the installer presents us with a registration process. It asks for typical information: username, password, address, email, etc. In addition, the user selects a “boss-key”, a key combination used to show or hide the trojan menu. It also grabs the external IP of the machine from This information is then inserted into the database. The password the user gives is then stored in “INSTALLDIR\EXENAME”, a file with no extension. The boss-key is written to “INSTALLDIR\_EXENAME.resx”.
A unique random 32-character alphanumeric string is generated. This used to uniquely identify the trojan install within the database later. This string is stored in “INSTALLDIR\EXENAME.0” (that’s a zero on the end, fonts are annoying).
The installer creates an entry in HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\ for the newly installed trojan executable. Finally, a browser windows is spawned to the LIGATT LocatePC page, and the trojan is launched.
The Trojan
First things first, the trojan makes a connection to the MySQL database with the same credentials used above. If it’s unable to connect, it quits. It then grabs its name and installation directory from the command-line arguments list.
Now, I found this next part interesting. It creates a mutex called “LocatePC Lite”, creating it if it doesn’t exist. If it’s unable to grab the mutex (because another process holds it) then it quits. This ensures that only one copy of the trojan is running!
After that, we grab the 32-character string from “INSTALLDIR\EXENAME.0”, and look that up in the database, giving us information about the license, version, username, password. The trojan then uses this information to update the “last_login” on the account, with the current time, software version, and the mac address of the machine.
The program then opens up “INSTALLDIR\_EXENAME.resx” to get the boss-key, and registers that with the windows HotKey interface; it is then tied to a small windows that allows the user to quit the trojan or click an “About” link taking them to the LIGATT website.
Now, the trojan spawns a new thread. This thread performs all the actions listed below.
  • Check the database for whether we should uninstall ourselves. If so, deletes the entire INSTALLDIR directory, and removes the relevant registry key.
  • Check the database for whether we should update ourselves. If so, downloads the new version, replaces the executable, spawns a thread with the new executable and closes this thread.
  • Grab system information, mostly from WMI. This includes things like all IP and MAC addresses, OS version, motherboard serial number, bios version, etc. All of this information is then inserted into the database and associated with the registration code
  • Check the database for whether we should keylog. If so, record all keystrokes to the database.
  • Check the database for whether we should shutdown the PC. If so, do so.
  • Check the database for whether we should display a custom message. Message box appears with the message if there is one.
  • Check the database for whether we should activate the webcam. If so, takes a photo now and every 30 minutes, upload the jpg capture to the database.

Final Thoughts

The product ideas are good. That is, recording keystrokes, IP addresses, and webcam images are a good way to retrieve a laptop. However the actual design is severely flawed: all interactions require the database, and both programs fail if the database is inaccessible. In addition, there are several occurrences within the code of MySQL queries being made without parameterization; this could lead to SQL Injection from inside the application. As mentioned above, if the database were actually accessible for the program, it would also be accessible for anyone able to extract the credentials from the executables; this would allow an attacker to extract all information stored about the LocatePC clients, including full registration information.
Something else emerges quickly from that last thought. A more dedicated attacker could modify the database to set all instances of the trojan to enable keylogging, and then extract this information from all those computers via the database. One could argue that this was part of the design of LocatePC from the beginning: having a client pay to install a keylogger on their computer and commit identity theft with the data obtained. That’s a pretty good scam.
EDIT: clarified the section about the trojan connecting to the database, and where it gets its name from.

July 2018
« Jul