Apache GET/POST DDoS - what to do

19 inches of...hardware.
Post Reply
User avatar
bad_brain
Site Owner
Site Owner
Posts: 11532
Joined: 06 Apr 2005, 16:00
15
Location: The zone.
Contact:

Apache GET/POST DDoS - what to do

Post by bad_brain »

2 days ago I was riding my bike when I got a mail from a customer about his site being down. didn't cared too much because other sites on the same server loaded fine on my phone and the error message I got seemed to be DNS related ("can't find server").
but when 3 more mails with the same topic from different customers on the same server came in like 30 minutes later I rushed home.......aaaand DDoS attack. yay.

server was still up and accessible, which is not only great for obvious reasons (you can access it through a shell and do your work):
- it also means the service is configured properly (apache in this case), a bad config can render the whole server unresponsive
- and, which is always a great relief: it means it's a poopy little botnet. a seriously massive attack will not just overload the server, it'll overload the underlying hardware (routers, switches, etc.) , and if your server is one you manage remotely this is a pain in the rear, because you'll spend a lot of time with waiting for others to do their work, and of course their work is not for free.

how to prepare
a good way to get rid of small scale floods, like the usual brute force/wordlist login attempts, etc., is to use fail2ban, it scans logs for patterns and can ban IPs using multiple methods:
https://www.fail2ban.org/wiki/index.php/Main_Page" onclick="window.open(this.href);return false;

here is how I block IPs if they access the Wordpress login page 3 times within 30 minutes:

Code: Select all

