Tag Archive : linux

/ linux

Debugging Linux Kernel on QEMU Using GDB

March 21, 2016 | Article | No Comments

Kernel is magic. Well, not really. All my experiences involving programming in userland. Could I step up to enter the land of kernel? Sure, but before that I need to arm myself with knowledge. Especially when dealing with kernel debugging.

This article will discuss about kernel debugging. When writing this, I use:

  • Linux Kernel 4.5
  • GDB 7.7.1
  • Qemu 2.5.0
  • Busybox 1.24.2
  • ParrotSec Linux for host

Although in the end we can run minimalistic kernel, this approach is not close to “real world” yet.

Preparation

Download the kernel source code from https://www.kernel.org/ and extract it to /usr/src

wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.5.tar.xz
mv linux-4.5.tar.xz /usr/src
cd /usr/src
tar -xf linux-4.5.tar.xz -C linux

Download busybox and extract it to /usr/src. We will use this for creating initramfs.

wget https://busybox.net/downloads/busybox-1.24.2.tar.bz2
mv busybox-1.24.2.tar.bz2
cd /usr/src
tar -xf busybox-1.24.2.tar.bz2 -C busybox

ParrotSec is debian derivative.

I use latest Qemu, you can read it from here.

Compile Linux Kernel

It’s a bit different to usual routine, we need to enable debug info.

cd /usr/src/linux
mkdir build
make menuconfig O=build

Select “Kernel hacking” menu.

Go to “Compile-time checks and compiler options”.

  • Enable the “Compile the kernel with debug info”
  • Enable the “Compile the kernel with frame pointers”
  • Enable the “Provide GDB scripts for kernel debugging”.

Search for “KGDB: kernel debugger” and make sure it is checked.

Go to the build directory and build from there

cd build
make bzImage -j $(grep ^Processor | wc -l)

Creating Initramfs

We need some kind of environment with basic command line tools. Something that provided by binutils, like: ls, cat, mkdir, etc. It is called initramfs (Initial RAM file system). The idea is to provide a minimal “root file system” as a temporary file system so Kernel can prepare all works before mounting the real file system. We will use Busybox.

cd /usr/src/busybox
mkdir build
make menuconfig O=build

Select “Busybox Settings” > “General Configuration” and uncheck the “Enable options for full-blown desktop systems” and check”. Go back and select “Build Options” and check “Build BusyBox as a static binary (no shared libs).

make && make install

This will create a new directory “_install” and install our busybox there. This _install will be base for initramfs.

Next we create a new “initramfs” directory and create some configuration files inside.

mkdir /usr/src/initramfs
cd /usr/src/initramfs
cp -R /usr/src/busybox/build/_install rootfs
cd rootfs
rm linuxrc
mkdir -p dev etc newroot proc src sys tmp

We don’t need “linuxrc” sine we are going to use initramfs boot scheme.

Create a file etc/wall.txt and fill it:

######################################
#                                    #
#      Kernel Debug Environment      #
#                                    #
######################################

Remember init? Once our kernel is up, we need init to spawn everything necessary. However in our minimalistic system, our init only needed to spawn tty. Now create and populate init file with following content.

#!/bin/sh
dmesg -n 1

mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys

cat /etc/wall.txt

while true; do
   setsid cttyhack /bin/sh
done

The cttyhack is a small utility for spawning tty device. This way, we can rest assure that when we execute the “exit” command new shell will be started automatically.

We need to make the init file is executable.

chmod +x init

Next we need to pack initramfs.

cd /usr/src/initramfs/rootfs
find . | cpio -H newc -o | gzip > ../rootfs.igz

Running Kernel on Qemu

Next thing to do is to launch the kernel inside Qemu.

qemu-system-x86_64 -no-kvm -s -S \
-kernel /usr/src/linux/build/arch/x86/boot/bzImage \
-hda /mnt/jessie.ext3 -append "root=/dev/sda"

At this point, we will see a blank QEMU terminal windows.

The -s option is a shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234.

The -S option stops the CPU to start at startup. Now QEMU is waiting for kernel to start in debug mode.

Running GDB

The QEMU had launched the kernel and waiting for debugging. The next thing is to launch GDB and do the debugging.

gdb

In our host, we need to load the the same kernel load in QEMU and point our target to QEMU.

file /usr/src/linux/build/arch/x86/boot/bzImage
set architecture i386:x86-64:intel
set remote interrupt-sequence Ctrl-C
target remote :1234

Let’s try it, using GDB:

continue
bt

As for now, GDB still not appreciate the size of registers changing. As for our kernel, there is a time when our kernel change from 16 bit to 32 bit (or 64 bit). You might notice that when we run QEMU we specify -S so QEMU will stop at startup. At that time, Linux will change to full 64 bit (or 32 bit) kernel. If you don’t do something, GDB will keep complaining about “remote packet reply is too long”.

