Sricam AP003 by Sricctv

I got this camera not long ago, and as it usually happens, in addition to its main purpose it served some hours of fun!

It's one of the cheapest wireless IP cameras right now, you can find it for around 40$ depending on the store. The manufacturer is Sricctv, a company based in Shenzhen specialized in CCTV.

It uses Linux 2.6 and has a MIPS processor (MIPS 24K V4.12).


I couldn't find the firmware in the official website and they didn't agree to send me the latest version. Luckily for me I got a firmware for a camera similar to mine so I could study the system a bit without messing with the hardware.

The firmware file format is pretty straightforward. It expects a 32 bytes header string, the size of the package in a 4 byte value, a ZIP file with the contents and a 32 bytes footer:

00000000 77 69 66 69 2d 63 61 6d 65 72 61 2d 73 79 73 2d |wifi-camera-sys-|
00000010 71 65 74 79 69 70 61 64 67 6a 6c 7a 63 62 6d 6e |qetyipadgjlzcbmn|
00000020 43 17 05 00 50 4b 03 04 0a 00 00 00 00 00 e7 7e |C...PK.........~|
00051760 00 07 13 05 00 00 00 77 69 66 69 2d 63 61 6d 65 |.......wifi-came|
00051770 72 61 2d 65 6e 64 2d 6e 76 78 6b 68 66 73 6f 75 |ra-end-nvxkhfsou|
00051780 74 65 71 7a 68 70 6f |teqzhpo|

There are two types of upgrades handled by the upgrader, system upgrades and web app upgrades.

- System upgrades overwrite the main system binaries, located in /system/system/ and have this header and footer combination: wifi-camera-sys-qetyipadgjlzcbmn, wifi-camera-end-nvxkhfsouteqzhpo.

- Web app upgrades overwrite the contents in /system/www/ and have this header and footer combination: wifi-camera-app-qazwsxedcrfvtgba, wifi-camera-end-yhnujmzaqxswcdef.

Interestingly, web app upgrades are expected to contain a password protected ZIP file, but system upgrades are not. As the upgrader is in the system firmware image, we can look at the binary and locate the hardcoded password.

Telnet access for everyone!

While there are several ports listening in the camera, the most interesting are probably 23 (telnet) and 81 (default http panel). When we extracted the firmware, we located a nice string:


The encrypted password for root is easy to crack: 123456

So now we can log in to the camera via telnet with the root account and get access to all the file system.

This can also be used to disclose all the configuration, including user and password of the admin account in the web panel:

$ telnet
Connected to
Escape character is '^]'.

(none) login: root

