Showing posts with label developing. Show all posts
Showing posts with label developing. Show all posts

Sunday, March 19, 2017

Sniffit

Sniffit Sniffit allows you to sniff your LAN traffic using Wireshark expressions and printing out the captured payload. You can think of Sniffit as a modest Wireshark.
Sniffit and libsnif are based on libpcap.

Usages

You can launch Sniffit without parameters and it will run using the default settings: lookup your network device and listen on port 80. But you can also specify the network device you want Sniffit open and a filtering expression.
Sniffit uses Wireshark expressions to filter out, so you can provide expressions like "port 22", "host 192.168.1.100", icmp, ip, etc. Further expressions can be found at the Wireshark's wiki.

For example
Sniffing traffic on port 80 on the localhost
# ./sniffit -e "port 80"

sniffing1

sniffing2

Since Sniffit opens your NIC in promiscuous mode, it needs root privileges to run.

Getting Sniffit
You can visit the GitLab page of the project, or you can get a snapshot dated on 2017-03-19.

Note that Sniffit is based on libpcap, so you need to install this dependency.

Monday, October 12, 2015

Crack it, don't break it

Crack it, don't break it This document explains a cleaner approach about cracking dynamic libraries. Have you ever needed to use a library which has already been expired?, Have you ever needed to bypass a validation method?, and the most important: Have you ever needed to crack a library but you know that modifying the binary is illegal? If the answer for one of these question is Yes, this article is for you.

Do not use the information on this article for illegal or malicious use.
I'm not responsible of your acts.

The situation

Some months ago, I had to use a dynamic library which, in association with a hardware fingerprint reader, provides fingerprint reading. The case was that the library only works until January of 2004.
When I contacted the vendor, he told me that they do not provide support anymore for the library, and, subtly, suggest me to crack it.

In order to don't violate any legal right, I wont expose the real library nor the real code. Instead, I created a replica to explain this technique.

Cracking

In order to read from the fingerprint reader, I have to create a CardReader object, and call read_card() from it. This is a good point from where to start.
The library in question is: libcardreader.so. I started for disassembling it:

objdump

(piping to c++filt is for demangling the nomenclature)

After skipping some sections, we have:

objdump_reader

Here je (jump if equal 74) is checking the condition after calling is_valid_date() (b42, two lines before). Here is where the library is validating the date. It works only if is_valid_date() is true.

What we need to do here, is the ABC of cracking, just to change je (74) for jne (jump if not equal, value 75), and after this, the library will work because it will check for not is_valid_date().
Putting the thing clear: In order to work, the original library, checks that the date is before January of 2004, now, after cracked, it checks that the date is after January of 2004. So that, the library now works.

Giving a look at the Intel x86 reference manual, we can corroborate the values for je = 74, and jne = 75.

The next is open the library with your favorite hex-editor, and change this 74 for 75

hexa-editting

hexa-editting_2

Calculating the offset (B49), and for the adjacent values, we know this is the 74 we need to change.

After changing the value, we disassemble again

objdump_2

cracked

Now we have 75 on the offset B49, and the wantedjne instruction. The library is cracked.

A cleaner approach

Of course, even when the vendor proposed me to crack its library, I didn't feel comfortable with the idea of modifying the executable, furthermore, I had a recall in my mind where someone had cracked using linking rules and making the library call his methods instead of the library methods! Yes, he did something like: When read_card() method calls to is_valid_date(), the library calls to his is_valid_date() version, where, of course, he did whatever he wanted inside hes methods. This is a cleaner approach because he was not modifying the binary.

Having this in mind, and after I read about the internal composition of the ELF format, and symbol resolution rules, I started with the tries and, after few ones, I found the way :)

Symbol cracking

Well, I don't really know how to call this technique. Maybe after explaining how it works, the name will make more sense.

The idea is to provoke a symbol collision. To collide the symbol, in this case the declaration of the function is_valid_date, with a symbol in the file of our main.

How can we do it? Easy, just declare a function with the same prototype in the main.cpp (actually where you have the main function declared) file.