To circumvent it, we can just disconnect and then reconnect.

disconnect
set architecture i386:x86-64:intel
target remote :1234

QEMU [Paused]_021  LXTerminal_022

Linux is dominating embedded system. It is mainly because of broad support of processor, such as: ARM, MIPS, PowerPC, etc. For some gadget, touch screen is an extra feature, other must have it. Whatever the reason, Linux support it. The fundamental thing in programming a system with touch screen is how to get coordinate of point touched by user.

This article will discuss about how to capture coordinate of point in touch screen. When I write this article I use Castles Technology’s EDC. I won’t disclose internal of the system used, but I should tell you that our discussion could be applied to Linux in general.

Some Knowledge

As usual, before we start we need to know some basic knowledge.

Linux is unix-like operating system. Everything in Linux is a file, including device. They are all stored inside /dev. Your first SCSI disk should be recognized as /dev/sda. Your DVD ROM might be recognized as /dev/sr0 (or /dev/dvd, a symlink to it).

You might also learn that device is categorized mainly as character device and block device. A character device is a class of device which send data by amount of character at a time, while block device will give you a block of data (typically some bytes).

Now direct our focus toward /dev/input. This is the location where device files for our input devices located. By input devices we means mouse, keyboard, or perhaps touch screen. Good, now spot eventX file where X is a number. Well, the number of files is depends on how much input device you have.

So how can we pinpoint the device?

In desktop I can see the /dev/input/by-id or /dev/input/by-path and see to which device they are pointing at. However, we don’t always have this luxury.

ls -la /dev/input/by-id/
ls -la /dev/input/by-path/

Another quick way to figure it out is by inspecting /proc/bus/input/devices. Yet, this might be not the case for most device. Also we need to parse some unneeded information.

cat /proc/bus/input/devices

Next option is dumping the raw data from file. Again this is not always the case.

cat /dev/input/event0 | hexdump -c

Last option is writing a small program, open the device, and read it. This works for me and we will discuss it deeper later.

Preparation

I will leave the idea of “how you can connect to device” to you. I assume you have some way to write a program. We also need a way to direct I/O to device.

I also assume you can produce code for the device. Whether you have compiler inside, or just do cross compilation doesn’t matter.

Last, I assume you know our great programming language, C.

Capturing

This is the sample working code I use to enumerate the device, open it, and capture the coordinate.

#include <stdio.h>
#include <stdlib.h>

/* For open and read data */
#include <unistd.h>
#include <fcntl.h>
#include <linux/input.h>

/* For directory listing */
#include <sys/stat.h>
#include <dirent.h>

/* Miscs */
#include <limits.h>
#include <string.h>

// We don't care it for now, let it be global.
DIR *dir = NULL;

