Wednesday 4 December 2013

Blocking Asterisk SIP Invite attacks with fail2ban

There's a lot of fuss about people putting too much trust into a program called fail2ban when using it with Asterisk to block SIP attacks.

Such as:

http://forums.digium.com/viewtopic.php?t=78988

Whilst I fully agree that simply installing fail2ban and relying on that as your only protection against SIP hacks is foolish, I do think it is still a useful tool.

The biggest current problem with it is that while it's quite good at stopping Register attacks, it doesn't do anything out of the box to protect against Invite floods.  This is where attackers send in SIP Invite messages to attempt calls and to brute-force passwords.

The good news is that simply adding an extra regex line to the fail2ban config can help in some cases.

This works with Asterisk 1.8 (possibly newer versions, I've not tested yet).  There is a big change you must make first.  Asterisk comes with a setting in sip.conf called "allowguest" which controls whether you allow un-authenticated SIP calls in or respond with a 401 Authentication Required message.  It is normally recommended to set this to "no" to stop unsolicited calls.  This addition to fail2ban will NOT work with this set, you must set it to "yes" or Asterisk will not log anything for fail2ban to act on.

Lots of people will say that this is a bad idea (and I don't necessarily disagree with them).  For my own use, I need this set anyway.  There is a possible argument saying that you're safer setting it to "yes" and allowing fail2ban to catch call attempts than leaving it to "no" and not knowing about these calls coming in.
Be aware that your default context (i.e. the context that external calls fall in to) must be carefully set up so as to only include extensions that you really want exposing to the outside world.  This would normally be your inbound phone numbers only.
If someone manages to guess one of your inbound numbers (or intentionally sends in calls to your numbers because they already know them) then you could get unsolicited "spit" (SIP spam) calls.

If you decide you want to do this or you already need allowguest=yes for some other reason like me, then here is what to do...

Find the list of regular expressions in the file /etc/fail2ban/filter.d/asterisk.conf (on Debian Wheezy, may be elsewhere on other systems) and add this line:

NOTICE.* .*: Call from '.?' \(<HOST>:.*\) to extension '.*' rejected

Reload fail2ban and it should stop multiple Invites from the same source IPs.

I have to admit, I have only just done this and I have so far only done a small amount of testing using SIPp.  So there could be cases it doesn't catch Invites and it may block valid Invites sometimes.  I will continue to test and update this post as I find more things out.

In general you should always be keeping an eye out on what is happening to your Asterisk installations (or any SIP system for that matter, this isn't limited to Asterisk).  My next plan is to write a monitoring tool in Python that'll keep an eye on logs and activity for unusual things going on.

Tuesday 29 October 2013

Quickly install Asterisk and Dahdi on Debian Wheezy

Most how-to guides I've seen on setting up Asterisk with Dahdi on Debian start off by telling you to download source from Digium and compile it yourself.

That's fine sometimes but I prefer to stick to the Debian maintained packages on a production system.

The main problem with this is that you don't get the Dahdi kernel modules in the Dahdi package, you need to build them on your system.  Fortunately, the Debian Module-Assistant makes this easy.

It's worth noting that even if you don't have an ISDN or analogue card in your system, if you are using Asterisk 1.8 or lower, you'll need Dahdi for certain things such meetme conferences as they need it for a timing source.

Getting Asterisk installed is just a case of installing the right packages.  Libpri is needed if you are going to be using a PRI (E1/T1/J1) card or a BRI card (yes, really, because for BRI to work Dahdi emulates PRI):

apt-get install asterisk libpri1.4 asterisk-dahdi
You'll get Asterisk 1.8 with Debian Wheezy.  During the install you'll be asked for your countries ITU telephony code.  This is the country code needed to dial you from other countries, for the UK it is 44.

At this stage you have a working Asterisk installation but Dahdi will fail to start due to missing kernel modules.  You must build these modules from source using module-assistant.  Install the things you need to build:

apt-get install linux-headers-`uname -r` dahdi-source
m-a a-i dahdi
'm-a' is short for module-assistant!

Now you can configure and start Dahdi:

dadhi_genconf
service dahdi restart
asterisk -rvvvvv
dahdi show status
That's it, it's actually a very quick and easy process. 
 

 
 
 

Wednesday 2 October 2013

LXC Linux Containers on Debian Wheezy

Linux Containers (LXC) is a fairly new operating-system level virtualisation technology.  

Getting it working in Debian Wheezy isn't as straight forward as it could be right now.  There are a couple of fixes needed (which I'm sure are in the pipeline).  Here are my notes on getting it going.  This may not be the best way of doing it and certainly wont be the only way but it works!

Also be aware that LXC is considered by many to not be production ready yet.  There are potential security issues.  This isn't an issue when you are using it yourself just to play with or as I do, to set up virtual systems on a server or desktop where I'm the only user!


How To Install LXC on Debian Wheezy and configuring the host


Install required packages:
  apt-get install lxc bridge-utils libvirt-bin debootstrap
Add this line to fstab:
  cgroup    /sys/fs/cgroup    cgroup  defaults    0  0

Mount it and make sure it is mounted OK

Set up a network bridge on the host in /etc/network/interface along the lines of:
  auto br0
  iface br0 inet static
        address 192.168.0.100
        netmask 255.255.255.0
        gateway 192.168.0.1
        bridge_ports eth0
        bridge_fd 0
        bridge_maxwait 0

Bring it up:
  ifup br0

and check it's OK.


Creating a virtual system (container)

Generate the container and it's root file system using the supplied script:
  lxc-create -n myvps -t debian
where 'myvps' is the host name you want to give the container and also the folder it's file system will be in.  You'll be asked various questions, they're self explanatory.

Note - I'll be using 'myvps' throughout the example, the commands will fail if you don't replace this with the real host name.  Copying&pasting directly from online how-to guides is never a great idea :)

If you don't know what a pre-seed file is then you can just skip that question that comes up at first!

Edit the config file /var/lib/lxc/myvps/config to add network device config such as:
  ## Network
  lxc.network.type                        = veth
  lxc.network.flags                       = up
  lxc.network.hwaddr                      = 00:FF:00:00:00:01
  lxc.network.link                        = br0
  lxc.network.name                        = lxceth1
  lxc.network.ipv4  = 192.168.0.1/24

Each container needs a unique MAC and device name (and IP, obviously).  Omit the last line if you want DHCP.

Edit the network config for the container /var/lib/lxc/myvps/rootfs/etc/network/interfaces to add the network devices such as:
  auto lxceth1
  iface lxceth1 inet static
  address 192.168.0.1
  netmask 255.255.255.0
  gateway 192.168.0.1
  dns-nameservers 192.168.0.1
Or as DHCP if no IP was put in the config file above.

At this point, you should be ready but there are a couple of fixes needed which the lxc scripts for Debian don't currently cover.

Fixing LXC Debian set up

At the time of writing, there are a couple of problems with the way the lxc-create script works in Debian.  One of these is that it doesn't create the necessary tty1, so manually add it:
  mknod -m 660 /var/lib/lxc/myvps/rootfs/dev/tty1 c 5 1
At this stage the container will actually start up so do that:
  lxc-start -n myvps -d
Note - the -d option detaches from the container's console.  You need to do this or you'll be permanently attached to it unless you completely stop the container!

Then console to the container:
  lxc-console -n myvps
This is safe because you can disconnect at any point using the "ctrl+a q" combination and the container stays running for you to connect to later on.

Log in using the root password you set during the container configuration process.

sshd will be running but broken, keys need regenerating:
  dpkg-reconfigure openssh-server
Two last things to fix are to add a default route and put a working dns server into /etc/resolv.conf (which is easiest from the host machine rather than the container due to lack of a text editor!).

Now you have a very basic Debian install.

To fix locale warnings with apt-get:
  dpkg-reconfigure locales 
To make containers start on boot of host (do this on the host, not the container):
ln -s /var/lib/lxc/myvps/config /etc/lxc/myvps
And make sure LXC_AUTO is set to "true" in /etc/default/lxc on the host so it starts on boot (if you want that).

Once you are familiar with this, setting up containers is very easy.  It will be even easier once the lxc-create debian script is improved.  I have used LXC in Ubuntu too and it is stupidly easy to get it going (although as a result you are given less options and less flexibility unless you re-configure it).

Wednesday 7 August 2013

Nexus 4 red light of death

OK just a quick note this one but it might help some people out.

The other day it seemed that my beloved Nexus 4 suffered from the red light of death.  The battery had died overnight.  I plugged the phone in at work, it normally leave it connected to my PC there during the day and it does charge.  However in this case, it just wouldn't turn on and I kept getting the red light of death.  It was showing the charging animation still.

I plugged it into a supposed 1 amp power supply (which I normally use with a Raspberry Pi) but it still wouldn't turn on which had me worried.

Long story short, when I got home I connected the proper charger up (well actually my nexus 7 charger) and it came back to life! 

So if you seem to have the red light of death problem make sure you are using a decent charger - ideally the original nexus 4 one or better.  The 1 amp PSU I had at work clearly isn't really capable of supplying 1 amp. 

Thursday 2 May 2013

Hacking the Xenta IP-11IR-H264-PT IP camera from Ebuyer part three - network access

Just a quick update.  I was going to try to get sshd working but decided to try to get telnetd working first as it is already on there (but disabled).

Firstly, to get to a command line through serial without having to use the ctrl+z method described previously.  Get to the command once once using that method, then use vi to edit the file /etc/boottab, this controls the programs that start on boot.

Find a line near the end:

/bin/vs/vs_auto.sh
and add an ampersand at the end like this:

/bin/vs/vs_auto.sh &
Then save the file.  This will background the vs_server program so you can get to the command line with it running.

The device has a watchdog running on it, this looks for various events and makes sure various processes are running.  If they are not then the camera reboots.  It is this that reboots the device if you stop vs_server by doing ctrl+c or ctrl+z once it's finished booting before editing the boottab file.

There's not much you can do with the watchdog as it is controlled by the program /bin/vs/vs_server which is a compiled ELF executable and not editable.

You can run telnetd now but you will find that it attempts to start a 2nd copy of vs_server, which then crashes and causes another reboot almost as soon as you telnet in!

To get telnet starting at boot, find a comment in the /etc/boottab file that reads:

#start Telnetd
And add:

/bin/telnetd &
On the next line.  Save and close the file.

Now your problem is stopping vs_server running a second time when you telnet in.  Edit the file /etc/profile file (which is executed whenever a user logs in) and find the line:

/etc/boottab ipcamera
Remove this line and replace it with the following section of code:

if [ -z "$(pidof vs_server)" ]
  then                    
  /etc/boottab ipcamera
fi
Save and close the file.  This code means the vs_server is only started if the vs_server process does not already exist.  So vs_server still starts when the camera boots (as well as the watchdog it has the web server, rtsp server etc... built into it).  But, it wont attempt to run again when you telnet in, or log in via any other method for that matter.

That's it.  Now you can put away your serial cable and telnet to your camera whenever you want!
 

Hacking the Xenta IP-11IR-H264-PT IP camera from Ebuyer part two - getting root access over serial

OK so this next post was supposed to be about my external web interface to view the camera from Linux.  

I've decided to skip that as my new soldering iron arrived so I have now successfully got serial access to the camera and modified part of the web interface directly on the camera itself.

Like many embedded devices these days, this camera is of course based on Linux.  More often than not there is a UART/serial port hidden on the PCB somewhere which usually consists of a 4 pin connector or 4 pads on the board.

On opening up the Xenta/Foscam casing, I located what appears to be a JTAG header but also 4 through-hole pads at the front of the board that looked like a hopeful candidate for a UART.  Firstly, I soldered 4 wires to these headers:


Next, to figure out what the pins are.  A 4 pin UART/serial will consist of a +'ve connection, -'ve connection, TX and RX.  Powering up the camera and using a multimeter in volts mode allows the + and - to be identified.  In this case, two pins had a solid 3.3v across them.  So the other two are clearly RX and TX.

Now to get it hooked up to a PC.  I have a nice little serial-to-USB adaptor (based on the common FTDI chipset) which is switch-able between 3.3v and 5v and very handy for things like this, I bought it off ebay a year or so ago.


I used the breadboard in-between so I could easily swap the wires around to figure out what was what.  
The serial pins on the Xenta/Foscam turned out to be as follows, the order from left to right is as you look at the PCB from the front with the camera the correct way up - as you see it in the pictures:

+3.3v - GND - TX - RX

Make sure you use a serial adaptor that is 3.3v not the more common 5v!

Then it's just a case of firing up your friendly serial communication program.  I use minicom.  Connect using these settings:

  • baud rate: 115200
  • data bits: 8
  • parity: N
  • stop bits: 1
  • hardware & software flow control: off
Then power up the camera and you'll see the console messages fly past:


 Right near the start of the boot process you can halt the boot by pressing a key when prompted and go into the bootloader menu.  This uses the common uboot software.  There's not really much you can do here other than reloading firmware etc...  This shows the list of bootloader commands available:


Of much more interest is getting to the Linux command prompt with the filesystem mounted.  If you let the camera finish booting normally then you are locked out of the command line.  You can press ctrl+c or ctrl+z here to stop the running process but after a couple of seconds the camera will reboot itself (I guess this is some protection against people doing this kind of thing built into the software).  
To get to a stable Linux prompt without the device rebooting itself, during the boot process (but after the "press any key" prompt for the bootloader), keep hitting ctrl+z and it will eventually halt the boot process and drop you back to the command prompt with no rebooting:




The camera is using an operating system called HiLinux which seems to be Chinese made.  As is often the case with embedded systems, it's using Busybox which gives most of the common Linux commands you'd expect.  The text editor 'vi' is present too.

I discovered most of the web interface files in the folder /bin/vs (which seems an odd place for them!).  To get going, I modified the "mobile.html" file which provides the next to useless web interface page for viewing on phones.  I replaced any reference to the file "auto.jpg" with "snap.jpg" in that file using vi and then saved it  "auto.jpg" gives you a very small, low resolution image where as "snap.jpg" gives a full size, full resolution image.

Now you have a usable web interface page for Linux (and anything else with a Javascript enabled web browser capable of displaying a jpeg image!):




That's all for now, next I intend to install an ssh server so I can copy files to/from the device easily.  I noticed that telnetd is running so I might just be configure that to allow network access.
I would also like to figure out how it decodes it's firmware so I can de-construct that myself and create my own firmware with the new web interface I plan on building.





Wednesday 24 April 2013

Hacking the Xenta IP-11IR-H264-PT IP camera from Ebuyer part one - Foscam firmware

A while ago I bought an IP camera from Ebuyer.com here in the UK because it was on offer and seemed too cheap to be true.  The camera is branded Xenta and the part code is IP-11IR-H264-PT.  It's still for sale quite cheaply here:

http://goo.gl/e7u6q

Although a bit more than I paid now.

It turns out this camera is a re-badged Foscam FI8608W, the main circuit board inside the camera even has this part code on it:

http://foscam.us/products/foscam-fi8608w-wireless-ip-camera.html

You can upgrade the firmware on the Xenta branded camera to the latest Foscam firmware.  I've put the firmware I found here:

http://goo.gl/sDV0E

That was the newest version I could find and given that the FI8608W is a discontinued product, I doubt there'll ever be another update. 

The bad news is that the web interface in this firmware still requires an Active-X plugin to view the video.

So despite the EBuyer page specifically listing Linux as a "supported OS" it absolutely is not.  I would also assume it wont work on a Mac either.  I have even spoken to EBuyer tech support about this but they haven't edited the page.

In the next post, I will describe how I built my own very simple web interface to drive the camera from any web browser with no need for any stupid plug-ins or platform dependencies.

Arduino Leonardo in Linux with Arduino 1.0.1 (Ubuntu 12.04)

I recently bought an Arduino Leonardo clone.  Previously I always used Duemilanove and clones which have been around for years and always just worked.
 
I use arduino-core, avrdude and a Makefile in Ubuntu 12.04, the version of Arduino here was 1.0.1 which claims to support the Leonardo.  I found that the definition for the Leonardo in boards.txt was commented out and when uncommented, still didn't work.

At the command line I was seeing the following error:

ioctl("TIOCMSET"): Broken pipe
ioctl("TIOCMSET"): Broken pipe
avrdude: stk500_getsync(): not in sync: resp=0x3f
ioctl("TIOCMSET"): Broken pipe
 After much Googling, I found others with the same issue but no solution.

The solution was surprisingly simple in the end, just copy the boards.txt definition for the Leonardo from the latest version of the Arduino source (1.0.4 at the time of writing)!  You could use the whole code from the arduino.cc site but I always prefer to stick to the versions I get from my OS's repositories.  The working definition is:

leonardo.name=Arduino Leonardo
leonardo.upload.protocol=avr109
leonardo.upload.maximum_size=28672
leonardo.upload.speed=57600
leonardo.upload.disable_flushing=true
leonardo.bootloader.low_fuses=0xff
leonardo.bootloader.high_fuses=0xd8
leonardo.bootloader.extended_fuses=0xcb
leonardo.bootloader.path=caterina
leonardo.bootloader.file=Caterina-Leonardo.hex
leonardo.bootloader.unlock_bits=0x3F
leonardo.bootloader.lock_bits=0x2F
leonardo.build.mcu=atmega32u4
leonardo.build.f_cpu=16000000L
leonardo.build.vid=0x2341
leonardo.build.pid=0x8036
leonardo.build.core=arduino
leonardo.build.variant=leonardo
The file is /usr/share/arduino/hardware/arduino/boards.txt

Then uploading worked fine.  Although I've not tested it, I suspect the same fix will get the Leonardo working in the Arduino IDE too.

 One last note is that uploading code to the Leonardo is a bit different to older boards because of the way the device presents itself as a HID keyboard and mouse once it has fully booted up.  So to upload code you have to put it into bootloader mode first.  There are two ways of doing this:

  1. Press and release the "reset" button the board itself.
  2. Connect to the serial port at 1200baud and then disconnect again.  You can write a simple script to do this for you, the following python script works OK:
#!/usr/bin/python
import serial, sys
serialPort = '/dev/ttyACM0'
try:
    serialPort = sys.argv[1]
except:
    pass
ser = serial.Serial(port=serialPort, baudrate=1200, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)
ser.isOpen()
ser.close()
Either way, you can tell the board is in bootloader mode because the pin 13 LED will be pulsating.  It will stay like this for about 7 seconds and you can upload your code.