BusyBox v1.12.1 (2013-03-02 13:26:40 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# cd /system/www/

# cat system.ini


We can change the root password, but as the passwords file is in a volatile partition of the file system, the default will be set again after reboot.

Connect the camera and say Hi to the Internet!

This bothered me a lot when I connected the camera for the first time. If your router has UPnP enabled, which is very common in SOHO routers, the camera will use this protocol to open the external port (Internet facing) of your router and forward it to the port where the web management service is listening. By default this port is 81.

If you haven't setup your credentials yet, the camera is wide open to everyone. If a vulnerability is found in the service, no matter what your configuration is, the camera will be there for sneaky eyes.

This is probably a "convenience" for non-technical users to connect from external networks using the P2P app provided by the vendor. The camera will also get the external IP of your network connecting to, so the app knows where to connect.


If you care about your privacy, this camera is not for you. I guess you get what you pay, the camera has good specifications and performance, but the software design is just horrible.

rdtsc x86 instruction to detect virtual machines

A new version of pafish has been recently released. It comes with a set of detections completely new for the project (read: not new techniques), which are based on CPUs information. To get this information, the code makes use of rdtsc and cpuid x86 instructions.

Here we are going to look at rdtsc instruction technique, and how it is used to detect VMs.

What is rdtsc?

Wikipedia's description is pretty straightforward [1]:

The Time Stamp Counter (TSC) is a 64-bit register present on all x86 processors since the Pentium. It counts the number of cycles since reset. The instruction RDTSC returns the TSC in EDX:EAX. In x86-64 mode, RDTSC also clears the higher 32 bits of RAX and RDX. Its opcode is 0F 31.

So it is a counter increased in each CPU cycle.

Well, it actually depends on the processor.

Initially, this value was used to count the actual internal processor clock cycles. It was meant for developers to measure how many cycles a routine takes to complete. It was good to measure performance.

In the latest Intel processor families, this counter increases at a constant rate, which is determined by the maximum frequency the processor can run at that boot. Maximum does not mean current, as power-saving measures can dynamically change the velocity of the processor. This means it is not good to measure performance anymore, because the processor frequency can change at runtime and ruin the metric. On the other hand, now it can be used to measure time.

This is explained much better in reference [2].

So, how is this used to detect VMs?

In a physical (host) system the counters subtraction of two consecutive rdtsc instructions will result in a very small amount of cycles.

On the other hand, doing the same in a virtualized (guest) system, the difference can be much bigger. This is caused by the overhead of actually run inside the virtual machine.

I wrote a small program to verify this behaviour, it will do the subtraction ten times with a sleeping period of time in between. You can get the source from here.

This is similar to what pafish does, the output in a physical machine looks like this:

$ gcc -O2 vmfun.c && ./a.out
(81889337556698 - 81889337556746) rdtsc difference: 48
(81891335245484 - 81891335245508) rdtsc difference: 24
(81893332927964 - 81893332927988) rdtsc difference: 24
(81895330659684 - 81895330659708) rdtsc difference: 24
(81897326984696 - 81897326984720) rdtsc difference: 24
(81899324782460 - 81899324782520) rdtsc difference: 60
(81901322471630 - 81901322471690) rdtsc difference: 60
(81903320069632 - 81903320069656) rdtsc difference: 24
(81905317727808 - 81905317727832) rdtsc difference: 24
(81907314531066 - 81907314531078) rdtsc difference: 12
difference average is: 32

Try to compile and run this code with different compiler optimizations if you want to have some fun ;)

This is the theory, but in practice it depends on the virtualization product, its configuration, and the number of cores assigned to the guest system.

For instance, VMware virtualizes the TSC by default. This can be disabled but it is not recommended, the TSC virtualization can also be tweaked in the configuration. Much more information about this in references [3] and [4].

There is also a substantial difference when the VM has two or more cores assigned. With one core, the differences are not that big, and it gets close to a physical processor although sometimes some peaks can happen. With two or more cores, the differences are much bigger and consistent.

I suspect the second behaviour is caused by CPU ready times, which is explained in references [5] and [6].

Have a look at the following example in VirtualBox:

One core assigned, note the peaks


Two cores assigned, the differences are large and consistent

So we can conclude two things.

The first one is, this method is not always reliable as it is heavily dependant on the processor and the virtualization product.

The second one is, if I were running a sandbox cluster, I would try to assign only one core to each guest machine. Not only because it would make this method a bit less reliable, but also for performance.

Our fabulous sandbox uses an emulator instead of a VM, should I care about this?

Well, generally speaking you should not care about this specific method then. Emulators replicate the whole machine hardware, including the CPU at the lowest level (binary translation), so it has its own TSC implementation, and the cycles usage for a routine should be similar to a physical CPU.

We can verify this running our testing program in QEMU:

QEMU is nice

I hope you enjoyed the post and this new pafish release, thanks to members for helping me with the tests :)

Check out the references for more information on this topic and general understanding on how VMs / emulators work!








Analysis of a Win32 (Neutrino?)/n3nmtx Trojan

I detected this piece a while ago, but didn't have time to get deeper into it. The detections of the malware sample are quite generic, so for the purpose of this post I'll name it "n3nmtx", based on the mutex it creates at the beginning of the execution. More details on the name at the end of the post.

This sample caught my attention because of the huge number of anti-analysis tricks it deploys. Actually, some of them are stolen from pafish, which makes me feel really bad and forces me to do the proper analysis.