/* Find first valid device which we can open */
int enum_and_open_dev()
{
    struct dirent *dirent;
    int fd;
    
    // Is it first time? Open it if yes.
    if (!dir)
        dir = opendir("/dev/input");

    if (dir)
    {
        while ((dirent = readdir(dir) != NULL)) {
            if (!memcmp(dirent->d_name, "event", 5)) {
                fd = open(dirent->d_name, O_RDONLY);
                if (fd == -1)
                    continue;   // Not a valid file

                return fd;   // file is opened
            }
        }
        closedir(dir);
        dir = NULL;
        return 0;
}

int get_dev_name(int fd)
{
    char buf[256] = "Unknown";

    /* Print Device Name */
    ioctl(fd, EVIOCGNAME(sizeof(buf)), buf);
    write(ofd, buf, strlen(buf));
}

int touch_screen_getxy(int fd)
{
    struct input_event ev;
    size_t ev_size = sizeof(struct input_event);
    size_t size;
    
    while (1) {
        size = read(fd, &ev, ev_size);
        if (size < ev_size) {
            write(ofd, "Error size when reading", 23);
            return -1;
        }
        
        if (ev.type == EV_ABS && 
            (ev.code == ABS_X || ev.code == ABS_Y))
        {
            sprintf(buf, "%s = %d\n", ev.code == ABS_X ? "X" : "Y", ev.value);
            write(ofd, buf, strlen(buf));
        }
    }
    return 0;
}

int test_()
{
   int fd;

   fd = enum_and_open_dev();
   if (fd == 0) {
      write(ofd, "No readable device found", 24);
      return -1;
   }

   get_dev_name(fd);
   touch_screen_getxy(fd);
}

Just a note, ofd is a file descriptor where will pipe to my host, in other words a debug means for me.

enum_and_open_dev() is a function to enumerate available file in /dev/input/ and trying to open it. In my sample code, I only use the first valid file descriptor. After I got it, I want to know it’s name and then the main dish: the coordinates.

Next?

Just a single point is not enough. What about two or three simultaneous touch (multitouch) ? Well, save it for later.

Capturing USB Data with Wireshark

February 6, 2016 | Article | 1 Comment

Everyone loves USB devices. Many devices use USB as communication port. It is popular and steadily improve the standard. So, did you ever feel curious of what, how, and why the devices works? Whether you are a hardware hacker, hobbyist, or anyone interest in peripheral and low level, USB is very challenging. With wireshark, we have power to sniff or capture data stream sent by our USB devices to our host. The host is PC with Windows or Linux installed.

In this article we will discussing how can we capture data with wireshark. While writing this article I use following material:

  • Wireshark 2.0.1 (SVN)
  • Linux kernel 4.1.6

You can use any wireshark above 1.2.0 to get it works. I didn’t add Windows section yet because I didn’t confirm it yet.

Some Knowledge

Before we start, I think it is good to know some basic knowledge in USB. USB has specification. There are three way to use USB:

  • USB UART
  • USB HID
  • USB Memory

UART or Universal Asynchronous Receiver/Transmitter. This device use USB simply as receiving or transmitting way. They use USB nothing more than that, like other communication work.

HID is Human Interface Device. It is a class of USB which is for interface. Devices in this class are keyboards, mice, game controllers, and alphanumeric display devices.

Last is USB Memory, or we can say storage. External HDD, thumb drive / flash drive, they are part of this class.

As you might expect, the most common devices are either USB HID or USB Memory.

Now every USB device, especially HID or Memory, has magic number called Vendor Id and Product Id. They come in pair. The vendor Id is identifier to which vendor make this device. Product Id is identifying the product and not a serial number. See following picture.

Terminal_047

That is a list of USB device connected to my box. To get this list we can invoke lsusb.

Let’s choose an entry. I have wireless mouse, Logitech. This is an HID device. This mouse comes with a receiver. It is detected and run as expected. Can you spot which is the device? Yes, the 4th entry. Here we have following:

Bus 003 Device 010: ID 046d:c52f Logitech, Inc. Unifying Receiver

The part ID 046d:c52f is Vendor-Product Id pair. The vendor id is 046d and the product id is c52f.

See Bus 003 Device 010. This inform us the Bus in which our device is connected. Note this.

Preparation

We can run Wireshark as root to sniff USB stream. But as always, it is not recommended. We need to give enough privilege for our user to dump the stream from Linux usbmon. We can use udev for this purpose. What we will do is creating a group usbmon, make our account as usbmon member, create udev rules.

addgroup usbmon
gpasswd -a $USER usbmon
echo 'SUBSYSTEM=="usbmon", GROUP="usbmon", MODE="640"' > /etc/udev/rules.d/99-usbmon.rules

Next we need usbmon kernel module. If it is not loaded yet, invoke following command as root

modprobe usbmon

Capturing

Open wireshark. See the interface list. You should see usbmonX where X is number. Here is mine (yeah, I use root):

The Wireshark Network Analyzer (as superuser)_048

If there is activity or stream in interface wireshark will show it as a wave graph. So which one should we choose? Did I ask you to note? Yes, the X or the number is corresponding to the USB Bus. In my case the target is usbmon3. Just open it and see the packet flow. Click on usbmon interface and click the blue shark fin icon.

-usbmon3 (as superuser)_049

Next?

What can we do after capturing? Well it depends. In general we can understand how devices and host communicate and maybe by this knowledge we can use our skill to reverse engineering it. Well, another article.

Embedded system / device running operating system such as Linux / BSD is not so uncommon today. Most of them fall in category as routers, servers, NAS devices and mostly have communication interface (serial port with RS-232, or even fancy USB). We can communicate with these kind of devices, by redirect our I/O to this port. That’s the hardware part, how can we feed information to it? What tools should we use?

This article will mention five ways to communicate with embedded device. Our operating system of choice is Linux.

Of course we need to specify, our embedded system is the one which is designed to send/receive data / command using communication line.

Preparation

The physical port might be one and only, but how it is referred by our system? Thus we should check. The port commonly referred as ttyS*, ttyACM*, ttyUSB*. It is analogous to COM* on Windows. Let’s check by dmesg command. Connect our box with our device and invoke following command:

dmesg | egrep --color 'serial|ttyS|ttyACM|ttyUSB'

This one will be our example:

[    1.245258] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    1.265727] serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
[    1.286713] 00:07: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
[    1.307321] 00:08: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A

Let’s get initial report regarding the port. We need the configuration information associated with serial port (in this context):

setserial -g /dev/ttyS[0123]

Sample outputs:

/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3

After confirmed, we can use following method to communicate.

CU Command

You might also want to read my old article: using CU to communicate with modem.

CU, abbreviated from call up, is an old unix command used to call up another system and act as dial in terminal. In some unix it is preinstalled. If not, you can always install it, most modern distro available.

Next, we use following command to communicate:

cu -l /dev/device -s baud-rate-speed

In our case, /dev/device would be /dev/ttyS0. Our baud rate is anything predefined value you want such as 19200 or 115200. Make sure the baudrate in both end is the same value.

 
cu -l /dev/device -s baud-rate-speed

In this example, I’m using /dev/ttyS0 with 115200 baud-rate:

 
cu -l /dev/ttyS0 -s 115200

To exit enter tilde dot (~.).

Screen Command

Most case, screen is used as a trick to run a process in server when we are remotely connect to it. We can also use screen to communicate with device.

screen /dev/device baud-rate

Minicom Command

Minicom is another approach. It is a tool designed for the job. Before we use, we need to setup it.

minicom -s

You will see some menu there. The most crucial part here is Serial port setup. Make sure the port and baud rate are set correctly.

Invoke minicom to do the job. We don’t need to specify command to minicom everytime we invoke it if we have saved the configuration before.

minicom

PuTTY Command

PuTTY, yes it is available also on Linux. It is a free and open source gui X based terminal emulator client for the SSH, Telnet, rlogin, and raw TCP computing protocols and as a serial console client. To use it, invoke PuTTY and wait for its GUI.

putty

On Session, select Serial. Again, specify the port as Serial line and the baud rate as Speed.

Tip command

Last but not least, is using tip command. To use tip, we invoke following:

tip -baud device

For example:

tip -115200 ttyS0

Running Debian MIPS Linux in QEMU

December 11, 2015 | Article | No Comments

Have you ever want to try system other than your PC? MIPS for example.

As a reverse engineer, I sometimes want to run a MIPS Linux system so that I can observe, develop, and testing somethings. However, I don’t have much room for another device, so virtualization might be a solution.

In this article we will try to run MIPS Linux on QEMU. In specific, Debian MIPS Linux, with following materials used:

  1. Slackware64 14.1
  2. QEMU 2.1.50

The article written here should be as generic as possible so I hope it can be used for different setup you use.

Obtain the Materials

Refer to this article to build a QEMU, if you don’t have one: Installing QEMU from Source

Next, we need to download the kernel images and a disk image which has Debian installed there. Go to this site to download. The ‘mips’ directory is for Big Endian MIPS and ‘mipsel’ is for Little Endian one. Choose what you want but in this case I will download both of them. In specific, we will test kernel version 3.2.0 (denoted as vmlinux-3.2.0-4-5kc-malta) with Debian Wheezy (denoted as debian_wheezy_mipsel_standard.qcow2)

At this point, we have (at least):

  1. QEMU installed
  2. Debian kernel
  3. Disk Image with qcow2 format.

Setup Bridged Networking

In order to make QEMU environment connected to the network, we need to do some additional setup.

Now create the two new files, /etc/qemu-ifup and /etc/qemu-ifdown. Make sure you give them executable permission. Also make sure you have right configuration, like GATEWAY and BROADCAST address. Also pay attention to the USER. It is a username you should specify when you want to run qemu.

#!/bin/bash
ETH0IPADDR=192.168.1.100
GATEWAY=192.168.1.1
BROADCAST=192.168.1.255
USER=xathrya
 
# First take eth0 down, then bring it up with IP address 0.0.0.0
/sbin/ifconfig eth0 down
/sbin/ifconfig eth0 0.0.0.0 promisc up
 
# Bring up the tap device (name specified as first argument, by QEMU)
/usr/sbin/openvpn --mktun --dev $1 --user $USER
/sbin/ifconfig $1 0.0.0.0 promisc up
 
# Create the bridge between eth0 and the tap device
/usr/sbin/brctl addbr br0
/usr/sbin/brctl addif br0 eth0
/usr/sbin/brctl addif br0 $1
 
# Only a single bridge so loops are not possible, turn off spanning tree protocol
/usr/sbin/brctl stp br0 off
 
# Bring up the bridge with ETH0IPADDR and add the default route
 
/sbin/ifconfig br0 $ETH0IPADDR netmask 255.255.255.0 broadcast $BROADCAST
/sbin/route add default gw $GATEWAY

and

#!/bin/bash
 
# Bring down eth0 and br0
/sbin/ifconfig eth0 down
/sbin/ifconfig br0 down
 
# Delete the bridge
/usr/sbin/brctl delbr br0
 
# Bring up eth0 in "normal" mode
/sbin/ifconfig eth0 -promisc
/sbin/ifconfig eth0 up
 
# Delete the tap debice
/usr/sbin/openvpn --rmtun --dev $1

To starting network bridge, just invoke

/etc/qemu-ifup tap0

and then invoke

/etc/qemu-ifdown tap0

to stop it.

Running the Debian MIPS

After all preparation we have done, it’s time for actual thing.

Go to the directory where we store kernel and disk image, for example $HOME/debian-mipsel, and then invoke following command:

qemu-system-mips64el -net nic -net tap,ifname=tap0,script=no,downscript=no \
-M malta -kernel vmlinux-3.2.0-4-5kc-malta -hda debian_wheezy_mipsel_standard.qcow2 \
-append "root=/dev/sda1 console=tty0"

We can also create a script to simplify it.

#!/bin/bash

qemu=qemu-system-mips64el
path="$HOME/debian-mipsel/"
hda="$path/debian_wheezy_mipsel_standard.qcow2"
kernel="$path/vmlinux-3.2.0-4-5kc-malta"
iface=tap0

echo "Stopping eth0, starting tap0"

/etc/qemu-ifup tap0 || quit 1 "Failed to start tap0"

echo "Starting Debian MIPS"

$qemu -net nic -net tap,ifname=$iface,script=no,downscript=no \
-nographic -M malta -kernel $kernel -hda $hda -append "root=/dev/sda1 console=tty0"

If everything goes well, you should see Debian is booting and then greeted with sweet login prompt.

Further Configuration

It’s nice to work with QEMU window. But you should admit taht QEMU console is very limiting, so you need SSH connection to do most of your work. You can, by installing OpenSSH inside Debian system using apt:

apt-get update
apt-get install openssh-server

Setup Slackware as Basic TFTP Server

December 11, 2015 | Article | No Comments

TFTP or Trivial File Transfer Protocol is a transfer protocol notable for its simplicity. TFTP is generally used for automated transfer of configuration or boot files between machines in a local environment, such as routers and PXE (Preboot eXecution Environment) mechanism. Compared to FTP, TFTP is extremely limited, providing no authentication and is rarely used interactively by a user.

There are many TFTP implementations, such as:

  • GNU inetutils
  • tftp-hpa
  • atftp
  • tftp-server
  • etc…

In this article, we will discuss about how to set Slackware as a basic  TFTP server. In specific, we will use tftp-hpa which is included by default. This article is tested using Slackware64 14.0 and tftp-hpa.

Upgrade or Not?

Slackware has shipped a TFTP server by default which is tftp-hpa. The version is 0.49. However we can install the latest tftp-hpa with simple process. If you decided to install the latest version, follow this section. Otherwise you can skip to next section.

Download the latest version of tftp-hpa here: www.kernel.org/pub/software/network/tftp/tftp-hpa/. The latest version is 5.2 which can be downloaded here: www.kernel.org/pub/software/network/tftp/tftp-hpa/tftp-hpa-5.2.tar.xz

Now invoke following series of command to build TFTP (server and client):

tar -Jxf tftp-hpa-5.2.tar.xz
cd tftp-hpa-5.2
./configure --prefix=/usr
make
cd tftp && strip --strip-unneeded tftp
cd ../tftpd && strip --strip-unneeded tftpd
cd ..

Now install it (make sure you are using root privileges):

make install

Set up

By default, the inetd use /tftpboot directory as root directory of the TFTP server. We can however change the directory to something else. Make sure the directory exists, whichever directory you use.

Suppose we want to use /usr/local/tftpboot as root directory:

mkdir -p /usr/local/tftpboot

Then we give a proper permission:

chmod +777 /usr/local/tftpboot
chown nobody /usr/local/tftpboot

Next we add the following entry to the /etc/inetd.conf file as a single line. Or you can edit it and make sure it’s uncommented.

tftp  dgram   udp     wait    root    /usr/sbin/in.tftpd  in.tftpd -s /usr/local/tftpboot -r blksize

Then, restart the inetd using root privileges.

/etc/rc.d/rc.inetd restart

Testing

Now, let’s testing our TFTP server. In our simple scenario, we will create a plain text and fill something there. Then we will download it via tftp.

echo "Xathrya was testing the TFTP server" >> /usr/local/tftpboot/test.txt

To download it, use:

tftp 127.0.0.1 -c get test.txt

And see in current directory, whether we have successfully download it:

cat test.txt

It should print out “Xathrya was testing the TFTP server”.

Why Linux/Unix is Less Infected by Malware?

December 11, 2015 | Article | 1 Comment

Initially I wrote this as a reply to local group discussion with similar question. And then my friend said I should publish my answer as a post. Thanks for the advice, and here is our discussion.

First, what is malware?

Malicious software, is any software used to disrupt computer operation, gather sensitive information, or gain access to certain computer. It can appear in the form of executable code, script, active content, anything. From user perspective, any malware often called as virus but it’s not exactly true. Virus is one malware categories. Malware can be divided into some categories such as computer virus, worm, trojan horse, adware, rootkits etc. If we want to discuss about malware, it can be another topic so let’s limit our discussion to computer virus and worm.

There’s a myth, if you are using Linux you are immune to malware. This is partially true. Viruses and Worms are exists even in Unix world. You can read some list from Wikipedia.

