Sunday, December 16, 2012

Running omxplayer from the command line easily using alias

Although I have previously written about running omxplayer via GUI, sometimes I like to control it via command line.
However, since I have my raspberry pi hooked up via HDMI and I like the show to be fullscreened, this requires typing:
omxplayer -r -o hdmi FILE
each time.
In order to make this easier we can use aliases. An alias lets you run a command with a shorter command. For instance:
ll is really an alias of ls - l

You can see what aliases you have by typing alias in the command line.
To temporarily add an alias you can use the command:
alias play='omxplayer -r -o hdmi'

However, I want to permanently add this. To do that, I'll edit /home/pi/.bash_aliases
you can do this using vim or nano. Simply add the line alias play='omxplayer -r -o hdmi' to this file.

Make sure you log out and log back in for this change to be made. Now we can just type: 

play FILE

To be able to easily find and intelligently play videos automatically, see this page:
http://stevenhickson.blogspot.com/2013/03/playing-videos-intelligently-with.html

Consider donating to further my tinkering.


Places you can find me

Wednesday, October 24, 2012

Fixing Raspberry Pi Crashes

The most common crash I've experienced/heard about posts an error that says:
raspberrypi kernel: <1-1.1:1.0: eth0: kevent 2 may have been dropped

This happens to a lot of people who are torrenting (probably using transmission) and especially to external HDDs. It tends to turn up in /var/log/messages and/or /var/log/kernel and/or /var/log/dmesg. You can cat these to see if the error is there.

There are a couple of reasons that this happens and the following has been the way I have managed to fix it (Supposedly there is a bug fix in a distant future kernel release).

Reason 1:

Memory isn't available fast enough and for some reason the kernel crashes.
I did two things to fix this.
1: Increase the number of min_kbytes by editing sysctl.conf
 (using vim or nano or whatever)
Start by opening a terminal then type the following to edit the proper files.

sudo nano /etc/sysctl.conf

at the end of the file add the following line
vm.min_free_kbytes = 16384

*Note, if that doesn't help, try increasing the number
Example:
vm.min_free_kbytes = 32768

Then save and exit the file.

The second thing I did was to add an option to the boot command

sudo nano /boot/cmdline.txt

At the end of the line, add: smsc95xx.turbo_mode=N

Save, exit the file, and then reboot (sudo reboot)

Reason 2:

Your usb hub has a problem where it is creating a feedback loop.

Tape over the +5V pin on the USB cord (You should use a multimeter to find it). Fixed, though a bit sketchily.



Check out my other Raspberry Pi Fixes/How tos:
http://stevenhickson.blogspot.com/2012/10/using-raspberry-pi-as-web-server-media.html
http://stevenhickson.blogspot.com/2012/08/setting-up-omxplayer-gui-on-raspberry-pi.html

Consider donating to further my tinkering.


Places you can find me

Wednesday, October 10, 2012

Using the Raspberry Pi as a Web Server, Media Server, and Torrent Box

So you've set your Raspberry Pi up.
If not you might want to check out this page first.
So now you want to set your Raspberry Pi up as a media/web/everything else server.

Before any of these, make sure your raspberry pi ip address is static. You can set this by opening up a terminal and typing in:
sudo nano /etc/network/interfaces

(Feel free to use gedit or vim or whatever you want. I like vim)
You should now be looking at a file. Change the line:
iface eth0 inet dhcp
To:
iface eth0 inet static
address 192.168.1.10
netmask 255.255.255.0
gateway 192.168.1.254

where the gateway is your router and the address is the ip address you want. Save the file and reboot (sudo reboot) and now your ip should be static.

Luckily, SSH is already enabled on the Raspbian image so we won't go into that. However, if you want to SSH externally, you should install something like SSHGuard for protection and then in your router config redirect port 22 traffic to your Raspberry Pi.


Section 1: Webserver

Installing apache is easy. Just open a terminal and type:
sudo apt-get install apache2

This will set up a webserver for you with the files at /var/www being your web directory. Modify those files how you feel like and if you want to make it publicly accessible then configure your router to forward port 80 to your raspberry pi's ip address.

Section 2: VNC

This is an optional thing since you can port X over SSH. But if you want vnc. All you have to do is open up a terminal and type:
sudo apt-get install tightvncserver