We can know the is_valid_date() prototype by looking at the declaration on the library header, or we can try to guess, since we know that the function is checked out for its truth value within an if sentence, so that, this function prototype and definition is a good candidate
is_valid_code

Since we are declaring a function with the same prototype, and in the same namespace (global), we are colliding the symbols, and, in opposite to we can expect, the library resolve to call our is_valid_date version.

Before creating the symbol collision
dia-no-cracked

After creating the symbol collision
dia-cracked

In this fashion, we can simply bypass the validation returning always true.

In case that the validation is method (a function class member), we have to generate the symbol including the class name ambit, as we were redefining it.

colliding

A more interesting case is when the validation method is private. If we try to redefine it, the compiler say that the method is private and we can not do that in that context.
To bypass this problem, we can redefine any other compatible public method of the class, where we call the private validation from there. We need to redefine this private validation as well. And of course, we lose the original public method functionality.

colliding_2

A compatible method is that one that allows us to check its return value in the same way we check for is_valid_date(). These could be: a boolean, or a integer.

Further details

This happens for a historical reason, and is related to the first shared library implementations were created so that the default semantic for symbol resolution exactly mirrored those application linked against static equivalents of the same libraries.

If a symbol is defined in multiple libraries, the resolution of that symbol is bound to the first definition found by scanning libraries in the left-to-right order in which they were listed on the static link command line.

Avoiding symbol cracking

Of course, it is possible because the library vendor made an error, he exported all the symbols of his library (the default behavior with gcc).

We can check this out by running nm -DCg on the library

checking_symbols

Here we can see the validation methods exposed, creating this security hole.

These methods must be hidden from exportation. We achieve this by adding the hidden attribute to each of these

hidding_attrib

__attribute__ ((visibility("hidden"))) allows as to control what symbols we export from our libraries.

A well designed shared library should make visible only those symbols that form part the its application binary interface (ABI), for the following reasons:
1) A user of the library could try to use a symbol that we don't want they use, and we can not change it on later library versions without breaking his code.
2) Exporting unnecessary symbols increase the size of the dynamic symbols table, and this table must be loaded at run time.
3) The security hole that this article is about.

The -Bsymbolic parameter

We can specify the linker parameter -Bsymbolic to indicate that the library preferentially should resolve the symbols (if they exist) within that library. This works for symbols duplicated on another libraries, but not for those defined on our main.

Summary

Cracking could be achieve by modifying a binary, or by playing around with symbol resolution.
A definition of a symbol in the main program, overrides a definition in a library.
Export only the symbols you want the users of your library use. This brings not only performance advantage, but security improvement.

Sunday, February 22, 2015

Bingrep - Binary Auditor

Bingrep - Binary Auditor Bingrep allows you to find a binary expression into a file, or files, by searching recursively in a directory tree. You do not depend on file extensions anymore. You can find any file for its type, Bingrep will find it looking for binary patterns into the file.
You could use Bingrep for binary audit purposes as well.

How to use it

You just have to provide the path where to look for the expression, and the text file containing the expression to be find:

using

The text file with the expression to be find must look like:
61 6E 64 6F
Using one space to separate each hexa expression.

Here an output sample:

sample

As you can see, bingrep returns the offset where the expression was found.

Download

Linux:
Bingrep: bingrep-0.2.07.tar.gz (Normally this is what you want)
Bingrep library: libbingrep-0.2.05.tar.gz

Instructions: Build libbingrep and copy the resulting dynamic library to the lib directory in the bingrep folder. Add this lib folder to the LD_LIBRARY_PATH environment variable.

Sunday, January 18, 2015

C++11 benchmarks

The last week I been running some benchs to compare the new C++ standard, C++11, against its predecessor. The feature I was testings was the new move semantics and, as I expected, the new move semantic is way ahead in performance over its predecessor.

The tests were written for Linux, since it is very common in any distro to find the tools that the program depends to run, and, most important: I am using GCC to compile both version, C++11 and the old standard. I just turn on/off the new standard flag (-std=c++11), and I compile each version.
Using the same compiler to build each version, I avoid any difference I could face for using different compiler version.