Now, it comes to the real question, why Linux/Unix is less infected by malware? Some people might answer from user demographic (who use Linux and other OS). Personally I don’t choose this answer and rather go to more technical answer.

Please note that this is my own opinion and might be biased.

Distribution

From OS distribution, most operating system used worldwide is still Windows. I pick the statistics from W3schools, Linux and Unix got less than 10% each. Per September 2014, most operating system used are Windows 7.

Linux and Unix mostly used for server, embedded system, devices, etc although quite many people use Linux as their main operating system. As we know one who creating something must have specific goal or purpose. As the OS market share still dominated by Windows then no wonder malware for Windows are keep popping up. Mostly they are targeting users.

If by chance Linux dominating the market share, it should be obvious malware will sprung and targetting linux. This is natural.

The Insides

To determine the answer, first we need to look to inside of both OSs.

Windows

Why Windows sucks?

  1. Windows API – Windows has rich APIs. Some of Windows API (WIN32 API) can be executed by any user. Yes, you got the point. When one user make mistakes, boom! The system is in danger. Also, Windows is famous with its being want to be backward compatible as possible (hence, we have Windows 10 instead of Windows 9) which implicate that you can use that API.
  2. Access Control List – Yes, Windows have ACL. But how many of us knows, or using it? People don’t know and maybe not apply it. Without control, malware can spread freely. Yes, you can use ACL but by default each resource you have is not affected by ACL.
  3. Multiuser Design – Windows have common user and superuser (known as Administrator). But on most system, one user on the system is also a super user.
  4. Device Access – Literally! On some Windows, any program can access any devices connected if you program it. Life is easier.
  5. Registry system – Windows use a huge database for it’s global configuration, known as registry. Like I said in point (1), whoever you are, you can access registry. Also you can change configuration easily, you can even set the autostart entry in registry to call your malware.
  6. Extensions – Most worms used other extension to camouflage. For example, a worm might disguise itself as Word Document program, using the same icon as the Microsoft Word. User can be fooled by this appearance. Also, the extension itself is registered to registry. Windows will look registry and call the appropriate program for this extension.

Linux

Now let’s compare it to Linux.

  1. API – Linux also has API for some operations. But, the operation is guaranteed always complies with Access Control. You can do what you are given. Linux/Unix access control is often called as Discretionary Access Control and it is enforced in the kernel itself. You cannot do something which you are not privileged to.
  2. Access Control – The Discretionary Access Control used by Linux/Unix is describing read/write/execute access to resource (file, directory, nodes, etc). This strict rule is integrated to kernel. Also, as a Linux/Unix user you are always inform to follow Least Privilege principle. Least Privilege principle means any operation you do should be done as low privilege as possible, you might request more privilege if the previous privilege is not sufficient but you should not always use super user privilege. Often some Linux distribution limit yourself from using root access.
  3. Multiuser Design – Linux is multiuser and multitasking. However, Linux make clear separation of each users. Linux have term users and groups to separate system power. On every Linux/Unix system you have a superuser account (root) and you are obligated to create your own user account. Most distribution will enforce you to create and use your own user account. This account however is different with root so you are guaranteed to not harm your system by accident, unless you are doing so.
  4. Device Access – be a network interface, printer, scanner, or any device connected all are managed by kernel by udev or similar mechanism. And the good news is any node has specific privilege.
  5. Registry System – what is registry? Linux/Unix doesn’t know that. To configure a system globally, one should modify config files and most of them stored in privileged directory. Unless you are root or given access to it, you are powerless.
  6. Extensions – Linux recognize file not by extension but by their header. Every file format has header and something we called magic words to distinguish the format and other formats. Even if the extensions are changed, Linux/Unix can know what it is and still give you correct information.

Apart from above comparison, there is one thing extra you should know! Windows executable is using PE (Portable Execution) format while executable format in Linux is ELF (Executable and Linkable Format). So you cannot run Windows program natively, in case you don’t know 🙂

Linux udev Rule for AVR USB Programmer

December 11, 2015 | Article | No Comments

In previous article, we have discussed about AVR development in both Linux and Windows. As you might see, we are using software avrdude to write our binary code to avr chip.

Now, when executing avrdude on Linux, it may give an error such as

avrdude: error: usbtiny_transmit: error sending control message: Operation not permitted.

This problem arise when we run avrdude without root privilege.

We can quickly fix this by run avrdude as root or doing sudo. The other choice we have is creating an udev rule for certain programmer. And that’s what we will discuss in this article.

Create udev Rule

First, what is udev?

Any device attached to Unix (and its derivation) will be represented as a node in /dev directory.For each device, it will receive a (major, minor) pair of integers. In the old school way, we can call “mknod” to create device. Starting from kernel version 2.6, Linux use udev to provide a userspace solution for dynamic /dev directory with persistent device naming. With udev we won’t have hard time to manage all device.