When it is finished installing it should ask for a password. If it doesn't or you need to change it. Just type vncpasswd to reset it.
Then type tightvncserver and a new instance will start. You can kill it by typing tightvncserver -kill :1

To use this externally, you will have to open up port 5801 (for the first instance, 5802 for the second, etc.)

Section 3: Media Server

Start off by mounting all of your external HDDs. If you have a Raid array that is great, if not, I have a handy little hack for you.
edit fstab by opening up a terminal and typing:
sudo nano /etc/fstab
Add each hard drive to the file, mine looks like this:
/dev/sda1 /media/Kingsley ntfs-3g defaults 0 0
/dev/sdb1 /media/HarvardMulligan ntfs-3g defaults 0 0
/dev/sdc1 /media/Moloch ntfs-3g defaults 0 0

(Make sure the folders in /media exist and their permissions are set properly with chmod, otherwise this won't work)

You really should set up a RAID array or something, but lets say you like to live by the seat of your pants and don't care if one of your HDDs fail and you want to access them all at the same time in one convenient directory. To do this you can use mhddfs. Install it by typing:
sudo apt-get install mhddfs

When its done installing, open fstab back up and after the lines with your HDD, type in something like what is shown below:
mhddfs#/media/Kingsley,/media/HarvardMulligan,/media/Moloch /media/ALLOFIT fuse defaults,allow_other 0 0

So my final fstab file has this at the bottom:
/dev/sda1 /media/Kingsley ntfs-3g defaults 0 0
/dev/sdb1 /media/HarvardMulligan ntfs-3g defaults 0 0
/dev/sdc1 /media/Moloch ntfs-3g defaults 0 0
mhddfs#/media/Kingsley,/media/HarvardMulligan,/media/Moloch /media/ALLOFIT fuse defaults,allow_other 0 0





where mhddfs mounts all of the drives to /media/ALLOFIT (which I previously created and set permissions for) and I can write to that and mhddfs will figure out where to put it for me.
Now just sudo reboot

Interesting tidbit: You can use sshfs (their is a Windows version call win-sshfs) to access these drives securely through ssh. This way you don't have to worry about Samba and you can access these files graphically using the internet.

Section 4: Torrent Box

So now you want to be able to torrent (let's assume completely legally) things directly to your server/external HDDs.
Simply install transmission by opening up a terminal and typing
sudo apt-get install transmission-daemon

Now we need to edit some settings, stop the daemon and open up the settings file by typing:
sudo service transmission-daemon stop
and
sudo nano /etc/transmission-daemon/settings.json

You will need to change a couple of settings.
Change your download directory to where you want your downloads, I use my external HDDs:  "download-dir": "/media/ALLOFIT",
Now to set up some security. Change the following text requires the ""s but numbers and true/false don't:
"rpc-authentication-required": true,
"rpc-enabled": true,
"rpc-password": "YourPasswordHere",
"rpc-port": 6669,
"rpc-username": "YourUserNameHere",

You can change the port to anything but it's probably a good idea to change it from the default to avoid brute force script kiddies.
Now start the daemon back up by typing
sudo service transmission-daemon start

Now open up a webbrowser on any computer in your network and type in your raspberry pi's ip address followed by :port. Ex: 192.168.1.10:6691
If you want to access this externally, just forward the port you chose to your raspberry pi ip address in your router config.

Now you are done.

To use transmission to its fullest potential and automatically download media:
http://stevenhickson.blogspot.com/2013/03/automatically-downloading-torrents-with.html


Check out my other Raspberry Pi Fixes/How tos:
http://stevenhickson.blogspot.com/2012/08/setting-up-omxplayer-gui-on-raspberry-pi.html
http://stevenhickson.blogspot.com/2012/10/fixing-raspberry-pi-crashes.html

Consider donating to further my tinkering.


Places you can find me

Friday, October 5, 2012

How to Implement Buffer Overflow


Buffer overflow exploits are commonly found problems which can cause irrevocable damage to a system if taken advantage of. The only way to prevent them is to be careful about coding practices and bounds check to make sure no kind of input, stream, file, command, encryption key, or otherwise can be used to overwrite a buffer past bounds. The problem with this is that many libraries, programs, and operating systems used by programmers already have many of these exploits in them, making prevention difficult if not impossible.

That being said, here is kind of how it works (all examples run in Windows XP using gdb):
The files used for exploit are named vulnerable_code (courtesy of Dr. Richard Brooks from Clemson University) and they can be found here: 

(All code is licensed under the GPL modified license included at the google-code address. It is simply the GPL v3.0 with the modifier that if you enjoyed this and run into me somewhere sometime, you are welcome to buy me a drink).

The link above also includes all the assembly files used to create shellcode, nasm to assemble it, and arwin to find the memory locations. It should have everything you need.

Note: Bear in mind that the memory locations will probably be different for you and you will have to find them yourself (probably by writing AAAA over and over again in memory).

IMPORTANT:
This tutorial is used for explanation and education only. Do not copy my examples and turn them in for a class. You will get caught and get in trouble and you won't learn anything and I will program a helicopter to hunt you down autonomously as revenge.



Exploit 1: Arc Injection
            The easiest method of buffer overflow, arc injection, was the first attempted. VulnerableCode_1.c was used for this for two reasons. Firstly, because VulnerableCode.c brings a character into an integer array, which doesn’t allow us to overwrite ¾ of memory. Secondly, because VulnerableCode_2.c doesn’t flip all the memory into little endian form (which is good for Shellcode but makes typing words awkward).
The exploit taken advantage here is two-fold but wouldn’t necessarily have to be depending on how it was done. First, vulnerable data would have to be overwritten in order to take advantage of the system function used in the ArcInjection function. The main function calls the ArcInjection function with the arguments of a predefined char array named command. This means that the predefined array is stored somewhere in memory and may be accessible. Using the gdb debugger, the memory address of command was found to be at 0x22ccf0. If this string in memory can be changed, the program can be made to run unauthorized code. Conveniently, the buffer in EnterDataToLocalBuffer is at the memory address 0x22ce50, which is previous to the command string, meaning it can be overwritten.
So to take advantage of this, the command ./VulnerableCode_1 2 ArcInject.txt was used, with ArcInject.txt being shown in hex below (using a standard hex editor):

The 2 command makes the EnterVulnerableDataToLocalBuffer run, which has only a buffer of 14 characters. The above hex overwrites the unimportant data with the letter A (0x41), the rest of the data is overwritten with what is already there in memory just in case it is important. This is a precaution that is not necessary if you know what needs to be reserved. The key points of the hex above are the ESP which starts at 0x48, the function return value at 0x4C, and the command string at 0xA0. These important parts are overwritten in the memory by being shifted the correct amount from where the buffer starts, hence the large amount of arbitrary As.
The function return pointer, shown in hex at 0x4C and in memory at the shifted location, is overwritten to 0x004015f9 which is the location of the assembly instructions in main preceding the arc injection function. This means that when EnterVulnerableDataToLocalBuffer finishes, it will jump to the ArcInjection case in main, push the command which is overwritten (to calc in this case) onto the stack, and then call ArcInjection, forcing the program to run new another new program. This method is easy to implement and could also be used to inject shellcode if wanted. 


Exploit 2: Recursive Arc Injection
Since the function RecursivePrefixLocal calls EnterVulnerableDataToLocalBuffer, an arc injection exploit can be used to recursively run injected code. To keep things simple, the previous exploit of using the Arc injection to run calc was used. However, this recursion function could be used to run multiple copies of shellcode since it calls itself multiple times with data in multiple places in memory. The command used was: VulnearbleCode_1 3 1 CalcRec.txt with the file used shown below in hex:


This is equivalent to the Calc.txt file used in Exploit 1, except that it overwrites the recursive local variable i to the value 1 and it overwrites the main recursive variable i to 0, shown above at 0xBC and in memory at 0x22ccec right above the command character array. This allows the main loop to run multiple times, each time calling the recursive function, which calls, EnterVulnerableDataToLocalBuffer, which opens the calculator, resulting in an infinite loop of calculators. 

Exploit 3: Shellcode injection using Global Data
The second implementation uses AttackGlobal to overwrite a global buffer much in the same way as the EnterVulnerableDataToLocalBuffer. However, this implementation injected shellcode. Creating shellcode is the first step of this process. In order to create shellcode, the program nasm (included at the link at the top as well) was downloaded to compile assembly in to a small binary format. The shellcode was written in assembly in order to keep it as compact as possible. The first shellcode created generates a messagebox using the Windows user32.dll library and its assembly instructions are shown in Appendix B. The function called is MessageBoxA, which is included in the Windows user32.dll library, which is not necessarily included in the vulnerable code. So the first step of the assembly is to dynamically load the user32.dll library. This is done by calling the LoadLibraryA function (which is included in every windows program in kernel32.dll) with the arguments of the library name, user32.dll, pushed onto the stack.
Next, the assembly needs to call GetProcAddress to find the address of a function in a library, with its arguments, the library to look in, and the function to look for, pushed on the stack. This function returns the memory address of the function MessageBoxA. The MessageBoxA function can then be finally called with its arguments pushed onto the stack. At this point, the code is finished, so it calls ExitProcess from kernel32.dll with an argument of 0. This is done to prevent the code from seg-faulting and make it look like the vulnerable code ended correctly even though it was exploited.
There are a couple of important factors to include about this type of exploit. Firstly, nasm is used to compile the assembly with the –f flag into a binary file with “Bits 32” included in the assembly file. This is important since the Windows library functions are 32 bit and therefore at 32 bit addresses. Without this line, the shellcode will load with 24 bit registers and seg-fault. Nextly, the locations of the Windows functions displayed are different per operating system and service pack in order to prevent exploits. In order to find the address of LoadLibraryA, GetProcAddress, and ExitProcess, the code called arwin.c was used (which is included in the link at top). This code was used as follows ./arwin kernel32.dll LoadLibraryA in order to find the memory addresses for this Operating system. If this step is not taken, the shellcode will most likely seg-fault. This concludes the creation of the shellcode; however, a shortened version of the assembly is included in the link at top. This version has no conditional jumps and calls MessageBoxA with its absolute memory address rather than using GetProcAddress.
With shellcode created, it is just a matter of finding a place to insert it and a function pointer to overwrite to call it. This is where AttackGlobal comes in. The GlobalBuf array is located at 0x404108 in memory, which is conveniently just before the global function pointer variable named FunctPtr, which is located at 0x404168. So in order to take advantage of this, the shellcode is inserted into GlobalBuf and then it overwrites the FunctPtr with the starting memory address of GlobalBuf. This way, when the FunctPtr is called, it goes instead to the inserted code. VulnerableCode_2.c is used this time instead of VulnerableCode_1.c because VulnerableCode_1 flips the memory around when entering the characters. The file used for this (called MessageBox.txt) is shown below in hex:

The shellcode is clearly displayed from 0x00 to 0x63 and then it is null data that doesn’t matter until the global variable FunctPtr located at 0xB0 in the hex file and 0x404168 in memory, which we overwrite to 0x404108. The trick, just like in the first exploit, is to get the shifting right so that the relative difference is the same and the correct data is overwritten. This way, by running ./VulnerableCode_2 4 6 MessageBox.txt the code will go into AttackGlobal because of the 4 argument, overwrite the buffer with shellcode and overwrite the FunctPtr with the location of the shellcode. Then the code will return to main and call FunctPtr because of the 6 argument, calling instead the injected shellcode. 

Exploit 4: Another Shellcode injection using Global Data
            In order to show how dangerous shellcode can be, the methods used in Exploit 3 were used to create another piece of shellcode that creates a user with administrator privledges on the host computer. This is dangerous because the username and password are set by the exploit, and the exploited program shows no indication that it has been exploited. The arwin function was used to find the memory location of WinExec in kernel32.dll and run a command to create a user. The assembly instructions for this are included in the link on top. It was run with the command ./ VulnearbleCode_2 4 6 NewUser.txt much like Exploit3 but with a different file generated using nasm and edited in hex to coincide with the proper memory locations. NewUser.txt is shown below:

Exploit 5: Recursive Shellcode injection using Global Data
            The RecursivePrefixGlobal function can be taken advantage of simply because it calls AttackGlobal. Therefore the same arguments and methods shown in Exploit 3 were used, except that it was run through RecursivePrefixGlobal with the command VulnearbleCode_2 7 1 6 MessageBox.txt. The local variables were not overrun in this instance since they were located at a different place in memory than the global data. However, this could be different if other global variables were used and is important to keep in mind.
References
**It is important to note that the examples described in the tutorials above will not properly work without editing since they are not meant for this specific environment (and have typos in the assembly instructions). However, they are very good references for understanding.

Consider donating to further my tinkering.


Places you can find me

Friday, August 10, 2012

Setting up OMXPlayer GUI on the Raspberry Pi (Updated)

This is a nice little trick to get OMXPlayer to work nice and pretty within the file manager so that the keypresses work and you don't need to use the command line. 

I got my Raspberry Pi in the mail and started setting it up as a  media server with my projector, external HDDs, and sound system.

You can do this in Arch Arm or in Raspbian Wheezy (It's easier in Wheezy since in Arch you have to get LXDE and omxplayer installed).

First thing, I noticed that the resolution auto-selection script didn't work properly with my projector.
I went into /opt/vc/bin and ran:
tvservice -d /home/pi/projector
edidparser /home/pi/projector /home/pi/available

Most of the options you need to change are in /boot/config.txt

This will give you the available resolutions. Each one has a code associated with it and is either a CEA code (hdmi_group=1) or a DMT code (hdmi_group=2). Then you can set the code with the hdmi_mode=? (I like hdmi_mode=15 and hmdi_mode=5).
Sometimes audio doesn't work over HDMI. If it doesn't, set hdmi_drive=2

Overclocking the Raspberry Pi is really easy, you can definitely get up to 850 MHz by adding this into the /boot/config.txt file:
arm_freq=855
sdram_freq=500

I got up to 1 GHz easily with the following options:
over_voltage=6
arm_freq=1000
sdram_freq=500
core_freq=500

I made the mistake of installing vlc. Don't! The ARM processor can't really handle it (unless overclocked and then it's still buggy).
Use omxplayer instead.

Unfortunately omxplayer is a command line tool and that can get bothersome. To easily get around this and use it, install xterm by running:

Note: You don't have to use xterm, you can use the built in lxterminal instead by replacing xterm with lxterminal in all the examples below. However, xterm allows for the nice fullscreen option that omxplayer messes up.

sudo apt-get install xterm

Then right click one of your avi files and select open with, then click custom command line tool, type in:
xterm -fullscreen -fg black -bg black -e omxplayer -o hdmi -r %f

and check the box saying always do this so you only have to double click on any avi file in the future and it will do the same thing.


This opens up omxplayer in a new terminal so the key presses, such as p (pause) and q (quit), work. It also opens it up in fullscreen (the -r flag and the -fullscreen flag for xterm). Note: The rest of the display goes to sleep after a while so if the screen is black when the movie quits, shake the mouse or press a key to wake it up.

Omxplayer Problems

For detail on issues and how to fix them, see here:
Updating Raspberry Pi packages, kernel, and firmware (also fixing omxplayer)

If you are having problems with the video not working or not showing or the screen locking, make sure your raspberry pi is up to date by running:
sudo apt-get update && sudo apt-get upgrade

**HELP my mouse and keyboard don't work  (SOLUTION)**
If it still doesn't work, you may need to upgrade your firmware (which is generally a good idea anyways) using:
sudo apt-get -y dist-upgrade
and also 
sudo rpi-update
The guide for updating your firmware can be found here:
https://github.com/Hexxeh/rpi-update

Also make sure your gpu_mem split is at a reasonable level such as 128/128 by adding the line
gpu_mem=128
in the /boot/config.txt file in the newer firmware versions

To be able to easily find and intelligently play videos automatically, see this page:
http://stevenhickson.blogspot.com/2013/03/playing-videos-intelligently-with.html

Omxplayer Key Bindings:

  • 1 Increase Speed
  • 2 Decrease Speed
  • j Previous Audio stream
  • k Next Audio stream
  • i Previous Chapter
  • o Next Chapter
  • n Previous Subtitle stream
  • m Next Subtitle stream
  • s Toggle subtitles
  • q Exit
  • Space or p Pause/Resume
  • - Decrease Volume
  • + Increase Volume
  • Left Seek -30
  • Right Seek +30
  • Down Seek -600
  • Up Seek +600

Check out my other Raspberry Pi Fixes/How tos:
http://stevenhickson.blogspot.com/2012/10/using-raspberry-pi-as-web-server-media.html
http://stevenhickson.blogspot.com/2012/10/fixing-raspberry-pi-crashes.html

Consider donating to further my tinkering.


Places you can find me