Anti-analysis tricks

Basically we will need to comply with some conditions to make the malware run. At the beginning of the execution, it will sleep for 0x2710 (10000), then it will do a call to 0x400, which is the function that contains all anti-analysis tricks. If that procedure doesn't complain, it will check for internet connection. If it can't connect, the execution will come back to the beginning of the loop procedure.

So, instead of patching the whole system to run it, we will patch the malware itself (:D), and radare2 will help us!

To patch the sleep time, the best we can do is going to the value and change it for something smaller, let's say 0x05. So we copy the binary and open it with r2 in write mode:

$ r2 -w original_patch.exe

Let's seek the address of the sleep value:

[0x0040a3fa]> s 0x00004f32

And in visual mode (V), using the cursor, we can +/- the push value.

We do the same with the other sleep, and we're done.

radiff2 is quite handy to confirm the changes:

$ radiff2 original.exe original_patch.exe
0x00004f32 1027 => 0500 0x00004f32
0x00004fb7 1027 => 0500 0x00004fb7

Great, no more sleeps.

The anti-analysis procedure is just a call, and it doesn't check any return value. If it would, we could patch the conditional jmp, but as it doesn't, we will just put some NOPs there.

Open the file in write mode again, knowing where to put the NOPs and how many of them ...

[0x0040a3fa]> wx 9090909090 @0x00004f0d

And in visual mode we can confirm that the procedure will never be executed, and also that we didn't mess up the opcodes.

At this moment, the malware will run instantly in any system, including sandboxes!


To stay alive after reboots, it creates some entries in the registry, common stuff.

Communication with CnC

The communication with the CnC is done via HTTP requests. It will basically send pings and ask for tasks to do.

The task delivery is interesting because the server will answer with a 404 response, but at the end of the content we can find the command sent to the bot in base64.


The commands accepted by the bot are:


Most of them are self-explanatory.


I want to keep this short because while I was redacting the post, I found some public information about the piece.

You can check this McAfee post for more detail on the anti-analysis techniques.

This bot seems to be part of a Neutrino botnet, Kafeine also wrote about it, but hashes and CnC are different.

My hashes are:

8130f713b2464c77c6500d5d8d37a4b3e3c0e98f2607ca4262a87ee6ae0e88c3 <- the sample used for the post


You can find them in VT or in our beloved Zoo :)

Friendly note for Technicolor TD 5130 owners

For some reason, I ended up with this SOHO router. It has been deployed by one of the biggest ISPs in Spain for some time (I've no idea if it's still being distributed). I bought it in a second hand store to configure it with my current ISP, and it ended up being a good device.

The firmware it had when I got it was quite bad, lots of configuration parameters missing, slow interface, ... So I surfed the Internet for a better solution.

At some point of my journey, I found this website (, which seems to be the Brazilian Technicolor site, and offers a firmware download. This firmware is for the Brazilian GVT ISP.

TD5130 V2.05.C17GVD (GVT) (SHA1 904d8d9153b3e0b90165e973cd5a29553a6933cc).

In this case the panel is "as is", with all advanced options, which is a much better solution for my use case.

At this point, I wanted to know the mechanisms of the router under the hood, so I started extracting the filesystem. It is an embedded Linux system, MIPS architecture.

I didn't find nasty tricks (yet?), but one thing caught my attention. There is a specific configuration panel that is not present in the regular panel tabs or buttons. This panel contains the TR069 settings, which is a protocol that basically gives the ISP control over your router to perform diagnostics, upgrade or change your firmware, and monitor your device.

This is what they use when you have a problem and call the support center, but I guess not all people want this protocol enabled (which is the default).

Anyway, to access this setting you have to login in your router and directly open the url

There you can enable/disable the protocol, change and see settings, ...

It's needless to say that I'm not responsible of your actions, so if you completely mess it up, and the router doesn't work anymore, deal with it.

Regarding the device it's quite simple, the configuration gives you a lot of possibilities, and I can't complain about the overall performance.

Home← Older posts