We use udev to give us enough privilege to access to device node.

It’s easy to use udev. We need to create a file containing udev rule and save it to /etc/udev/rules.d/

Create file “/etc/udev/rules.d/99-avrprogrammer.rules” and write following this:

# /etc/udev/rules.d/99-avrprogrammer.rules
#
# Udev rules to make AVR programmers user-accessible

# USBtinyISP Programmer rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1781", ATTRS{idProduct}=="0c9f", GROUP="users", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="0479", GROUP="users", MODE="0666"

# USBasp Programmer rules http://www.fischl.de/usbasp/
SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="05dc", GROUP="users", MODE="0666"

# Mdfly.com Generic (SiLabs CP2102) 3.3v/5v USB VComm adapter
SUBSYSTEMS=="usb", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", GROUP="users", MODE="0666"

#Atmel AVR Dragon (dragon_isp) rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2107", GROUP="users", MODE="0666"

#Atmel AVR JTAGICEMKII rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2103", GROUP="users", MODE="0666"

#Atmel Corp. AVR ISP mkII
SUBSYSTEM=="usb", ATTRS{idVendor}=="03eb", ATTRS{idProduct}=="2104", GROUP="users", MODE="0666"

The above rules describe about six hardware programmers.

Creating Disk Image

December 11, 2015 | Article | No Comments

I remember creating one or two challenges for local forensic competition in my community. Ideally the image should be created from live hard drive or SD card. However, I’m not in condition to do that. The constraint I have is to create image as small as possible so we can distribute it across any media. Therefore I create a “disk image” by myself.

In this article we will use:

  1. Slackware64 14.1
  2. dd
  3. fdisk

We will create a small disk image, 50MB in size. It can be an image of a single partition, or even we can make it as if it was an image of a disk. Let’s say we will create “partition.img” and “disk.img”

Creating a Blank Image

The disk image is exactly a single file. It is a storage containing the complete contents and structure representing a data storage or device, such as hard drive, tape drive, optical disc, or USB flash drive. Creating a disk image is usually done by creating complete sector-by-sector copy of the source medium. Thereby perfect replicating the structure and contents of a storage device.

In our case, however, we are not copying real disk. We create it, literally. What we will do is creating an empty file with sufficient size before we do something to it.

If you have experience with Virtual Machine and ever creating disk image for particular VM (for example, VirtualBox VDI), you should know that it is slightly different thing. Yes, it is still a disk image, but we have extra metadata and various thing over it.

Now, to create our blank disk image of size 50MB, we invoke following command:

dd if=/dev/zero of=disk.img bs=512 count=97656

The dd utility is used with following argument:

  • if=/dev/zero, we specify the input is /dev/zero. This is a special node in Linux which generate a zero every time it is read.
  • of=disk.img, we specify the output will be a file named disk.img.
  • bs=512, we set the block size to 512 byte. Actually you can set the zie to any convenient number. Anything will do but I choose this number.
  • count=97656, we specify how many block we will write. So, in our case, we will have 97656 blocks or 97656 x512 byte = 49999872 bytes or around 50MB. I got the number by calculating 50*1000*1000/512.

Creating the partition.img is in similar manner.

Single Partitioned Disk Image

Having partition.img, we are ready to format the image into certain partition. I want an EXT4 format, so i use following command:

mkfs.ext4 partition.img

The command will take partition.img and format the partition with to EXT4 file system.

In general, we are attempting to imitate a partition. Later we can mount the partition by:

mount -o loop partition.img /mnt/partition

Now you can mount the partition and copy files tot he /mnt/partition and they will be written to our image file.

Multiple Partitioned Disk Image

In this section we will create a disk image with multiple partitions. In other words, we are trying to imitate the real disk.

The procedure is basically similar, but the image file must first be partitioned. So, more work involved here.

As in our case, we will create two partitions. First partition will occupy 10MB. The rest will be allocated to second partition.

fdisk disk.img

The fdisk utility is interactive program and quite clear. You just need to choose right option and enter right number for start and end of partition. Before you proceed, make sure you print current condition (using option p). Fdisk will display how many heads, sectors, and cylinders it recognized. It also print out the size of sector.

Here is what specification we need:

Partition 1:
primary partition
First sector = 2048
Last sector = 22527

Partition 2:
primary partition
First sector = 22528
Last sector = 97655

If you see the number 97655 and wonder it might have something to do with the count=97656 argument to dd, you are sharp! It is truly last sector of our disk image.

Now the formatting would be bit complicated. In short, we have to make a loop back device to point a partition inside our disk image and then do formatting.

losetup /dev/loop0 disk.img -o 2048
losetup /dev/loop1 disk.img -o 22528

mkfs.ext4 /dev/loop0
mkfs.ext4 /dev/loop1

To mount our disk image, you can follow this article: Mounting Partition from Raw Disk Image on Linux