The environment

The machine where the tests were ran:
Phenom II x4 955
SSD Corsair GT 160 GB
4 GB of RAM memory
Arch Linux Kernel 3.17.6-1-ARCH #1 SMP PREEMPT
gcc (GCC) 4.9.2 20141224 (prerelease)
GNU bash, version 4.3.33(1)-release (x86_64-unknown-linux-gnu)

Our program has:
An dummy object, called Dummy. It has implemented all the move semantics for the new standard, and, to put the things interesting, it has a double pointer that points to an array of 67108864 double, all of them genereted dynamically in it constructor.
Some foo functions. One of those take a Dummy object by value (lvalue), and other take a Dummy as a rvalue.


The features we are testing

The idea for this section is to clarify how the things had been working before the new standard, and how thing could be now, of course, if we do the things well :)

We are going to see three features:
- Perfect forwarding.
- Move constructors.
- Move assignment.


Perfect forwarding:

Let's say we have a function that takes an object Dummy by value, and other one that takes a Dummy object as a rvalue:








Before the new standard, we just call foo passing our object:



Here, a temporary object is created, calling the Dummy's copy constructor, and going on a deep copy to duplicate its array member, which is very expensive.

In C++11, we can use std::move(d1) to pass to foo:



The move call returns a rvalue, this way, we perform a Perfect forwarding, because no temporary object is created, instead, the rvalue version of foo is called, calling the move constructor of Dummy, going on a shallow copy, which does not duplicate the member array, instead, takes the same memory address of its source.

Based on this, for our tests, we can conclude that the rival of Perfect forwarding is going to be the Copy constructor. Because before perfect forwarding, we had no option more than create the temporary object.


Move constructor
Let's say we want to create a new instance of our Dummy object, but we want to base this one on an already existing Dummy object.
Dummy interface


Before the new standard, when we want to create an object based on another object, our best option is deep copying the old one to the new one. As I said before, it is very expensive, and unnecessary if we are not going to use our old object any more.



The new standard allow us to create an object stealing the members from the object we are basing the new one, by calling the Dummy's move constructor.



Just, after this, be careful when you refer to d1. It is better if you don't.

Based on this, for our tests, we can conclude that the rival of Move constructor is going to be the Copy constructor. Because before move constructos, we had no option more than do a deep copy of an object.


Move assignment
Let's we have already created d1 and d2, and we want to copy d2 to d1. Or we just want to assign a default Dummy object to d1.








As we can see on the Dummy interface image, Dummy implements the move semantics overloading the operator=.

Before the new standard, when we want to assign an already existing object to another existing one, we just assign d2 to d1, which goes on a deep copy. And the same happens when we want to assign an object created on the fly:




In C++11 we can overload the operator= for an rvalue, this allow us move assignments.




Since the Dummy() call returns a rvalue, the move assignment operator= is called.
And as Dummy() is a rvalue, when don't have to have the same caution that we have to have when we call the move constructor in the previous test example (which is a lvalue), when don't have the address of Dummy() to make any mistakes ;)

Based on this, for our tests, we can conclude that the rival of Move assignment is going to be the Copy assignment. Because before move assignment, we had no option more than do a copy assignment.


The benchs

Well, finally we have the results of the benchs. We run the benchs using the command time, which shows the wall clock time, the user time, and the sys time.
The wall clock time is the the human perception time. The user time is the time that the program runs on user space of the operative system. The sys time is the time that the program runs on kernel space (system calls).
Each test was ran 20 times, and I took the average.

First Test: Perfect Forwarding vs Temporaries







 






Unbelieve!, no? It is beacuse Perfect forwarding does not duplicate memory.


Second test: Move Constructor vs Copy Constructor










Same monster difference. Same motive.


Third test: Move Assignment vs Copy Assignment










And finally we can see that the same happens with the assignments.



Summary

Overload the operator= to achieve the move semantics.
Use move semantics whenever the situation allow you. They are way faster than duplicating blocks of memory.


You can download the benchs and run on you computer: c9xvsc++11