##jail.conf##
[wp-login]
enabled = true
port = http,https
filter = wp-login
logpath = /var/www/virtual/*/logs/*-access.log
maxretry = 3
findtime = 30

Code: Select all

##according definition file in /filter.d/##
[Definition]
failregex = <HOST>.*] "POST /wp-login.php
ignoreregex =
it's not perfect because it can not make a difference between failed and successful logins, but you can whitelist IPs easily.

also fail2ban is a little diva to set up sometimes, for example it will throw errors if the filter/definition name is more than 15 characters. so always check fail2ban.log.


on larger scale attacks, like the one I experienced 2 days ago, fail2ban can be overchallenged because the logs entries from new IPs appear faster than the log file can be scanned, so a lot of malicious traffic gets through. in this case some manual work is needed.
what I do is to process the access log for the site by counting the appearance of IP addresses, and then list them together with the access count in a new file named 111:

Code: Select all

cat website-access.log | awk '{print $1}' | sort | uniq -c | sort -nr > 111
the result looks like this (actual bots here):
538 142.93.113.182
431 38.135.32.148
429 36.91.91.50
426 46.45.187.54
420 119.47.115.162
417 162.241.132.208
412 45.62.230.136
406 202.254.239.159
398 3.225.212.130
so yes, if an IP causes lots of entries within a short time it's safe to say it's a bot and part of the attack. I simply keep the most obvious ones on top and delete the others.

next, I add route add -host in front of the IPs in file 111, and reject after every IP:

Code: Select all

sed 's/$/ reject/g' && sed 's/^/route add -host /g' 111 > 222
this results in a batch file named 222 with the following content:
route add -host 173.224.123.240 reject
route add -host 42.93.113.182 reject
route add -host 38.135.32.148 reject
route add -host 36.91.91.50 reject
route add -host 46.45.187.54 reject
route add -host 119.47.115.162 reject
route add -host 162.241.132.208 reject
route add -host 45.62.230.136 reject
route add -host 202.254.239.159 reject
route add -host 3.225.212.130 reject
simply run it and you block all the IPs at once by 0-routing them, this is a much better method than using iptables, because it causes a much smaller overhead.....if you have hundreds of rules in iptables and every single request has to go though it the resulting i/o-wait can be even worse than the actual DDoS itself.

repeat this a couple of times until you see a remarkable effect on the system load/process count, then fail2ban can take over and you finally can go back to playing games on steam, dammit. :lol:
Image

User avatar
ayu
Staff
Staff
Posts: 8047
Joined: 27 Aug 2005, 16:00
15
Contact:

Re: Apache GET/POST DDoS - what to do

Post by ayu »

Nice!

Do you know if rejecting an IP in "UFW" (Uncomplicated firewall) does the same as iptables, as in bad for larger attacks?
Because that's what I've set up for one of our services at work right now, but you got me thinking :-k
"The best place to hide a tree, is in a forest"

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11532
Joined: 06 Apr 2005, 16:00
15
Location: The zone.
Contact:

Re: Apache GET/POST DDoS - what to do

Post by bad_brain »

well, ufw is obviously an interface to iptables (and iptables is an interface to netfilter, which is part of the kernel), so it should cause even more overhead than iptables alone.... :wink:

but as long as there are no i/o-waits (the "wa" value when running top) all is fine.
Image

User avatar
z3r0aCc3Ss
Fame ! Where are the chicks?!
Fame ! Where are the chicks?!
Posts: 699
Joined: 23 Jun 2009, 16:00
11
Contact:

Re: Apache GET/POST DDoS - what to do

Post by z3r0aCc3Ss »

b_b, very useful and informative.
Thank you :)
Beta tester for major RATs, all kinds of stealers and keyloggers.
Learning NMAP

User avatar
Gogeta70
^_^
^_^
Posts: 3247
Joined: 25 Jun 2005, 16:00
15

Re: Apache GET/POST DDoS - what to do

Post by Gogeta70 »

Nice! Null-routing the response packets is just fucking brilliant and as a bonus, it keeps your iptables cleaner which is always a plus for me. I hate it when I have like 3 screens of iptables listings.
¯\_(ツ)_/¯ It works on my machine...

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11532
Joined: 06 Apr 2005, 16:00
15
Location: The zone.
Contact:

Re: Apache GET/POST DDoS - what to do

Post by bad_brain »

iptables is great for filtering certain types of packets/requests, like by flags set, packet size, etc., which can be usually managed by a few permanent rules. I remember banning IP after IP when suck-o was attacked by that 5k botnet back in the days....and how the system got slower and slower... :lol: now I feed every new server I set up a ~3MB routing table with IP ranges to ban, with no noticeable decrease in performance.

here's a wonderful page where you can create all kinds of ACLs btw:
https://www.countryipblocks.net/acl.php" onclick="window.open(this.href);return false;
Image

User avatar
Gogeta70
^_^
^_^
Posts: 3247
Joined: 25 Jun 2005, 16:00
15

Re: Apache GET/POST DDoS - what to do

Post by Gogeta70 »

Dude, that's an awesome tool. Thanks for the link! :P

One time I used IP tables as a way to keep people from cracking the password for the security camera system at my previous job :lol:

So, one of the paper-pushers in the admin office at my last job completely ignored my recommendations for a security camera system and bought a completely different system on the premise of trying to save money. What landed on my desk for me to install was a 16-camera, 1080p quality network-video-recorder system. I was impressed with the quality of the cameras - each camera had its own web interface, built-in region-based motion detection, PNP configuration, etc).

The NVR (video recorder) though, it was basically garbage. It booted to some god-awful custom made UI that was difficult to use. But most importantly, it was accessible via the network. One of the main reasons they wanted these cameras is so that management could view the cameras from the phones. Web access to the NVR was provided via an ActiveX control that you had to download upon your first visit to the NVR web management page. Even the phone app for the camera system accessed the cameras via the web interface (which then forwarded RTSP streams directly to the app).

What I'm getting to with all this, is that the only access control to the camera system is an HTTP Basic Auth prompt asking for a username and password. It would let you try logging in as many times as you wanted. But also, if you made the password longer than 8 characters or included any non alpha-numeric characters in the password, the ActiveX control would break and you'd be unable to log in. Yeah, I shit you not - their system BROKE if you tried to use a secure password.

So, couple this fucked-off password debauchery with the fact that the NVR itself was publicly accessible so that management could play big brother, and sure enough... it wasn't long before I had someone running a password cracker on the NVR system login. How to deal with this? It was only a matter of time before they actually cracked the password. Well...

The entire camera system was physically isolated to its own network (try running 16 1080p cameras on your main network and see how long it takes before people complain that "the internet is slow"). To facilitate access to the cameras, I set up a debian box with a couple of NICs to route traffic between the internet and main company networks to/from the camera network. After some in-depth reading of the iptables man page, I ended up coming up with basically, this:

iptables -A FORWARD -m string --source NVR_IP --sport 80 --algo bm --string "401 Unauthorized" -j CONNMARK --set-mark 1234

iptables -I INPUT 0 -m recent --update --seconds 3600 --hitcount 5 -j DROP
iptables -A INPUT -m connmark --mark 1234 --destination NVR_IP --dport 80 -m recent --set -j CONNMARK --set-mark 0

Disclaimer: I originally wrote these rules 5 years ago. The reproduction above may not be exactly right, but should be close. If you want to use this, test!

Essentially, this looks for any responses coming from port 80 of the NVR containing "401 Unauthorized" and marks the connection. On the next incoming packet from the attacker, since the connection is marked, they're added to a list of recent IP's.
Each time they're added to the list, a counter is incremented for their IP indicating a hit count and the connmark is removed. If the hit count passes 4 within one hour, all traffic from the attacker is dropped until the hit count drops below 5 (one hour has passed).

It's a pretty hacky way of dealing with failed HTTP login attempts, but when you have no other options, it does the trick ^_^. Also, I never found anyone accessing the cameras that wasn't supposed to be, so I guess it worked well enough :P
¯\_(ツ)_/¯ It works on my machine...

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11532
Joined: 06 Apr 2005, 16:00
15
Location: The zone.
Contact:

Re: Apache GET/POST DDoS - what to do

Post by bad_brain »

for such jobs iptables is really good, and LOL at Active X...I kinda miss those cheap ass ifaces... :lol:

if it's Apache you can use mod security to do a finer granulated traffic filtering:
https://modsecurity.org/" onclick="window.open(this.href);return false;
should be available in all standard repositories.
you can do such nice things as displaying a custom error message when the request contains a specific string (full blown regex supported).....just try a RFI on s-o. :mrgreen:
Image

User avatar
Gogeta70
^_^
^_^
Posts: 3247
Joined: 25 Jun 2005, 16:00
15

Re: Apache GET/POST DDoS - what to do

Post by Gogeta70 »

Lol, yeah iptables did the trick it seems, but yeah seeing an ActiveX control in like 2015 was a bit surprising :lol:

Unfortunately, the web server ran on the NVR box itself too and was included in the firmware bundle. The debian box I had set up was just acting as a router/gateway between the internal company network, internal camera/nvr network, and the internet, so I'm not sure if they were running lighttpd, nginx, apache, or what. :?

I actually did reverse engineer the firmware a little bit at the time (I can't remember why I was doing it though). I recall I was able to unpack either the kernel or the filesystem because I remember running either the 'file' command or 'binwalk' against a binary file and seeing that the processor architecture was something weird, like powerpc or some shit. I wonder if they still have that firmware file on their website, I'm kinda interested... I do remember the brand/model (I spent a lot of time working on that damned camera system lol)

Hmm. I'm gonna go see if they still have it... [5 minutes later] They sure do, and you don't even have to freaking use binwalk to unpack their firmware! Just good 'ol "tar -xf <file>" :P

Standby, I'll post an update here after I look over these files...
aj@aj-laptop:~/sec_stuff/firmware_re/mystery_nvr/upd_900s$ ls *
-rw-r--r-- 1 aj aj 44439595 May 21 2018 d9b15-0H330003450085511224.tgz
-rw-r--r-- 1 aj aj 67 May 21 2018 d9b15-0H330003450085511224.tgz.md5
-rw-r--r-- 1 aj aj 230456 May 21 2018 dvr_logo.bmp
-rw-r--r-- 1 aj aj 202 May 21 2018 logo_def.txt

tgz_data:
total 47436
-rw-r--r-- 1 aj aj 2676927 May 21 2018 d9b15-00345.ker
-rw-r--r-- 1 aj aj 50 Aug 29 2017 d9b15-00345.ker.md5
-rwxr--r-- 1 aj aj 12374600 May 21 2018 d9b15-00855.ocx
-rw-r--r-- 1 aj aj 50 May 21 2018 d9b15-00855.ocx.md5
-rw-r--r-- 1 aj aj 27060522 May 21 2018 d9b15-0H330.rfs
-rw-r--r-- 1 aj aj 50 Aug 29 2017 d9b15-0H330.rfs.md5
-rwxr-xr-x 1 aj aj 6435312 May 21 2018 d9b15-11224.ppc
-rw-r--r-- 1 aj aj 50 Aug 29 2017 d9b15-11224.ppc.md5
¯\_(ツ)_/¯ It works on my machine...

User avatar
Gogeta70
^_^
^_^
Posts: 3247
Joined: 25 Jun 2005, 16:00
15

Re: Apache GET/POST DDoS - what to do

Post by Gogeta70 »

This is only one directory of three that I extracted from the base firmware zip file, so this is not all the
data stored in the firmware file. Now with that said...


If the '.ppc' file didn't give it away, the 'file' command sure did: This firmware runs on a PowerPC architecture CPU. The last 'file' command output indicates a 32-bit big Endian processor as well.

Also worth noting here: if my memory serves me correctly, ActiveX controls were wrapped up in .ocx files.
I thought OCX files were just basically DLL files, but I don't think I ever actually confirmed that,
so I'm not sure if the .ocx file below being gzip'd is weird or not... Time for some research.
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data$ ls
total 47420
-rw-r--r-- 1 aj aj 2676927 May 21 2018 d9b15-00345.ker
-rwxr--r-- 1 aj aj 12374600 May 21 2018 d9b15-00855.ocx
-rw-r--r-- 1 aj aj 27060522 May 21 2018 d9b15-0H330.rfs
-rwxr-xr-x 1 aj aj 6435312 May 21 2018 d9b15-11224.ppc

aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data$ file *

d9b15-00345.ker:
u-boot legacy uImage, Linux-2.6.25.00345, Linux/PowerPC, OS Kernel Image (gzip), 2676863 bytes, Wed Jan 21
07:32:54 2015, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0x0B14FB09, Data CRC: 0x96A4C618

d9b15-00855.ocx:
gzip compressed data, last modified: Mon May 21 05:36:29 2018, from Unix, original size modulo 2^32 13629440

d9b15-0H330.rfs:
u-boot legacy uImage, ver:0H330 initrd glibc, Linux/PowerPC, RAMDisk Image (gzip), 27060458 bytes, Mon Aug 28
03:02:39 2017, Load Address: 0x00000000, Entry Point: 0x00000000, Header CRC: 0x89CBCC3B, Data CRC: 0x40B0FB7D

d9b15-11224.ppc:
ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.10, stripped
[Some research later...]

So, I found an old 32-bit ocx file from around the WinXP days, here's what 'file' says for that file:
aj@aj-laptop:~$ file ./comdlg32.ocx
./comdlg32.ocx: PE32 executable (DLL) (GUI) Intel 80386 (stripped to external PDB), for MS Windows
Ok, so I confirmed that ocx files are indeed just DLL files with a different name. So, let's see what I get if I decompress that OCX file...

So upon further inspection, the OCX file is not an OCX file at all. It's a .tar.gz file that someone just renamed...
So, here's a listing of our 'OCX' tar file:
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data$ tar --list -f d9b15-00855.ocx.tar.gz
./
./conf/
./conf/http-up.sh
./conf/httpd.conf
./conf/users.db
./QT/
./QT/img/
./QT/dyna.rcc
./QT/fonts/
./QT/fonts/[fonts cut out for space reasons]
./http.ver
./Certs/
./Certs/netguard-hd-apns-key.pem
./Certs/netguard-apns-key.pem
./Certs/netguard-hd-apns-cert.pem
./Certs/netguard-apns-cert.pem
./web/
./web/md5.js
./web/RemoteWeb.cab
./web/logo.htm
./web/Components.inf
./web/liveview.html
./web/VideoViewer.inf
./web/DVRPlayer.zip
./web/favicon.ico
./web/RemoteWeb.inf
./web/images/
./web/images/ie-logo.jpg
./web/images/avertx-logo.png
./web/images/app-store.png
./web/images/google-play.png
./web/login.html
./web/logo.jpg
./web/Components.cab
./web/icons/
./web/icons/[icons cut out for space reasons]
We're definitely headed in the right direction here. You can see some interesting files already:

Everything in ./conf/:
* http-up.sh - This is probably the script that brings the web server up.
* httpd.conf - Probably a web server config...
* users.db - Should probably contain the factory default user (admin). Couldn't hurt to do a quick
check for "undocumented" accounts...

./Certs:
* Are those private key files I see? If those are actually used for securing the session
and they're not changed automatically (such as during the first boot-up), This would
mean we could now use these keys to decrypt traffic to ANY AvertX NVR of this model (at least).

Cab/zip files: ./web/RemoteWeb.cab, ./web/DVRPlayer.zip, ./web/Components.cab
* These files are what you are required to download upon your first visit to the NVR web page.
One of these files should contain the ActiveX control...


First, let's take a look at our Conf files:

httpd.conf:
ServerRoot "/etc/appWeb"
DocumentRoot "/var/www/cgi-video"

Listen 0.0.0.0:80

TypesConfig mime.types

LoadModulePath /lib ./bin ../bin ../bin/Debug ../bin/Release
LoadModule admin libadminModule
LoadModule auth libauthModule
LoadModule cgi libcgiModule
LoadModule copy libcopyModule
LoadModule egi libegiModule
LoadModule upload libuploadModule

AddHandler authHandler
AddHandler egiHandler .vdo .get .set index help viewer login Components
AddHandler copyHandler
AddHandler uploadHandler

<Directory $DOCUMENT_ROOT/auth>
AuthDigestQop auth
AuthUserFile users.db
AuthType digest
AuthName "DVR"

Require user admin user max Admin User
</Directory>

LimitRequestBody 614400

KeepAlive on
Timeout 60

FileUploadDir "/upgrade/net"

Group nobody
User nobody

DirectoryIndex index
Looks like an Apache config file to me. I'm a bit surprised, systems like this usually run servers like lighttpd and other "micro" web servers.

http-up.sh:
!/bin/sh
if [ $1 ]; then
if [ $1 = "-a" ]; then
cp -apR /nfs70/max_tmp/web/cgi-video/* /mtd0/data/web/
cp -apR /nfs70/max_tmp/web/cgi-video /var/www/
fi
if [ $1 = "-w" ]; then
wget ftp://DynaColor:dynacolor@ftp.dynacolor ... 200Web.cab" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; -P/mtd1/web
wget ftp://DynaColor:dynacolor@ftp.dynacolor ... 200Web.inf" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; -P/mtd1/web
wget ftp://DynaColor:dynacolor@ftp.dynacolor ... Viewer.ver" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; -P/mtd1/web
wget ftp://DynaColor:dynacolor@ftp.dynacolor ... Viewer.ocx" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; -P/mtd1/web
fi
else
echo "cp -apR /nfs70/max_tmp/web/cgi-video /var/www/"
cp -apR /nfs70/max_tmp/web/cgi-video /var/www/
fi
Mmmkay, so the name of this script is a bit deceptive. It doesn't seem to start a web server at all, it just copies
some data around. Interesting to note here is the FTP server address and credentials hardcoded into this file. Huge
mistake - they can NEVER change that username/password or risk every single customer (that uses products with
these credentials) not receiving any more updates. This is a classic example of security through obscurity, and a very

good example of why it is bad. Don't hard-code credentials, kids.

users.db:
1: admin: DG200: c754d474ae5aca8294aabd0c3674e5fe
1: user: DG200: 041e78b9348e48b872d62ba8f64cc5fc
So the good news is there are no backdoor accounts here. Looking in the manual for the NVR, you can find the following:
Logging In To the Recorder

1.Right-click in the Live screen.
2.Click admin or user, depending on your account.
3.Use the on-screen keyboard or a USB keyboard to type your password.
The default password for the admin account is 1234.
The default password for the user account is 4321.
4.Click OK.
However, I have run into something concerning; I know both the plaintext and hashed password for the admin user.
Doing a search for this hash value (the hash of '1234') returns nothing, which is odd for any common hash algorithm.
So, they've either rolled their own hash algorithm (oh god, I hope not...), implemented an existing hash algorithm
incorrectly, or they are perhaps transforming the output hash value somehow (even just a simple xor encryption would
work). Alternatively, they could be using a lesser-known hash algorithm, though I feel this is unlikely.

I do know that these password hashes don't match MD5, MD4, or double MD5 hashes. This may require further investigation.


Now, let's take a look at those PEM files:
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data/ocx/Certs$ ls
total 24
-rw-r--r-- 1 aj aj 2000 May 21 2018 netguard-apns-cert.pem
-rw-r--r-- 1 aj aj 4286 May 21 2018 netguard-apns-key.pem
-rw-r--r-- 1 aj aj 2009 May 21 2018 netguard-hd-apns-cert.pem
-rw-r--r-- 1 aj aj 4306 May 21 2018 netguard-hd-apns-key.pem
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data/ocx/Certs$ for i in $(echo *); do echo -en "\n$i:\n\t"; grep -A3 "BEGIN" $i; done

netguard-apns-cert.pem:
-----BEGIN CERTIFICATE-----
MIIFmDCCBICgAwIBAgIIWBFJqT7Bx24wDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3

netguard-apns-key.pem:
-----BEGIN CERTIFICATE-----
MIIFmDCCBICgAwIBAgIIWBFJqT7Bx24wDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
--
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDmKdZKmOLkRFcm
MGpXJ1Jn2lLgXOvL0ESexgcCHjqdUfM2w1wmQUKN17BwHt7IB0YyOUm/21qdyh4u
87PBjEaerc6ItTZbbwsFdSPeLzqNPlCe+DumyD9RK8LrfX/gAh5GXTDjJnbFhuiD

netguard-hd-apns-cert.pem:
-----BEGIN CERTIFICATE-----
MIIFnjCCBIagAwIBAgIIGB8DpxmaefcwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3

netguard-hd-apns-key.pem:
-----BEGIN CERTIFICATE-----
MIIFnjCCBIagAwIBAgIIGB8DpxmaefcwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
--
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCmT+6o+PP7P3rf
N9E/7Bcdxuw71tGymOLMUJyoT3wDAereFjrWhwWKhJXBP1n8Xo/tzOmVUtObqjh9
uza0kjHawicntwhF8hHI8lYYwZb/e9fFPCqlWeWULmuDH/flQyhEWGkWVPowtEQH
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data/ocx/Certs$
There are no words this, just head shaking. Moving on...


Checking just the DVRPlayer.zip file, we see this list:
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data/zipcab$ unzip -l DVRPlayer.zip
Archive: DVRPlayer.zip
Length Date Time Name
--------- ---------- ----- ----
570408 2018-05-21 10:27 DVR_Player.exe
0 2015-12-04 17:13 resource/
74 2014-01-14 10:18 resource/autorun.inf
445166 2018-05-21 10:39 resource/Components.cab
12720 2016-04-06 17:01 resource/Components.inf
18944 2014-01-14 10:19 resource/expand
3783672 2008-07-29 08:05 resource/mfc90u.dll
1857 2014-11-14 10:12 resource/Microsoft.VC90.CRT.manifest
2354 2014-11-14 10:12 resource/Microsoft.VC90.MFC.manifest
572928 2008-07-29 08:05 resource/msvcp90.dll
348160 2013-12-26 13:23 resource/msvcr71.dll
655872 2008-07-29 08:05 resource/msvcr90.dll
7278 2014-01-14 10:18 resource/Player.ico
18048 2014-01-14 10:18 resource/PlayerLogo.jpg
5596712 2018-05-21 10:27 resource/Remote200Web.ocx
3069992 2018-05-21 10:27 resource/VideoViewer.ocx
Yeah, I think we found our real ActiveX control(s) this time ^_^
However, the target has now changed. My whole purpose here was to dig into
why the password input validation is so fucky. Initially, I thought the issue was in the ActiveX
controller, but I realized that actually makes no sense. You have to log in the very first time, before
downloading the ActiveX control, so it makes sense the ActiveX control doesn't handle logins.
I'm not sure why I didn't catch that before... :roll:

Anyway, when we found the users.db file above, we discovered that the web server is handling the authentication.
We also found that the hash algorithm they're using seems to be very uncommon or modified in a way to be
unrecognizable. Given that the web server does such a poor job at sanitizing password input, I have a hard time
believing we're running Apache here. It feels like they just mimicked the Apache config format and wrote their own web
server? Let's take a look...


Before going to find the rest of the filesystem, I decided to check on the 'ppc' binary that was in the same folder as
our "tar.gz" "ocx" file: d9b15-11224.ppc. I won't post the entire string dump (which is quite long), but the language
found in the binary tells me that this file is most likely the NVR UI application - the one that runs after bootup and
is displayed if you have an actual screen plugged into the NVR box. However, there was an interesting string I found
in the string dump:
aj@aj-laptop:~/sec_stuff/firmware_re/Avertx_nvr/upd_900s/tgz_data$ strings -n8 d9b15-11224.ppc | sort | less
[... other string dump data ...]
401 - Unauthorized: Access is denied due to invalid credentials.
[... other string dump data ...]
This makes me wonder, is the web server built into this binary? Let's load it up in a debugger/reversing tool, such as
radare2. Apparently, this binary has been stripped (according to the 'file' command), so it may be a bit difficult to
determine if it's opening a port on port 80 or 443. Let's see...

Yes. I am fairly certain that this binary actually is also the web server. Unfortunately, this binary gave
the Radare2 analyzer some problems (the analyzer never finished analyzing the program). Since the analyzer doesn't
work, I'm unable to find any cross-references to function calls or data within the program. However, even without the
analysis, I was able to see that the "socket, bind, listen, accept" functions were all imported. I also found a string in the string dump referring to users.db. There are also various strings in the binary referring to things such as the document root, "appWeb", etc.

I can't be bothered to figure out why this binary is hanging up the Radare2 analyzer, otherwise I would totally look
for the code that handles the password input in the binary. But, I just can't be bothered to put that much effort
into this endeavour when I don't even have the hardware anymore and my tools aren't working right for this binary :P

Anyway, I decided to go ahead and release the name of the system. For fairly obvious reasons, I did not want to
disclose information about a security system currently used by my previous employer. However, I have reason to believe they are no longer using this system, so here you go:

The system in question here is the AvertX NV160-P2B Network Video Recorder system:
https://www.avertx.com/downloads/" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; Downloads page
https://www.avertx.com/nvr-firmware-11224/" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; Firmware download
https://www.avertx.com/content/recorder ... Manual.pdf" onclick="window.open(this.href);return false;" onclick="window.open(this.href);return false; User manual

If anyone wants to pick up where I left off, I'd love to see what you find!
¯\_(ツ)_/¯ It works on my machine...

Post Reply