For you who are not patient enough, here’s how we mont both partitions:

mount -o loop,offset=1048576 disk.img /mnt/disk1

mount -o loop,offset=11534336 disk.img /mnt/disk2

Installing PostGIS From Source on Slackware64

December 11, 2015 | Article | No Comments

PostGIS is a spatial database extender for PostgreSQL object-relational database. It adds support for geographic objects allowing location queries to be run in SQL. In effect, PostGIS “spatially enables” the PostgreSQL server, allowing it to be used as a backend spatial database for geographic information systems (GIS).

PostGIS is a free open source project, licensed under GNU GPLv2.

In this article, we will discuss about how to install PostGIS on Slackware64. For this purpose, we will use following materials:

  1. Slackware64 14.0
  2. PostgreSQL 9.3.5
  3. GEOS 3.4.2
  4. GDAL 1.11
  5. Proj 4.8.0
  6. JSON-C 0.11
  7. PostGIS 2.1.3

Obtain Materials

PostgreSQL is a DBMS which can be freely downloaded from PostgreSQL. Or download the latest version 9.35 here.

GEOS is Geometry Engine – Open Source, a C++ post of the Java Topology Suite (JTS). To download it, go to GEOS page or download GEOS 3.4.2 from here.

GDAL is Geospatial Data Abstraction Library. To download it, go to GDAL page or download GDAL 1.11 from here.

PROJ4 is a cartographic projections library. To download it, go to PROJ4 page or download PROJ 4.8.0 from here.

JSON-C is a library to read/write JSON objects in C. To downloat it, download JSON-C directly from here.

Now, our main dish. Download PostGIS from PostGIS page, or download it directly from here.

In the end of this section, you should have:

  1. postgresql-9.3.5.tar.bz2
  2. geos-3.4.2.tar.bz2
  3. gdal-1.11.0.tar.xz
  4. proj-4.8.0.tar.gz
  5. json-c-0.11.tar.gz
  6. postgis-2.1.3.tar.gz

Install

Dependency

We will install all dependency in this order:

  1. PostgreSQL
  2. GEOS
  3. GDAL
  4. PROJ4
  5. JSON-C

All the installation procedure will require root privilege.

Installation of PostgreSQL has been discussed in different article. See here to read it. You can also skip it if you have already installed PostgreSQL.

Next, install GEOS.

tar -jxf geos-3.4.2.tar.bz2
cd geos-3.4.2
./configure
make -j4
make install

Next, install GDAL.

tar -Jxf gdal-1.11.0.tar.xz
cd gdal-1.11.0
./configure
make -j4
make install

Next, install PROJ4.

tar -zxf proj-4.8.0.tar.gz
cd proj-4.8.0
./configure
make -j4
make install

When building PROJ4, you might encounter error like this:

jniproj.c:52:26: fatal error: org_proj4_PJ.h: No such file or directory

To solve it, go to src directory and edit jniproj.c then change this line

#include "org_proj4_PJ.h"

to

#include "org_proj4_Projections.h"

then resume the installation.

Next, install JSON-C. There is option to use the JSON-C from their github, but when I try it, it would break as JSON-C has removed some macro and functions. So let’s use it as is.

tar -zxf json-c-0.11.tar.gz
cd json-c-0.11
./configure
make -j4
make install

Now we are ready to install PostGIS.

PostGIS

Installing PostGIS is straightforward.

tar -zxf postgis-2.1.3.tar.gz
cd postgis-2.1.3
./configure
make -j4
make install

Installation finished. You should have PostGIS installed and ready.

Configuration

Enabling PostGIS

PostGIS is an optional extension that must be enabled in each database you want to use it before you can use it. Installing the software is just the first step. And do not install it in the database called “postgres”.

Connect to database using psql. Run the following SQL:

-- Enable PostGIS (includes raster)
CREATE EXTENSION postgis;
-- Enable Topology
CREATE EXTENSION postgis_topology;
-- fuzzy matching needed for Tiger
CREATE EXTENSION fuzzystrmatch;
-- Enable US Tiger Geocoder
CREATE EXTENSION postgis_tiger_geocoder;

Example of Spatial SQL

-- Create table with spatial column
CREATE TABLE mytable ( 
  id SERIAL PRIMARY KEY,
  geom GEOMETRY(Point, 26910),
  name VARCHAR(128)
); 

-- Add a spatial index
CREATE INDEX mytable_gix
  ON mytable 
  USING GIST (geom); 

-- Add a point
INSERT INTO mytable (geom) VALUES (
  ST_GeomFromText('POINT(0 0)', 26910)
);

-- Query for nearby points
SELECT id, name
FROM mytable
WHERE ST_DWithin(
  geom, 
  ST_GeomFromText('POINT(0 0)', 26910),
  1000
);

Social media & sharing icons powered by UltimatelySocial